/* * 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