--- old/core/JemmyAWTInput/src/org/jemmy/input/RobotDriver.java 2019-03-06 17:23:24.000000000 -0800 +++ /dev/null 2019-03-06 17:23:24.000000000 -0800 @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2007, 2017, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ -package org.jemmy.input; - - -import org.jemmy.Point; -import java.awt.event.InputEvent; -import java.util.HashMap; -import org.jemmy.Rectangle; -import org.jemmy.env.Timeout; -import org.jemmy.env.Environment; -import org.jemmy.image.Image; -import static org.jemmy.input.AWTRobotInputFactory.*; -import org.jemmy.interfaces.Button; -import org.jemmy.interfaces.Keyboard.KeyboardButton; -import org.jemmy.interfaces.Keyboard.KeyboardButtons; -import org.jemmy.interfaces.Keyboard.KeyboardModifiers; -import org.jemmy.interfaces.Modifier; -import org.jemmy.interfaces.Mouse.MouseButton; -import org.jemmy.interfaces.Mouse.MouseButtons; -import org.jemmy.interfaces.Mouse.MouseModifiers; - - -/** - * @author shura - * @author mrkam - * - */ -public class RobotDriver { - - private static boolean haveOldPos = false; - private static int smoothness; - private static double oldX; - private static double oldY; - - static { - Environment.getEnvironment().setTimeout( - new Timeout(ROBOT_DELAY_TIMEOUT_NAME, 10)); - Environment.getEnvironment().setPropertyIfNotSet( - AWTRobotInputFactory.ROBOT_MOUSE_SMOOTHNESS_PROPERTY, - Integer.toString(Integer.MAX_VALUE)); - smoothness = Integer.parseInt( - (String)Environment.getEnvironment().getProperty( - AWTRobotInputFactory.ROBOT_MOUSE_SMOOTHNESS_PROPERTY)); - } - - /** - * Sets mouse smoothness - * @param mouseSmoothness the maximum distance in pixels between - * mouse positions during movement - * @see #moveMouse(Point) - */ - public static void setMouseSmoothness(int mouseSmoothness) { - smoothness = mouseSmoothness; - } - - /** - * Gets mouse smoothness - * @return the maximum distance in pixels between - * mouse positions during movement - * @see #setMouseSmoothness(int) - * @see #moveMouse(Point) - */ - public static int getMouseSmoothness() { - return smoothness; - } - - /** - * Constructs a RobotDriver object. - * @param autoDelay Time for Robot.setAutoDelay(long) method. - */ - public RobotDriver(Timeout autoDelay) { - RobotExecutor.get().setAutoDelay(autoDelay); - } - - /** - * Constructs a RobotDriver object. - * @param env Environment with ROBOT_DELAY_TIMEOUT_NAME timeout - * @see AWTRobotInputFactory#ROBOT_DELAY_TIMEOUT_NAME - */ - public RobotDriver(Environment env) { - this(env.getTimeout(ROBOT_DELAY_TIMEOUT_NAME)); - } - - /** - * Capture an image of specified rectangular area of screen - * @param screenRect area on screen that will be captured - * @return image of specified rectangular area of screen - */ - public static Image createScreenCapture(Rectangle screenRect) { - return RobotExecutor.get().createScreenCapture(screenRect); - } - - /** - * Presses mouse button specified by mouseButton preceding pressing of - * modifier keys or buttons specified by modifiers - * @param mouseButton One of MouseEvent.BUTTON*_MASK - * @param modifiers Combination of InputEvent.*_DOWN_MASK - * @see java.awt.event.InputEvent - * @see java.awt.event.MouseEvent - */ - public void pressMouse(MouseButton mouseButton, Modifier... modifiers) { - pressModifiers(modifiers); - makeAnOperation("mousePress", - new Object[]{mouseButton}, - new Class[]{MouseButton.class}); - } - - /** - * Releases mouse button specified by mouseButton then releasing - * modifier keys or buttons specified by modifiers - * @param mouseButton One of MouseEvent.BUTTON*_MASK - * @param modifiers Combination of InputEvent.*_DOWN_MASK - * @see java.awt.event.InputEvent - * @see java.awt.event.MouseEvent - */ - public void releaseMouse(MouseButton mouseButton, Modifier... modifiers) { - makeAnOperation("mouseRelease", - new Object[]{mouseButton}, - new Class[]{MouseButton.class}); - releaseModifiers(modifiers); - } - - /** - * Moves mouse to the specified mouse. When previous mouse location is - * remembered mouse moved smoothly between the points according to - * mouse smoothness parameter. Otherwise it jumps to the specified point - * @param point Position on the screen where to move mouse - * @see #setMouseSmoothness(int) - * @see #getMouseSmoothness() - */ - public void moveMouse(Point point) { - double targetX = point.x; - double targetY = point.y; - if (haveOldPos && (oldX != targetX || oldY != targetY)) { - double currX = oldX; - double currY = oldY; - double hyp = Math.sqrt((targetX - currX) * (targetX - currX) + - (targetY - currY) * (targetY - currY)); - double steps = Math.ceil(hyp / Math.min(hyp, smoothness)); - double vx = (targetX - currX) / steps; - double vy = (targetY - currY) / steps; - assert (long)vx * vx + (long)vy * vy <= (long)smoothness * smoothness; - while (Math.round(currX) != Math.round(targetX) || - Math.round(currY) != Math.round(targetY)) { - currX += vx; - currY += vy; - makeAnOperation("mouseMove", new Object[]{ - new Integer((int) Math.round(currX)), - new Integer((int) Math.round(currY))}, - new Class[]{Integer.TYPE, Integer.TYPE}); - } - } else { - makeAnOperation("mouseMove", - new Object[]{new Integer(point.x), new Integer(point.y)}, - new Class[]{Integer.TYPE, Integer.TYPE}); - } - haveOldPos = true; - oldX = targetX; - oldY = targetY; - } - - /** - * Clicks the mouse button specified by mouseButton at the specified point - * specified number of times preceding it by pressing the modifiers key or - * buttons and ending by releasing them. The last click is as long as - * mouseClick timeout - * @param point Screen location where to click mouse - * @param clickCount Number of clicks - * @param mouseButton One of MouseEvent.BUTTON*_MASK - * @param modifiers Combination of InputEvent.*_DOWN_MASK - * @param mouseClick Timeout of the last click - * @see java.awt.event.InputEvent - * @see java.awt.event.MouseEvent - */ - public void clickMouse(Point point, int clickCount, MouseButton mouseButton, Timeout mouseClick, Modifier... modifiers) { - pressModifiers(modifiers); - moveMouse(point); - makeAnOperation("mousePress", new Object[]{mouseButton}, new Class[]{MouseButton.class}); - for (int i = 1; i < clickCount; i++) { - makeAnOperation("mouseRelease", new Object[]{mouseButton}, new Class[]{MouseButton.class}); - makeAnOperation("mousePress", new Object[]{mouseButton}, new Class[]{MouseButton.class}); - } - mouseClick.sleep(); - makeAnOperation("mouseRelease", new Object[]{mouseButton}, new Class[]{MouseButton.class}); - releaseModifiers(modifiers); - } - - /** - * @deprecated Implementation doesn't seem to be correct as it ignores mouseButton and modifiers - * @param point todo document - * @param mouseButton One of MouseEvent.BUTTON*_MASK - * @param modifiers todo document - */ - public void dragMouse(Point point, int mouseButton, int modifiers) { - moveMouse(point); - } - - /** - * Performs drag and drop from startPoint to endPoint using specified - * mouseButton and modifiers to perform it. - * @param startPoint Screen coordinates of drag start point - * @param endPoint Screen coordinates of drag end point - * @param mouseButton One of MouseEvent.BUTTON*_MASK - * @param modifiers Combination of InputEvent.*_DOWN_MASK - * @param before Timeout between pressing mouse at the startPoint and - * mouse move - * @param after Timeout between mouse move to the endPoint and mouse - * release - */ - public void dragNDrop(Point startPoint, Point endPoint, MouseButton mouseButton, Modifier modifiers[], Timeout before, Timeout after) { - moveMouse(startPoint); - pressMouse(mouseButton, modifiers); - before.sleep(); - moveMouse(endPoint); - after.sleep(); - releaseMouse(mouseButton, modifiers); - } - - /** - * Presses a key. - * @param kbdButton Key code (KeyEventVK_* field. - * @param modifiers a combination of InputEvent.*_MASK fields. - */ - public void pressKey(KeyboardButton kbdButton, Modifier... modifiers) { - pressModifiers(modifiers); - makeAnOperation("keyPress", - new Object[]{kbdButton}, - new Class[]{KeyboardButton.class}); - } - - /** - * Releases a key. - * @param kbdButton Key code (KeyEventVK_* field. - * @param modifiers a combination of InputEvent.*_MASK fields. - */ - public void releaseKey(KeyboardButton kbdButton, Modifier... modifiers) { - makeAnOperation("keyRelease", - new Object[]{kbdButton}, - new Class[]{KeyboardButton.class}); - releaseModifiers(modifiers); - } - - /** - * Turns the wheel. - * @param p todo document - * @param amount Either positive or negative - * @param modifiers a combination of InputEvent.*_MASK fields. - */ - public void turnWheel(Point p, int amount, Modifier... modifiers) { - pressModifiers(modifiers); - moveMouse(p); - java.awt.Robot r = null; - makeAnOperation("mouseWheel", - new Object[]{amount}, - new Class[]{Integer.TYPE}); - releaseModifiers(modifiers); - } - - /** - * Performs a single operation. - * @param method a name of java.awt.Robot method. - * @param params method parameters - * @param paramClasses method parameters classes - */ - public void makeAnOperation(final String method, final Object[] params, final Class[] paramClasses) { - RobotExecutor.get().makeAnOperation(method, params, paramClasses); - } - - final static int SHIFT_MASK = InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK; - final static int ALT_GRAPH_MASK = InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.ALT_GRAPH_MASK; - final static int ALT_MASK = InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK; - final static int META_MASK = InputEvent.META_DOWN_MASK | InputEvent.META_MASK; - final static int CTRL_MASK = InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK; - - /** - * Presses modifiers keys by robot. - * @param modifiers a combination of InputEvent.*_MASK fields. - */ - protected void pressModifiers(Modifier... modifiers) { - for (Modifier modifier : modifiers) { // TODO: ALT_GRAPH_MASK? - if (modifier == KeyboardModifiers.ALT_DOWN_MASK) { - pressKey(KeyboardButtons.ALT); - } else if (modifier == KeyboardModifiers.CTRL_DOWN_MASK) { - pressKey(KeyboardButtons.CONTROL); - } else if (modifier == KeyboardModifiers.META_DOWN_MASK) { - pressKey(KeyboardButtons.META); - } else if (modifier == KeyboardModifiers.SHIFT_DOWN_MASK) { - pressKey(KeyboardButtons.SHIFT); - } - } - } - - /** - * Releases modifiers keys by robot. - * @param modifiers a combination of InputEvent.*_MASK fields. - */ - protected void releaseModifiers(Modifier... modifiers) { - for (Modifier modifier : modifiers) { // TODO: ALT_GRAPH_MASK? - if (modifier == KeyboardModifiers.ALT_DOWN_MASK) { - releaseKey(KeyboardButtons.ALT); - } else if (modifier == KeyboardModifiers.CTRL_DOWN_MASK) { - releaseKey(KeyboardButtons.CONTROL); - } else if (modifier == KeyboardModifiers.META_DOWN_MASK) { - releaseKey(KeyboardButtons.META); - } else if (modifier == KeyboardModifiers.SHIFT_DOWN_MASK) { - releaseKey(KeyboardButtons.SHIFT); - } - } - } - /** - * If java.awt.Robot is running in other JVM, it shutdowns that JVM - * @see AWTRobotInputFactory#runInOtherJVM(boolean) - */ - public static void exit() { - RobotExecutor.get().exit(); - } -} --- /dev/null 2019-03-06 17:23:24.000000000 -0800 +++ new/core/JemmyAWTInput/src/org/jemmy/input/awt/RobotDriver.java 2019-03-06 17:23:23.000000000 -0800 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2007, 2017, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ +package org.jemmy.input.awt; + + +import org.jemmy.Point; +import java.awt.event.InputEvent; + +import org.jemmy.Rectangle; +import org.jemmy.env.Timeout; +import org.jemmy.env.Environment; +import org.jemmy.image.Image; +import static org.jemmy.input.awt.AWTRobotInputFactory.*; + +import org.jemmy.interfaces.Keyboard.KeyboardButton; +import org.jemmy.interfaces.Keyboard.KeyboardButtons; +import org.jemmy.interfaces.Keyboard.KeyboardModifiers; +import org.jemmy.interfaces.Modifier; +import org.jemmy.interfaces.Mouse.MouseButton; + + +/** + * @author shura + * @author mrkam + * + */ +public class RobotDriver { + + private static boolean haveOldPos = false; + private static int smoothness; + private static double oldX; + private static double oldY; + + static { + Environment.getEnvironment().setTimeout( + new Timeout(ROBOT_DELAY_TIMEOUT_NAME, 10)); + Environment.getEnvironment().setPropertyIfNotSet( + AWTRobotInputFactory.ROBOT_MOUSE_SMOOTHNESS_PROPERTY, + Integer.toString(Integer.MAX_VALUE)); + smoothness = Integer.parseInt( + (String)Environment.getEnvironment().getProperty( + AWTRobotInputFactory.ROBOT_MOUSE_SMOOTHNESS_PROPERTY)); + } + + /** + * Sets mouse smoothness + * @param mouseSmoothness the maximum distance in pixels between + * mouse positions during movement + * @see #moveMouse(Point) + */ + public static void setMouseSmoothness(int mouseSmoothness) { + smoothness = mouseSmoothness; + } + + /** + * Gets mouse smoothness + * @return the maximum distance in pixels between + * mouse positions during movement + * @see #setMouseSmoothness(int) + * @see #moveMouse(Point) + */ + public static int getMouseSmoothness() { + return smoothness; + } + + /** + * Constructs a RobotDriver object. + * @param autoDelay Time for Robot.setAutoDelay(long) method. + */ + public RobotDriver(Timeout autoDelay) { + RobotExecutor.get().setAutoDelay(autoDelay); + } + + /** + * Constructs a RobotDriver object. + * @param env Environment with ROBOT_DELAY_TIMEOUT_NAME timeout + * @see AWTRobotInputFactory#ROBOT_DELAY_TIMEOUT_NAME + */ + public RobotDriver(Environment env) { + this(env.getTimeout(ROBOT_DELAY_TIMEOUT_NAME)); + } + + /** + * Capture an image of specified rectangular area of screen + * @param screenRect area on screen that will be captured + * @return image of specified rectangular area of screen + */ + public static Image createScreenCapture(Rectangle screenRect) { + return RobotExecutor.get().createScreenCapture(screenRect); + } + + /** + * Presses mouse button specified by mouseButton preceding pressing of + * modifier keys or buttons specified by modifiers + * @param mouseButton One of MouseEvent.BUTTON*_MASK + * @param modifiers Combination of InputEvent.*_DOWN_MASK + * @see java.awt.event.InputEvent + * @see java.awt.event.MouseEvent + */ + public void pressMouse(MouseButton mouseButton, Modifier... modifiers) { + pressModifiers(modifiers); + makeAnOperation("mousePress", + new Object[]{mouseButton}, + new Class[]{MouseButton.class}); + } + + /** + * Releases mouse button specified by mouseButton then releasing + * modifier keys or buttons specified by modifiers + * @param mouseButton One of MouseEvent.BUTTON*_MASK + * @param modifiers Combination of InputEvent.*_DOWN_MASK + * @see java.awt.event.InputEvent + * @see java.awt.event.MouseEvent + */ + public void releaseMouse(MouseButton mouseButton, Modifier... modifiers) { + makeAnOperation("mouseRelease", + new Object[]{mouseButton}, + new Class[]{MouseButton.class}); + releaseModifiers(modifiers); + } + + /** + * Moves mouse to the specified mouse. When previous mouse location is + * remembered mouse moved smoothly between the points according to + * mouse smoothness parameter. Otherwise it jumps to the specified point + * @param point Position on the screen where to move mouse + * @see #setMouseSmoothness(int) + * @see #getMouseSmoothness() + */ + public void moveMouse(Point point) { + double targetX = point.x; + double targetY = point.y; + if (haveOldPos && (oldX != targetX || oldY != targetY)) { + double currX = oldX; + double currY = oldY; + double hyp = Math.sqrt((targetX - currX) * (targetX - currX) + + (targetY - currY) * (targetY - currY)); + double steps = Math.ceil(hyp / Math.min(hyp, smoothness)); + double vx = (targetX - currX) / steps; + double vy = (targetY - currY) / steps; + assert (long)vx * vx + (long)vy * vy <= (long)smoothness * smoothness; + while (Math.round(currX) != Math.round(targetX) || + Math.round(currY) != Math.round(targetY)) { + currX += vx; + currY += vy; + makeAnOperation("mouseMove", new Object[]{ + new Integer((int) Math.round(currX)), + new Integer((int) Math.round(currY))}, + new Class[]{Integer.TYPE, Integer.TYPE}); + } + } else { + makeAnOperation("mouseMove", + new Object[]{new Integer(point.x), new Integer(point.y)}, + new Class[]{Integer.TYPE, Integer.TYPE}); + } + haveOldPos = true; + oldX = targetX; + oldY = targetY; + } + + /** + * Clicks the mouse button specified by mouseButton at the specified point + * specified number of times preceding it by pressing the modifiers key or + * buttons and ending by releasing them. The last click is as long as + * mouseClick timeout + * @param point Screen location where to click mouse + * @param clickCount Number of clicks + * @param mouseButton One of MouseEvent.BUTTON*_MASK + * @param modifiers Combination of InputEvent.*_DOWN_MASK + * @param mouseClick Timeout of the last click + * @see java.awt.event.InputEvent + * @see java.awt.event.MouseEvent + */ + public void clickMouse(Point point, int clickCount, MouseButton mouseButton, Timeout mouseClick, Modifier... modifiers) { + pressModifiers(modifiers); + moveMouse(point); + makeAnOperation("mousePress", new Object[]{mouseButton}, new Class[]{MouseButton.class}); + for (int i = 1; i < clickCount; i++) { + makeAnOperation("mouseRelease", new Object[]{mouseButton}, new Class[]{MouseButton.class}); + makeAnOperation("mousePress", new Object[]{mouseButton}, new Class[]{MouseButton.class}); + } + mouseClick.sleep(); + makeAnOperation("mouseRelease", new Object[]{mouseButton}, new Class[]{MouseButton.class}); + releaseModifiers(modifiers); + } + + /** + * @deprecated Implementation doesn't seem to be correct as it ignores mouseButton and modifiers + * @param point todo document + * @param mouseButton One of MouseEvent.BUTTON*_MASK + * @param modifiers todo document + */ + public void dragMouse(Point point, int mouseButton, int modifiers) { + moveMouse(point); + } + + /** + * Performs drag and drop from startPoint to endPoint using specified + * mouseButton and modifiers to perform it. + * @param startPoint Screen coordinates of drag start point + * @param endPoint Screen coordinates of drag end point + * @param mouseButton One of MouseEvent.BUTTON*_MASK + * @param modifiers Combination of InputEvent.*_DOWN_MASK + * @param before Timeout between pressing mouse at the startPoint and + * mouse move + * @param after Timeout between mouse move to the endPoint and mouse + * release + */ + public void dragNDrop(Point startPoint, Point endPoint, MouseButton mouseButton, Modifier modifiers[], Timeout before, Timeout after) { + moveMouse(startPoint); + pressMouse(mouseButton, modifiers); + before.sleep(); + moveMouse(endPoint); + after.sleep(); + releaseMouse(mouseButton, modifiers); + } + + /** + * Presses a key. + * @param kbdButton Key code (KeyEventVK_* field. + * @param modifiers a combination of InputEvent.*_MASK fields. + */ + public void pressKey(KeyboardButton kbdButton, Modifier... modifiers) { + pressModifiers(modifiers); + makeAnOperation("keyPress", + new Object[]{kbdButton}, + new Class[]{KeyboardButton.class}); + } + + /** + * Releases a key. + * @param kbdButton Key code (KeyEventVK_* field. + * @param modifiers a combination of InputEvent.*_MASK fields. + */ + public void releaseKey(KeyboardButton kbdButton, Modifier... modifiers) { + makeAnOperation("keyRelease", + new Object[]{kbdButton}, + new Class[]{KeyboardButton.class}); + releaseModifiers(modifiers); + } + + /** + * Turns the wheel. + * @param p todo document + * @param amount Either positive or negative + * @param modifiers a combination of InputEvent.*_MASK fields. + */ + public void turnWheel(Point p, int amount, Modifier... modifiers) { + pressModifiers(modifiers); + moveMouse(p); + java.awt.Robot r = null; + makeAnOperation("mouseWheel", + new Object[]{amount}, + new Class[]{Integer.TYPE}); + releaseModifiers(modifiers); + } + + /** + * Performs a single operation. + * @param method a name of java.awt.Robot method. + * @param params method parameters + * @param paramClasses method parameters classes + */ + public void makeAnOperation(final String method, final Object[] params, final Class[] paramClasses) { + RobotExecutor.get().makeAnOperation(method, params, paramClasses); + } + + final static int SHIFT_MASK = InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK; + final static int ALT_GRAPH_MASK = InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.ALT_GRAPH_MASK; + final static int ALT_MASK = InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK; + final static int META_MASK = InputEvent.META_DOWN_MASK | InputEvent.META_MASK; + final static int CTRL_MASK = InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK; + + /** + * Presses modifiers keys by robot. + * @param modifiers a combination of InputEvent.*_MASK fields. + */ + protected void pressModifiers(Modifier... modifiers) { + for (Modifier modifier : modifiers) { // TODO: ALT_GRAPH_MASK? + if (modifier == KeyboardModifiers.ALT_DOWN_MASK) { + pressKey(KeyboardButtons.ALT); + } else if (modifier == KeyboardModifiers.CTRL_DOWN_MASK) { + pressKey(KeyboardButtons.CONTROL); + } else if (modifier == KeyboardModifiers.META_DOWN_MASK) { + pressKey(KeyboardButtons.META); + } else if (modifier == KeyboardModifiers.SHIFT_DOWN_MASK) { + pressKey(KeyboardButtons.SHIFT); + } + } + } + + /** + * Releases modifiers keys by robot. + * @param modifiers a combination of InputEvent.*_MASK fields. + */ + protected void releaseModifiers(Modifier... modifiers) { + for (Modifier modifier : modifiers) { // TODO: ALT_GRAPH_MASK? + if (modifier == KeyboardModifiers.ALT_DOWN_MASK) { + releaseKey(KeyboardButtons.ALT); + } else if (modifier == KeyboardModifiers.CTRL_DOWN_MASK) { + releaseKey(KeyboardButtons.CONTROL); + } else if (modifier == KeyboardModifiers.META_DOWN_MASK) { + releaseKey(KeyboardButtons.META); + } else if (modifier == KeyboardModifiers.SHIFT_DOWN_MASK) { + releaseKey(KeyboardButtons.SHIFT); + } + } + } + /** + * If java.awt.Robot is running in other JVM, it shutdowns that JVM + * @see AWTRobotInputFactory#runInOtherJVM(boolean) + */ + public static void exit() { + RobotExecutor.get().exit(); + } +}