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. Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package org.netbeans.jemmy.drivers.scrolling;
26 
27 import java.awt.Point;
28 
29 import javax.swing.JScrollBar;
30 
31 import org.netbeans.jemmy.QueueTool;
32 import org.netbeans.jemmy.Timeout;
33 import org.netbeans.jemmy.drivers.DriverManager;
34 import org.netbeans.jemmy.drivers.MouseDriver;
35 import org.netbeans.jemmy.operators.ComponentOperator;
36 import org.netbeans.jemmy.operators.JButtonOperator;
37 import org.netbeans.jemmy.operators.JScrollBarOperator;
38 import org.netbeans.jemmy.operators.Operator;
39 
40 /**
41  * ScrollDriver for javax.swing.JScrollBar component type.
42  *
43  * @author Alexandre Iline(alexandre.iline@oracle.com)
44  */
45 public class JScrollBarDriver extends AbstractScrollDriver {
46 
47     private final static int SMALL_INCREMENT = 1;
48     private final static int MINIMAL_DRAGGER_SIZE = 5;
49     private final static int RELATIVE_DRAG_STEP_LENGTH = 20;
50 
51     private QueueTool queueTool;
52 
53     /**
54      * Constructs a JScrollBarDriver.
55      */
JScrollBarDriver()56     public JScrollBarDriver() {
57         super(new String[]{"org.netbeans.jemmy.operators.JScrollBarOperator"});
58         queueTool = new QueueTool();
59     }
60 
61     @Override
position(ComponentOperator oper, int orientation)62     protected int position(ComponentOperator oper, int orientation) {
63         return ((JScrollBarOperator) oper).getValue();
64     }
65 
66     @Override
scrollToMinimum(ComponentOperator oper, int orientation)67     public void scrollToMinimum(ComponentOperator oper, int orientation) {
68         startDragging(oper);
69         Point pnt = new Point(0, 0);
70         drag(oper, pnt);
71         Timeout sleepTime = oper.getTimeouts().create("Waiter.TimeDelta");
72         while (((JScrollBarOperator) oper).getValue()
73                 > ((JScrollBarOperator) oper).getMinimum()) {
74             sleepTime.sleep();
75         }
76         drop(oper, pnt);
77     }
78 
79     @Override
scrollToMaximum(ComponentOperator oper, int orientation)80     public void scrollToMaximum(ComponentOperator oper, int orientation) {
81         startDragging(oper);
82         Point pnt = new Point(oper.getWidth() - 1, oper.getHeight() - 1);
83         drag(oper, pnt);
84         Timeout sleepTime = oper.getTimeouts().create("Waiter.TimeDelta");
85         while (((JScrollBarOperator) oper).getValue()
86                 > (((JScrollBarOperator) oper).getMaximum()
87                 - ((JScrollBarOperator) oper).getVisibleAmount())) {
88             sleepTime.sleep();
89         }
90         drop(oper, pnt);
91     }
92 
93     @Override
step(ComponentOperator oper, ScrollAdjuster adj)94     protected void step(ComponentOperator oper, ScrollAdjuster adj) {
95         JButtonOperator boper = findAButton(oper, adj.getScrollDirection());
96         DriverManager.getButtonDriver(boper).push(boper);
97     }
98 
99     @Override
jump(final ComponentOperator oper, final ScrollAdjuster adj)100     protected void jump(final ComponentOperator oper, final ScrollAdjuster adj) {
101         final JButtonOperator lessButton = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
102         final JButtonOperator moreButton = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
103         queueTool.invokeSmoothly(new QueueTool.QueueAction<Void>("Scrolling by clicking with the mouse") {
104             @Override
105             public Void launch() {
106                 if (adj.getScrollDirection() != ScrollAdjuster.DO_NOT_TOUCH_SCROLL_DIRECTION) {
107                     int x, y;
108                     switch (((JScrollBarOperator) oper).getOrientation()) {
109                         case JScrollBar.HORIZONTAL:
110                             switch (adj.getScrollDirection()) {
111                                 case ScrollAdjuster.INCREASE_SCROLL_DIRECTION:
112                                     x = moreButton.getX() - 1;
113                                     break;
114                                 case ScrollAdjuster.DECREASE_SCROLL_DIRECTION:
115                                     x = lessButton.getX() + lessButton.getWidth();
116                                     break;
117                                 default:
118                                     return null;
119                             }
120                             y = lessButton.getHeight() / 2;
121                             break;
122                         case JScrollBar.VERTICAL:
123                             switch (adj.getScrollDirection()) {
124                                 case ScrollAdjuster.INCREASE_SCROLL_DIRECTION:
125                                     y = moreButton.getY() - 1;
126                                     break;
127                                 case ScrollAdjuster.DECREASE_SCROLL_DIRECTION:
128                                     y = lessButton.getY() + lessButton.getHeight();
129                                     break;
130                                 default:
131                                     return null;
132                             }
133                             x = lessButton.getWidth() / 2;
134                             break;
135                         default:
136                             return null;
137                     }
138                     DriverManager.getMouseDriver(oper).
139                             clickMouse(oper, x, y, 1, Operator.getDefaultMouseButton(), 0, new Timeout("", 0));
140                 }
141                 return null;
142             }
143         });
144     }
145 
146     @Override
startPushAndWait(ComponentOperator oper, int direction, int orientation)147     protected void startPushAndWait(ComponentOperator oper, int direction, int orientation) {
148         JButtonOperator boper = findAButton(oper, direction);
149         DriverManager.getButtonDriver(boper).press(boper);
150     }
151 
152     @Override
stopPushAndWait(ComponentOperator oper, int direction, int orientation)153     protected void stopPushAndWait(ComponentOperator oper, int direction, int orientation) {
154         JButtonOperator boper = findAButton(oper, direction);
155         DriverManager.getButtonDriver(boper).release(boper);
156     }
157 
158     @Override
startDragging(ComponentOperator oper)159     protected Point startDragging(ComponentOperator oper) {
160         JButtonOperator lessButton = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
161         JButtonOperator moreButton = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
162         Point pnt = getClickPoint((JScrollBarOperator) oper, lessButton, moreButton, ((JScrollBarOperator) oper).getValue());
163         MouseDriver mdriver = DriverManager.getMouseDriver(oper);
164         mdriver.moveMouse(oper, pnt.x, pnt.y);
165         mdriver.pressMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
166         return pnt;
167     }
168 
169     @Override
drop(ComponentOperator oper, Point pnt)170     protected void drop(ComponentOperator oper, Point pnt) {
171         DriverManager.getMouseDriver(oper).
172                 releaseMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
173     }
174 
175     @Override
drag(ComponentOperator oper, Point pnt)176     protected void drag(ComponentOperator oper, Point pnt) {
177         DriverManager.getMouseDriver(oper).
178                 dragMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
179     }
180 
181     @Override
getScrollDeltaTimeout(ComponentOperator oper)182     protected Timeout getScrollDeltaTimeout(ComponentOperator oper) {
183         return (oper.getTimeouts().
184                 create("ScrollbarOperator.DragAndDropScrollingDelta"));
185     }
186 
187     @Override
canDragAndDrop(ComponentOperator oper)188     protected boolean canDragAndDrop(ComponentOperator oper) {
189         if (!isSmallIncrement((JScrollBarOperator) oper)) {
190             return false;
191         }
192         boolean result = false;
193         MouseDriver mdriver = DriverManager.getMouseDriver(oper);
194         JButtonOperator less = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
195         JButtonOperator more = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
196         Point pnt = getClickPoint((JScrollBarOperator) oper, less, more, ((JScrollBarOperator) oper).getValue());
197         mdriver.moveMouse(oper, pnt.x, pnt.y);
198         mdriver.pressMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
199         result = ((JScrollBarOperator) oper).getValueIsAdjusting();
200         mdriver.releaseMouse(oper, pnt.x, pnt.y, Operator.getDefaultMouseButton(), 0);
201         return result && isSmallIncrement((JScrollBarOperator) oper);
202     }
203 
204     @Override
canJump(ComponentOperator oper)205     protected boolean canJump(ComponentOperator oper) {
206         return isSmallIncrement((JScrollBarOperator) oper);
207     }
208 
209     @Override
canPushAndWait(ComponentOperator oper)210     protected boolean canPushAndWait(ComponentOperator oper) {
211         return isSmallIncrement((JScrollBarOperator) oper);
212     }
213 
214     @Override
getDragAndDropStepLength(ComponentOperator oper)215     protected int getDragAndDropStepLength(ComponentOperator oper) {
216         JButtonOperator less = findAButton(oper, ScrollAdjuster.DECREASE_SCROLL_DIRECTION);
217         JButtonOperator more = findAButton(oper, ScrollAdjuster.INCREASE_SCROLL_DIRECTION);
218         int width = oper.getWidth() - less.getWidth() - more.getWidth();
219         int height = oper.getHeight() - less.getHeight() - more.getHeight();
220         int max = (width > height) ? width : height;
221         if (max >= RELATIVE_DRAG_STEP_LENGTH * 2) {
222             return max / RELATIVE_DRAG_STEP_LENGTH;
223         } else {
224             return 1;
225         }
226     }
227 
isSmallIncrement(JScrollBarOperator oper)228     private boolean isSmallIncrement(JScrollBarOperator oper) {
229         return (oper.getUnitIncrement(-1) <= SMALL_INCREMENT
230                 && oper.getUnitIncrement(1) <= SMALL_INCREMENT);
231     }
232 
getClickPoint(JScrollBarOperator oper, JButtonOperator lessButton, JButtonOperator moreButton, int value)233     private Point getClickPoint(JScrollBarOperator oper, JButtonOperator lessButton, JButtonOperator moreButton, int value) {
234         int lenght = (oper.getOrientation() == JScrollBar.HORIZONTAL)
235                 ? oper.getWidth() - lessButton.getWidth() - moreButton.getWidth()
236                 : oper.getHeight() - lessButton.getHeight() - moreButton.getHeight();
237         int subpos = (int) (((float) lenght / (oper.getMaximum() - oper.getMinimum())) * value);
238         if (oper.getOrientation() == JScrollBar.HORIZONTAL) {
239             subpos = subpos + lessButton.getWidth();
240         } else {
241             subpos = subpos + lessButton.getHeight();
242         }
243         subpos = subpos + MINIMAL_DRAGGER_SIZE / 2 + 1;
244         return ((oper.getOrientation() == JScrollBar.HORIZONTAL)
245                 ? new Point(subpos, oper.getHeight() / 2)
246                 : new Point(oper.getWidth() / 2, subpos));
247     }
248 
findAButton(ComponentOperator oper, int direction)249     private JButtonOperator findAButton(ComponentOperator oper, int direction) {
250         return ((direction == ScrollAdjuster.DECREASE_SCROLL_DIRECTION)
251                 ? ((JScrollBarOperator) oper).getDecreaseButton()
252                 : ((JScrollBarOperator) oper).getIncreaseButton());
253     }
254 }
255