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