Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/lib/testlibrary/ExtendedRobot.java
38833 views
1
/*
2
* Copyright (c) 2014, 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
26
import sun.awt.ExtendedKeyCodes;
27
import sun.awt.SunToolkit;
28
29
import java.awt.AWTException;
30
import java.awt.Robot;
31
import java.awt.GraphicsDevice;
32
import java.awt.Toolkit;
33
import java.awt.Point;
34
import java.awt.MouseInfo;
35
import java.awt.event.InputEvent;
36
37
/**
38
* ExtendedRobot is a subclass of {@link java.awt.Robot}. It provides some convenience methods that are
39
* ought to be moved to {@link java.awt.Robot} class.
40
* <p>
41
* ExtendedRobot uses delay {@link #getSyncDelay()} to make syncing threads with {@link #waitForIdle()}
42
* more stable. This delay can be set once on creating object and could not be changed throughout object
43
* lifecycle. Constructor reads vm integer property {@code java.awt.robotdelay} and sets the delay value
44
* equal to the property value. If the property was not set 500 milliseconds default value is used.
45
* <p>
46
* When using jtreg you would include this class via something like:
47
* <pre>
48
* {@literal @}library ../../../../lib/testlibrary
49
* {@literal @}build ExtendedRobot
50
* </pre>
51
*
52
* @author Dmitriy Ermashov
53
* @since 1.9
54
*/
55
56
public class ExtendedRobot extends Robot {
57
58
private static int DEFAULT_SPEED = 20; // Speed for mouse glide and click
59
private static int DEFAULT_SYNC_DELAY = 500; // Default Additional delay for waitForIdle()
60
private static int DEFAULT_STEP_LENGTH = 2; // Step length (in pixels) for mouse glide
61
62
private final int syncDelay = DEFAULT_SYNC_DELAY;
63
64
//TODO: uncomment three lines below after moving functionality to java.awt.Robot
65
//{
66
// syncDelay = AccessController.doPrivileged(new GetIntegerAction("java.awt.robotdelay", DEFAULT_SYNC_DELAY));
67
//}
68
69
/**
70
* Constructs an ExtendedRobot object in the coordinate system of the primary screen.
71
*
72
* @throws AWTException if the platform configuration does not allow low-level input
73
* control. This exception is always thrown when
74
* GraphicsEnvironment.isHeadless() returns true
75
* @throws SecurityException if {@code createRobot} permission is not granted
76
*
77
* @see java.awt.GraphicsEnvironment#isHeadless
78
* @see SecurityManager#checkPermission
79
* @see java.awt.AWTPermission
80
*/
81
public ExtendedRobot() throws AWTException {
82
super();
83
}
84
85
/**
86
* Creates an ExtendedRobot for the given screen device. Coordinates passed
87
* to ExtendedRobot method calls like mouseMove and createScreenCapture will
88
* be interpreted as being in the same coordinate system as the specified screen.
89
* Note that depending on the platform configuration, multiple screens may either:
90
* <ul>
91
* <li>share the same coordinate system to form a combined virtual screen</li>
92
* <li>use different coordinate systems to act as independent screens</li>
93
* </ul>
94
* This constructor is meant for the latter case.
95
* <p>
96
* If screen devices are reconfigured such that the coordinate system is
97
* affected, the behavior of existing ExtendedRobot objects is undefined.
98
*
99
* @param screen A screen GraphicsDevice indicating the coordinate
100
* system the Robot will operate in.
101
* @throws AWTException if the platform configuration does not allow low-level input
102
* control. This exception is always thrown when
103
* GraphicsEnvironment.isHeadless() returns true.
104
* @throws IllegalArgumentException if {@code screen} is not a screen
105
* GraphicsDevice.
106
* @throws SecurityException if {@code createRobot} permission is not granted
107
*
108
* @see java.awt.GraphicsEnvironment#isHeadless
109
* @see GraphicsDevice
110
* @see SecurityManager#checkPermission
111
* @see java.awt.AWTPermission
112
*/
113
public ExtendedRobot(GraphicsDevice screen) throws AWTException {
114
super(screen);
115
}
116
117
/**
118
* Returns delay length for {@link #waitForIdle()} method
119
*
120
* @return Current delay value
121
*
122
* @see #waitForIdle()
123
*/
124
public int getSyncDelay(){ return this.syncDelay; }
125
126
/**
127
* Clicks mouse button(s) by calling {@link java.awt.Robot#mousePress(int)} and
128
* {@link java.awt.Robot#mouseRelease(int)} methods
129
*
130
*
131
* @param buttons The button mask; a combination of one or more mouse button masks.
132
* @throws IllegalArgumentException if the {@code buttons} mask contains the mask for
133
* extra mouse button and support for extended mouse buttons is
134
* {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
135
* @throws IllegalArgumentException if the {@code buttons} mask contains the mask for
136
* extra mouse button that does not exist on the mouse and support for extended
137
* mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled}
138
* by Java
139
*
140
* @see #mousePress(int)
141
* @see #mouseRelease(int)
142
* @see InputEvent#getMaskForButton(int)
143
* @see Toolkit#areExtraMouseButtonsEnabled()
144
* @see java.awt.event.MouseEvent
145
*/
146
public void click(int buttons) {
147
mousePress(buttons);
148
waitForIdle(DEFAULT_SPEED);
149
mouseRelease(buttons);
150
waitForIdle();
151
}
152
153
/**
154
* Clicks mouse button 1
155
*
156
* @throws IllegalArgumentException if the {@code buttons} mask contains the mask for
157
* extra mouse button and support for extended mouse buttons is
158
* {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java
159
* @throws IllegalArgumentException if the {@code buttons} mask contains the mask for
160
* extra mouse button that does not exist on the mouse and support for extended
161
* mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled}
162
* by Java
163
*
164
* @see #click(int)
165
*/
166
public void click() {
167
click(InputEvent.BUTTON1_DOWN_MASK);
168
}
169
170
/**
171
* Waits until all events currently on the event queue have been processed with given
172
* delay after syncing threads. It uses more advanced method of synchronizing threads
173
* unlike {@link java.awt.Robot#waitForIdle()}
174
*
175
* @param delayValue Additional delay length in milliseconds to wait until thread
176
* sync been completed
177
* @throws sun.awt.SunToolkit.IllegalThreadException if called on the AWT event
178
* dispatching thread
179
*/
180
public synchronized void waitForIdle(int delayValue) {
181
SunToolkit.flushPendingEvents();
182
((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
183
delay(delayValue);
184
}
185
186
/**
187
* Waits until all events currently on the event queue have been processed with delay
188
* {@link #getSyncDelay()} after syncing threads. It uses more advanced method of
189
* synchronizing threads unlike {@link java.awt.Robot#waitForIdle()}
190
*
191
* @throws sun.awt.SunToolkit.IllegalThreadException if called on the AWT event
192
* dispatching thread
193
*
194
* @see #waitForIdle(int)
195
*/
196
@Override
197
public synchronized void waitForIdle() {
198
waitForIdle(syncDelay);
199
}
200
201
/**
202
* Move the mouse in multiple steps from where it is
203
* now to the destination coordinates.
204
*
205
* @param x Destination point x coordinate
206
* @param y Destination point y coordinate
207
*
208
* @see #glide(int, int, int, int)
209
*/
210
public void glide(int x, int y) {
211
Point p = MouseInfo.getPointerInfo().getLocation();
212
glide(p.x, p.y, x, y);
213
}
214
215
/**
216
* Move the mouse in multiple steps from where it is
217
* now to the destination point.
218
*
219
* @param dest Destination point
220
*
221
* @see #glide(int, int)
222
*/
223
public void glide(Point dest) {
224
glide(dest.x, dest.y);
225
}
226
227
/**
228
* Move the mouse in multiple steps from source coordinates
229
* to the destination coordinates.
230
*
231
* @param fromX Source point x coordinate
232
* @param fromY Source point y coordinate
233
* @param toX Destination point x coordinate
234
* @param toY Destination point y coordinate
235
*
236
* @see #glide(int, int, int, int, int, int)
237
*/
238
public void glide(int fromX, int fromY, int toX, int toY) {
239
glide(fromX, fromY, toX, toY, DEFAULT_STEP_LENGTH, DEFAULT_SPEED);
240
}
241
242
/**
243
* Move the mouse in multiple steps from source point to the
244
* destination point with default speed and step length.
245
*
246
* @param src Source point
247
* @param dest Destination point
248
*
249
* @see #glide(int, int, int, int, int, int)
250
*/
251
public void glide(Point src, Point dest) {
252
glide(src.x, src.y, dest.x, dest.y, DEFAULT_STEP_LENGTH, DEFAULT_SPEED);
253
}
254
255
/**
256
* Move the mouse in multiple steps from source point to the
257
* destination point with given speed and step length.
258
*
259
* @param srcX Source point x cordinate
260
* @param srcY Source point y cordinate
261
* @param destX Destination point x cordinate
262
* @param destY Destination point y cordinate
263
* @param stepLength Approximate length of one step
264
* @param speed Delay between steps.
265
*
266
* @see #mouseMove(int, int)
267
* @see #delay(int)
268
*/
269
public void glide(int srcX, int srcY, int destX, int destY, int stepLength, int speed) {
270
int stepNum;
271
double tDx, tDy;
272
double dx, dy, ds;
273
double x, y;
274
275
dx = (destX - srcX);
276
dy = (destY - srcY);
277
ds = Math.sqrt(dx*dx + dy*dy);
278
279
tDx = dx / ds * stepLength;
280
tDy = dy / ds * stepLength;
281
282
int stepsCount = (int) ds / stepLength;
283
284
// Walk the mouse to the destination one step at a time
285
mouseMove(srcX, srcY);
286
287
for (x = srcX, y = srcY, stepNum = 0;
288
stepNum < stepsCount;
289
stepNum++) {
290
x += tDx;
291
y += tDy;
292
mouseMove((int)x, (int)y);
293
delay(speed);
294
}
295
296
// Ensure the mouse moves to the right destination.
297
// The steps may have led the mouse to a slightly wrong place.
298
mouseMove(destX, destY);
299
}
300
301
/**
302
* Moves mouse pointer to given screen coordinates.
303
*
304
* @param position Target position
305
*
306
* @see java.awt.Robot#mouseMove(int, int)
307
*/
308
public synchronized void mouseMove(Point position) {
309
mouseMove(position.x, position.y);
310
}
311
312
313
/**
314
* Emulate native drag and drop process using {@code InputEvent.BUTTON1_DOWN_MASK}.
315
* The method successively moves mouse cursor to point with coordinates
316
* ({@code fromX}, {@code fromY}), presses mouse button 1, drag mouse to
317
* point with coordinates ({@code toX}, {@code toY}) and releases mouse
318
* button 1 at last.
319
*
320
* @param fromX Source point x coordinate
321
* @param fromY Source point y coordinate
322
* @param toX Destination point x coordinate
323
* @param toY Destination point y coordinate
324
*
325
* @see #mousePress(int)
326
* @see #glide(int, int, int, int)
327
*/
328
public void dragAndDrop(int fromX, int fromY, int toX, int toY){
329
mouseMove(fromX, fromY);
330
mousePress(InputEvent.BUTTON1_DOWN_MASK);
331
waitForIdle();
332
glide(toX, toY);
333
mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
334
waitForIdle();
335
}
336
337
/**
338
* Emulate native drag and drop process using {@code InputEvent.BUTTON1_DOWN_MASK}.
339
* The method successively moves mouse cursor to point {@code from},
340
* presses mouse button 1, drag mouse to point {@code to} and releases
341
* mouse button 1 at last.
342
*
343
* @param from Source point
344
* @param to Destination point
345
*
346
* @see #mousePress(int)
347
* @see #glide(int, int, int, int)
348
* @see #dragAndDrop(int, int, int, int)
349
*/
350
public void dragAndDrop(Point from, Point to){
351
dragAndDrop(from.x, from.y, to.x, to.y);
352
}
353
354
/**
355
* Successively presses and releases a given key.
356
* <p>
357
* Key codes that have more than one physical key associated with them
358
* (e.g. {@code KeyEvent.VK_SHIFT} could mean either the
359
* left or right shift key) will map to the left key.
360
*
361
* @param keycode Key to press (e.g. {@code KeyEvent.VK_A})
362
* @throws IllegalArgumentException if {@code keycode} is not
363
* a valid key
364
*
365
* @see java.awt.Robot#keyPress(int)
366
* @see java.awt.Robot#keyRelease(int)
367
* @see java.awt.event.KeyEvent
368
*/
369
public void type(int keycode) {
370
keyPress(keycode);
371
waitForIdle(DEFAULT_SPEED);
372
keyRelease(keycode);
373
waitForIdle(DEFAULT_SPEED);
374
}
375
376
/**
377
* Types given character
378
*
379
* @param c Character to be typed (e.g. {@code 'a'})
380
*
381
* @see #type(int)
382
* @see java.awt.event.KeyEvent
383
*/
384
public void type(char c) {
385
type(ExtendedKeyCodes.getExtendedKeyCodeForChar(c));
386
}
387
388
/**
389
* Types given array of characters one by one
390
*
391
* @param symbols Array of characters to be typed
392
*
393
* @see #type(char)
394
*/
395
public void type(char[] symbols) {
396
for (int i = 0; i < symbols.length; i++) {
397
type(symbols[i]);
398
}
399
}
400
401
/**
402
* Types given string
403
*
404
* @param s String to be typed
405
*
406
* @see #type(char[])
407
*/
408
public void type(String s) {
409
type(s.toCharArray());
410
}
411
}
412
413