/* * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.awt.AWTException; import java.awt.Component; import java.awt.EventQueue; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.InputEvent; import java.util.concurrent.atomic.AtomicReference; import java.lang.reflect.InvocationTargetException; import javax.swing.SwingUtilities; /** * JRobot is a wrapper around java.awt.Robot that provides some convenience * methods. *
When using jtreg you would include this class via something like: *
{@code
* @library ../../../regtesthelpers
* @build JRobot
* }
*/
public class JRobot extends java.awt.Robot {
private static final int DEFAULT_DELAY = 550;
private static final int INTERNAL_DELAY = 250;
private int delay;
private boolean delaysEnabled;
protected JRobot(boolean enableDelays) throws AWTException {
super();
delaysEnabled = enableDelays;
setAutoWaitForIdle(enableDelays);
if (enableDelays) {
setAutoDelay(INTERNAL_DELAY);
setDelay(DEFAULT_DELAY);
}
}
/**
* Return a JRobot. Delays are enabled by default.
* @return a JRobot
*/
public static JRobot getRobot() {
return getRobot(true);
}
/**
* Create a JRobot. The parameter controls whether delays are enabled.
* @param enableDelays controls whether delays are enabled.
* @return a JRobot
*/
public static JRobot getRobot(boolean enableDelays) {
JRobot robot = null;
try {
robot = new JRobot(enableDelays);
} catch (AWTException e) {
System.err.println("Coudn't create Robot, details below");
throw new Error(e);
}
return robot;
}
/**
* Press and release a key.
* @param keycode which key to press. For example, KeyEvent.VK_DOWN
*/
public void hitKey(int keycode) {
keyPress(keycode);
keyRelease(keycode);
delay();
}
/**
* Press and release a key with modifiers.
* @param keys keys to press. Keys are pressed in order they are passed as
* parameters to this method. All keys except the last one are considered
* modifiers. For example, to press Ctrl+Shift+T, call:
* hitKey(KeyEvent.VK_CONTROL, KeyEvent.VK_SHIFT, KeyEvent.VK_T);
*/
public void hitKey(int... keys) {
for (int i = 0; i < keys.length; i++) {
keyPress(keys[i]);
}
for (int i = keys.length - 1; i >= 0; i--) {
keyRelease(keys[i]);
}
delay();
}
/**
* Move mouse cursor to the center of the Component.
*
* Note: This method is executed on EDT.
*
* @param c Component the mouse is placed over
*/
public void moveMouseTo(Component c) {
Point p = getCenterPoint(c);
mouseMove(p.x, p.y);
delay();
}
private static Point getCenterPoint(Component c) {
AtomicReference
* Note: This method is executed on EDT.
*
* @param c the Component to click on
* @param buttons mouse button(s)
*/
public void clickMouseOn(Component c, int buttons) {
moveMouseTo(c);
clickMouse(buttons);
}
/**
* Click the first mouse button in the center of the given Component
*
* Note: This method is executed on EDT.
*
* @param c the Component to click on
*/
public void clickMouseOn(Component c) {
clickMouseOn(c, InputEvent.BUTTON1_DOWN_MASK);
}
/**
* Return whether delays are enabled
* @return whether delays are enabled
*/
public boolean getDelaysEnabled() {
return delaysEnabled;
}
/**
* Delay execution by delay milliseconds
*/
public void delay() {
delay(delay);
}
/**
* Return the delay amount, in milliseconds
*/
public int getDelay() {
return delay;
}
/**
* Set the delay amount, in milliseconds
*/
public void setDelay(int delay) {
this.delay = delay;
}
/**
* Waits until all events currently on the event queue have been processed.
* Does nothing if called on EDT
*/
public synchronized void waitForIdle() {
if (!EventQueue.isDispatchThread()) {
super.waitForIdle();
}
}
/**
* Calculate the center of the Rectangle passed, and return them
* in a Point object.
* @param r a non-null Rectangle
* @return a new Point object containing coordinates of r's center
*/
public static Point centerOf(Rectangle r) {
return centerOf(r, new Point());
}
/**
* Calculate the center of the Rectangle passed, and store it in p.
* @param r a non-null Rectangle
* @param p a non-null Point that receives coordinates of r's center
* @return p
*/
public static Point centerOf(Rectangle r, Point p) {
p.x = r.x + r.width / 2;
p.y = r.y + r.height / 2;
return p;
}
/**
* Convert a rectangle from coordinate system of Component c to
* screen coordinate system.
*
* Note: This method is executed on EDT.
*
* @param r a non-null Rectangle
* @param c a Component whose coordinate system is used for conversion
*/
public void convertRectToScreen(Rectangle r, Component c) {
AtomicReference