AbstractScrollDriver.java revision 13978:1993af50385d
1/* 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.netbeans.jemmy.drivers.scrolling; 24 25import java.awt.Adjustable; 26import java.awt.Point; 27import org.netbeans.jemmy.JemmyException; 28import org.netbeans.jemmy.JemmyProperties; 29 30import org.netbeans.jemmy.Timeout; 31import org.netbeans.jemmy.drivers.LightSupportiveDriver; 32import org.netbeans.jemmy.drivers.ScrollDriver; 33import org.netbeans.jemmy.operators.ComponentOperator; 34 35/** 36 * Superclass for all scroll drivers. Contains all the logic of scrolling. Tries 37 * allowed operations in this order: "jump", "drag'n'drop", "push'n'wait", 38 * "step". Repeats "step" scrolling while scroller value is not equal to the 39 * necessary value, but no more than {@code ADJUST_CLICK_COUNT}. 40 * 41 * @author Alexandre Iline(alexandre.iline@oracle.com) 42 */ 43public abstract class AbstractScrollDriver extends LightSupportiveDriver implements ScrollDriver { 44 45 /** 46 * Maximal number of attempts to reach required position by minimal 47 * scrolling operation. 48 */ 49 public static final int ADJUST_CLICK_COUNT = 10; 50 public static final String SCROLL_FREEZE_TIMEOUT = AbstractScrollDriver.class.getName() + ".freeze.timeout"; 51 52 static { 53 JemmyProperties.getProperties().initTimeout(SCROLL_FREEZE_TIMEOUT, 1000); 54 } 55 56 /** 57 * Constructs an AbstractScrollDriver. 58 * 59 * @param supported an array of supported class names 60 */ 61 public AbstractScrollDriver(String[] supported) { 62 super(supported); 63 } 64 65 @Override 66 public void scroll(ComponentOperator oper, ScrollAdjuster adj) { 67 if (canJump(oper)) { 68 doJumps(oper, adj); 69 } 70 if (canDragAndDrop(oper)) { 71 doDragAndDrop(oper, adj); 72 } 73 if (canPushAndWait(oper)) { 74 if (!doPushAndWait(oper, adj, oper.getTimeouts().getTimeout(SCROLL_FREEZE_TIMEOUT))) { 75 throw new JemmyException("Scrolling stuck for more than " 76 + oper.getTimeouts().getTimeout(SCROLL_FREEZE_TIMEOUT) 77 + " on " + oper); 78 } 79 } 80 for (int i = 0; i < ADJUST_CLICK_COUNT; i++) { 81 doSteps(oper, adj); 82 } 83 } 84 85 /** 86 * Performs minimal scrolling step. 87 * 88 * @param oper an operator. 89 * @param adj a scroll adjuster 90 */ 91 protected abstract void step(ComponentOperator oper, ScrollAdjuster adj); 92 93 /** 94 * Performs maximal scroll step. 95 * 96 * @param oper an operator. 97 * @param adj a scroll adjuster 98 */ 99 protected abstract void jump(ComponentOperator oper, ScrollAdjuster adj); 100 101 /** 102 * Presses something like a scroll button. 103 * 104 * @param oper an operator. 105 * @param direction - one of the ScrollAdjister.INCREASE_SCROLL_DIRECTION, 106 * ScrollAdjister.DECREASE_SCROLL_DIRECTION, 107 * ScrollAdjister.DO_NOT_TOUCH_SCROLL_DIRECTION values. 108 * @param orientation one of the Adjustable.HORIZONTAL or 109 * Adjustable.VERTICAL values. 110 */ 111 protected abstract void startPushAndWait(ComponentOperator oper, int direction, int orientation); 112 113 /** 114 * Releases something like a scroll button. 115 * 116 * @param oper an operator. 117 * @param direction - one of the ScrollAdjister.INCREASE_SCROLL_DIRECTION, 118 * ScrollAdjister.DECREASE_SCROLL_DIRECTION, 119 * ScrollAdjister.DO_NOT_TOUCH_SCROLL_DIRECTION values. 120 * @param orientation one of the Adjustable.HORIZONTAL or 121 * Adjustable.VERTICAL values. 122 */ 123 protected abstract void stopPushAndWait(ComponentOperator oper, int direction, int orientation); 124 125 /** 126 * Starts drag'n'drop scrolling. 127 * 128 * @param oper an operator. 129 * @return start drugging point. 130 */ 131 protected abstract Point startDragging(ComponentOperator oper); 132 133 /** 134 * Drop at a specified point. 135 * 136 * @param oper an operator. 137 * @param pnt the point to drop. 138 */ 139 protected abstract void drop(ComponentOperator oper, Point pnt); 140 141 /** 142 * Drag to a specified point. 143 * 144 * @param oper an operator. 145 * @param pnt the point to drag to. 146 */ 147 protected abstract void drag(ComponentOperator oper, Point pnt); 148 149 /** 150 * Returns a timeout for sleeping between verifications during "push and 151 * wait" scrolling. 152 * 153 * @param oper an operator. 154 * @return a timeout 155 */ 156 protected abstract Timeout getScrollDeltaTimeout(ComponentOperator oper); 157 158 /** 159 * Tells if this driver allows to perform drag'n'drop scrolling. 160 * 161 * @param oper an operator. 162 * @return true if this driver allows to drag'n'drop. 163 */ 164 protected abstract boolean canDragAndDrop(ComponentOperator oper); 165 166 /** 167 * Tells if this driver allows to perform jumps. 168 * 169 * @param oper an operator. 170 * @return true if this driver allows to jump. 171 */ 172 protected abstract boolean canJump(ComponentOperator oper); 173 174 /** 175 * Tells if this driver allows to perform "push and wait" scrolling. 176 * 177 * @param oper an operator. 178 * @return true if this driver allows to "push and wait". 179 */ 180 protected abstract boolean canPushAndWait(ComponentOperator oper); 181 182 /** 183 * Returns a number of pixels in one drag and drop scrolling. 184 * 185 * @param oper an operator. 186 * @return drag'n'drop step length. 187 */ 188 protected abstract int getDragAndDropStepLength(ComponentOperator oper); 189 190 /** 191 * Performs drag'n'drop scrolling till scroller's value does not cross 192 * required value. 193 * 194 * @param oper an operator. 195 * @param adj a scroll adjuster 196 */ 197 protected void doDragAndDrop(ComponentOperator oper, ScrollAdjuster adj) { 198 int direction = adj.getScrollDirection(); 199 if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) { 200 Point pnt = startDragging(oper); 201 while (adj.getScrollDirection() == direction) { 202 drag(oper, pnt = increasePoint(oper, pnt, adj, direction)); 203 } 204 drop(oper, pnt); 205 } 206 } 207 208 /** 209 * Performs jump scrolling till scroller's value does not cross required 210 * value. 211 * 212 * @param oper an operator. 213 * @param adj a scroll adjuster 214 */ 215 protected void doJumps(ComponentOperator oper, ScrollAdjuster adj) { 216 int direction = adj.getScrollDirection(); 217 if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) { 218 while (adj.getScrollDirection() == direction) { 219 jump(oper, adj); 220 } 221 } 222 } 223 224 protected abstract int position(ComponentOperator oper, int orientation); 225 226 /** 227 * Performs "push and wait" scrolling till scroller's value does not cross 228 * required value. 229 * 230 * @param oper an operator. 231 * @param adj a scroll adjuster 232 */ 233 protected boolean doPushAndWait(ComponentOperator oper, ScrollAdjuster adj, long freezeTimeout) { 234 int direction = adj.getScrollDirection(); 235 int orientation = adj.getScrollOrientation(); 236 int position = position(oper, orientation); 237 long lastChanded = System.currentTimeMillis(); 238 if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) { 239 Timeout delta = getScrollDeltaTimeout(oper); 240 startPushAndWait(oper, direction, orientation); 241 while (adj.getScrollDirection() == direction) { 242 delta.sleep(); 243 int curPosition = position(oper, orientation); 244 if (curPosition != position) { 245 position = curPosition; 246 lastChanded = System.currentTimeMillis(); 247 } else if ((System.currentTimeMillis() - lastChanded) > freezeTimeout) { 248 return false; 249 } 250 } 251 stopPushAndWait(oper, direction, orientation); 252 } 253 return true; 254 } 255 256 /** 257 * Performs minimal scrollings till scroller's value does not cross required 258 * value. 259 * 260 * @param oper an operator. 261 * @param adj a scroll adjuster 262 */ 263 protected void doSteps(ComponentOperator oper, ScrollAdjuster adj) { 264 int direction = adj.getScrollDirection(); 265 if (direction != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) { 266 while (adj.getScrollDirection() == direction) { 267 step(oper, adj); 268 } 269 } 270 } 271 272 private Point increasePoint(ComponentOperator oper, Point pnt, ScrollAdjuster adj, int direction) { 273 return ((adj.getScrollOrientation() == Adjustable.HORIZONTAL) 274 ? new Point(pnt.x + ((direction == 1) ? 1 : -1) * getDragAndDropStepLength(oper), pnt.y) 275 : new Point(pnt.x, pnt.y + ((direction == 1) ? 1 : -1) * getDragAndDropStepLength(oper))); 276 } 277} 278