--- /dev/null 2014-03-28 16:59:30.287562856 +0400 +++ new/test/lib/testlibrary/ExtendedRobot.java 2014-03-31 15:25:35.918153221 +0400 @@ -0,0 +1,291 @@ +/* + * Copyright (c) 1999, 2009, 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. + */ + +import sun.awt.ExtendedKeyCodes; +import sun.awt.SunToolkit; +import java.awt.AWTException; +import java.awt.Robot; +import java.awt.GraphicsDevice; +import java.awt.Toolkit; +import java.awt.Point; +import java.awt.MouseInfo; +import java.awt.event.InputEvent; + +/** + * ExtendedRobot is a wrapper around java.awt.Robot that provides some convenience + * methods. It contains methods that are ought to be moved to {@code java.awt.Robot} + * class + *

+ * When using jtreg you would include this class via something like: + *

+ * {@literal @}library ../../../../lib/testlibrary
+ * {@literal @}build ExtendedRobot
+ * 
+ * + * @author Dmitriy Ermashov + * @since 1.9 + */ + +public class ExtendedRobot extends Robot { + + private static int DEFAULT_SPEED = 20; // Speed for mouse glide and click + private static int DEFAULT_SYNC_DELAY = 500; // Additional delay for realSync + private static int DEFAULT_STEP_LENGTH = 2; // Step length (in pixels) for mouse glide + + private int syncDelay = DEFAULT_SYNC_DELAY; + + /** + * {@inheritDoc} + */ + public ExtendedRobot() throws AWTException { + super(); + } + + /** + * {@inheritDoc} + */ + public ExtendedRobot(GraphicsDevice screen) throws AWTException { + super(screen); + } + + /** + * Sets the delay length for {@link #waitForIdle()} method + * + * @param delay Delay value + */ + public void setSyncDelay(int delay){ + this.syncDelay = delay; + } + + /** + * Returns delay length for {@link #waitForIdle()} method + * + * @return Current delay value + */ + public int getSyncDelay(){ + return this.syncDelay; + } + + /** + * Clicks mouse button(s) by calling {@link java.awt.Robot#mousePress(int)} + * and {@link java.awt.Robot#mouseRelease(int)} methods + * + * @param buttons the Button mask; a combination of one or more + * mouse button masks. + * @see #mousePress(int) + * @see #mouseRelease(int) + */ + public void click(int buttons) { + mousePress(buttons); + waitForIdle(DEFAULT_SPEED); + mouseRelease(buttons); + waitForIdle(); + } + + /** + * Clicks mouse button 1 + * + * @see #click(int) + */ + public void click() { + click(InputEvent.BUTTON1_DOWN_MASK); + } + + /** + * Waits until all events currently on the event queue have been processed. + * It uses more advanced method of synchronizing threads unlike {@link java.awt.Robot#waitForIdle()} + * + * @param delayValue Delay length in milliseconds to wait until realSync been executed + */ + public synchronized void waitForIdle(int delayValue) { + SunToolkit.flushPendingEvents(); + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + delay(delayValue); + } + + /** + * Waits until all events currently on the event queue have been processed + * with delay {@link #getSyncDelay()} after using {@link sun.awt.SunToolkit#realSync()} call. + * It uses more advanced method of synchronizing threads unlike {@link java.awt.Robot#waitForIdle()} + * + * @see #waitForIdle(int) + */ + @Override + public synchronized void waitForIdle() { + waitForIdle(syncDelay); + } + + /** + * Move the mouse in multiple steps from where it is + * now to the destination coordinates.

+ * + * @param x Destination point x coordinate + * @param y Destination point y coordinate + * @see #glide(java.awt.Point) + */ + public void glide(int x, int y) { + glide(new Point(x, y)); + } + + /** + * Move the mouse in multiple steps from where it is + * now to the destination point.

+ * + * @param dest Destination point + * @see #glide(java.awt.Point, java.awt.Point) + */ + public void glide(Point dest) { + glide(MouseInfo.getPointerInfo().getLocation(), dest); + } + + /** + * Move the mouse in multiple steps from source coordinates + * to the destination coordinates.

+ * + * @param fromX Source point x coordinate + * @param fromY Source point y coordinate + * @param toX Destination point x coordinate + * @param toY Destination point y coordinate + * @see #glide(java.awt.Point, java.awt.Point) + */ + public void glide(int fromX, int fromY, int toX, int toY) { + glide(new Point(fromX, fromY), new Point(toX, toY)); + } + + /** + * Move the mouse in multiple steps from source point to the + * destination point with default speed and step length. + * + * @param src Source point + * @param dest Destination point + * @see #glide(java.awt.Point, java.awt.Point, int, int) + */ + public void glide(Point src, Point dest) { + glide(src, dest, DEFAULT_STEP_LENGTH, DEFAULT_SPEED); + } + + /** + * Move the mouse in multiple steps from source point to the + * destination point with given speed and step length. + * + * @param src Source point + * @param dest Destination point + * @param stepLength Approximate length of one step + * @param speed Delay between steps. + * @see #mouseMove(int, int) + * @see #delay(int) + */ + public void glide(Point src, Point dest, int stepLength, int speed) { + int stepNum; + double tDx, tDy; + double dx, dy, ds; + double x, y; + + dx = (dest.getX() - src.getX()); + dy = (dest.getY() - src.getY()); + ds = Math.sqrt(dx*dx + dy*dy); + + tDx = dx / ds * stepLength; + tDy = dy / ds * stepLength; + + int stepsCount = (int) ds / stepLength; + + // Walk the mouse to the destination one step at a time + mouseMove(src.x, src.y); + + for (x = src.x, y = src.y, stepNum = 0; + stepNum < stepsCount; + stepNum++) { + x += tDx; + y += tDy; + mouseMove((int)x, (int)y); + delay(speed); + } + + // Ensure the mouse moves to the right destination. + // The steps may have led the mouse to a slightly wrong place. + mouseMove(dest.x, dest.y); + } + + /** + * Moves mouse pointer to given screen coordinates. + * + * @param position Point position + * @see java.awt.Robot#mouseMove(int, int) + */ + public synchronized void mouseMove(Point position) { + mouseMove(position.x, position.y); + } + + /** + * Successively presses and releases a given key. + *

+ * Key codes that have more than one physical key associated with them + * (e.g. {@code KeyEvent.VK_SHIFT} could mean either the + * left or right shift key) will map to the left key. + * + * @param kc Key to press (e.g. {@code KeyEvent.VK_A}) + * @see java.awt.Robot#keyPress(int) + * @see java.awt.Robot#keyRelease(int) + * @see java.awt.event.KeyEvent + */ + public void type(int kc) { + keyPress(kc); + keyRelease(kc); + } + + /** + * Types given character + * + * @param c Character to be typed (e.g. {@code 'a'}) + * @see #type(int) + * @see java.awt.event.KeyEvent + */ + public void type(char c) { + type(ExtendedKeyCodes.getExtendedKeyCodeForChar(c)); + } + + /** + * Types given array of characters one by one + * + * @param symbols Array of characters to be typed + * @see #type(char) + */ + public void type(char[] symbols) { + for (int i = 0; i < symbols.length; i++) { + type(symbols[i]); + } + } + + /** + * Types given string + * + * @param s String to be typed + * @see #type(char[]) + */ + public void type(String s) { + type(s.toCharArray()); + } +}