diff --git a/test/jdk/javax/swing/regtesthelpers/JRobot.java b/test/jdk/javax/swing/regtesthelpers/JRobot.java index 5c4c4cbcf40..4c936c10dc8 100644 --- a/test/jdk/javax/swing/regtesthelpers/JRobot.java +++ b/test/jdk/javax/swing/regtesthelpers/JRobot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -21,29 +21,29 @@ * questions. */ -/** - * JRobot is a wrapper around java.awt.Robot that provides some convenience - * methods. - * <p>When using jtreg you would include this class via something like: - * <pre> - * @library ../../../regtesthelpers - * @build JRobot - * </pre> - * - */ import java.awt.AWTException; import java.awt.Component; -import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; +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. + * <p>When using jtreg you would include this class via something like: + * <pre>{@code + * @library ../../../regtesthelpers + * @build JRobot + * }</pre> + */ public class JRobot extends java.awt.Robot { - private static int DEFAULT_DELAY = 550; - private static int INTERNAL_DELAY = 250; + private static final int DEFAULT_DELAY = 550; + private static final int INTERNAL_DELAY = 250; private int delay; private boolean delaysEnabled; @@ -112,17 +112,35 @@ public class JRobot extends java.awt.Robot { /** * Move mouse cursor to the center of the Component. + * <p> + * <b>Note:</b> This method is executed on EDT. + * * @param c Component the mouse is placed over */ public void moveMouseTo(Component c) { - Point p = c.getLocationOnScreen(); - Dimension size = c.getSize(); - p.x += size.width / 2; - p.y += size.height / 2; + Point p = getCenterPoint(c); mouseMove(p.x, p.y); delay(); } + private static Point getCenterPoint(Component c) { + AtomicReference<Point> result = new AtomicReference<>(); + if (SwingUtilities.isEventDispatchThread()) { + result.set(getCenterPointImpl(c)); + } else { + try { + SwingUtilities.invokeAndWait(() -> result.set(getCenterPointImpl(c))); + } catch (InterruptedException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + return result.get(); + } + + private static Point getCenterPointImpl(Component c) { + return centerOf(new Rectangle(c.getLocationOnScreen(), c.getSize())); + } + /** * Move mouse smoothly from (x0, y0) to (x1, y1). */ @@ -153,13 +171,16 @@ public class JRobot extends java.awt.Robot { * Perform a click with the first mouse button. */ public void clickMouse() { - clickMouse(InputEvent.BUTTON1_MASK); + clickMouse(InputEvent.BUTTON1_DOWN_MASK); } /** - * Click in the center of the given Component + * Click in the center of the given Component. + * <p> + * <b>Note:</b> This method is executed on EDT. + * * @param c the Component to click on - * @param buttons mouse button(s). + * @param buttons mouse button(s) */ public void clickMouseOn(Component c, int buttons) { moveMouseTo(c); @@ -168,10 +189,13 @@ public class JRobot extends java.awt.Robot { /** * Click the first mouse button in the center of the given Component + * <p> + * <b>Note:</b> This method is executed on EDT. + * * @param c the Component to click on */ public void clickMouseOn(Component c) { - clickMouseOn(c, InputEvent.BUTTON1_MASK); + clickMouseOn(c, InputEvent.BUTTON1_DOWN_MASK); } /** @@ -219,8 +243,8 @@ public class JRobot extends java.awt.Robot { * @param r a non-null Rectangle * @return a new Point object containing coordinates of r's center */ - public Point centerOf(Rectangle r) { - return new Point(r.x + r.width / 2, r.y + r.height / 2); + public static Point centerOf(Rectangle r) { + return centerOf(r, new Point()); } /** @@ -229,7 +253,7 @@ public class JRobot extends java.awt.Robot { * @param p a non-null Point that receives coordinates of r's center * @return p */ - public Point centerOf(Rectangle r, Point 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; @@ -238,14 +262,24 @@ public class JRobot extends java.awt.Robot { /** * Convert a rectangle from coordinate system of Component c to * screen coordinate system. + * <p> + * <b>Note:</b> 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) { - Point p = new Point(r.x, r.y); - SwingUtilities.convertPointToScreen(p, c); - r.x = p.x; - r.y = p.y; + AtomicReference<Point> p = new AtomicReference<>(); + if (SwingUtilities.isEventDispatchThread()) { + p.set(c.getLocationOnScreen()); + } else { + try { + SwingUtilities.invokeAndWait(() -> p.set(c.getLocationOnScreen())); + } catch (InterruptedException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + r.setLocation(p.get()); } /**