--- /dev/null 2014-03-28 17:53:11.000000000 +0400
+++ new/test/lib/testlibrary/RobotWrapper.java 2014-03-28 17:53:10.811367800 +0400
@@ -0,0 +1,360 @@
+/*
+ * 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.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;
+import java.awt.event.KeyEvent;
+
+/**
+ * RobotWrapper is a wrapper around java.awt.Robot that provides some convenience
+ * methods. It contains methods that are ought to be moved to java.awt.Robot
+ * class
+ *
+ * When using jtreg you would include this class via something like: + *
+ * {@literal @}library ../../../regtesthelpers + * {@literal @}build RobotWrapper + *+ * + * @author Dmitriy Ermashov, David Herron + * @since 1.9 + */ + +public class RobotWrapper extends Robot { + + private static int DEFAULT_SPEED = 20; // Speed for mouse glide and click + private static int DEFAULT_SYNC_DELAY = 100; // 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 RobotWrapper() throws AWTException { + super(); + } + + /** + * {@inheritDoc} + */ + public RobotWrapper(GraphicsDevice screen) throws AWTException { + super(screen); + } + + /** + * Sets the delay length for
waitForIdle()
method
+ *
+ * @param delay Delay value
+ */
+ public void setSyncDelay(int delay){
+ this.syncDelay = delay;
+ }
+
+ /**
+ * Returns delay length for waitForIdle()
method
+ *
+ * @return Current delay value
+ */
+ public int setSyncDelay(){
+ return this.syncDelay;
+ }
+
+ /**
+ * Clicks mouse button(s) by calling java.awt.Robot.mousePress(int)
+ * and 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();
+ mouseRelease(buttons);
+ waitForIdle();
+ }
+
+ /**
+ * Clicks mouse button 1 with the default pause between Press and Release.
+ *
+ * @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 java.awt.Robot#waitForIdle()
+ */
+ public synchronized void waitForIdle() {
+ SunToolkit.flushPendingEvents();
+ ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ delay(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. 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. 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. 'a'
)
+ * @see #type(int)
+ * @see java.awt.event.KeyEvent
+ */
+ public void type(char c) {
+ try {
+ if (Character.isLetter(c)) {
+ boolean low = Character.isLowerCase(c);
+ if (!low)
+ keyPress(KeyEvent.VK_SHIFT);
+ type(Character.getNumericValue(c) + 55);
+ if (!low)
+ keyRelease(KeyEvent.VK_SHIFT);
+ return;
+ }
+ if (Character.isDigit(c)) {
+ switch (c) {
+ case '0': type(KeyEvent.VK_0); break;
+ case '1': type(KeyEvent.VK_1); break;
+ case '2': type(KeyEvent.VK_2); break;
+ case '3': type(KeyEvent.VK_3); break;
+ case '4': type(KeyEvent.VK_4); break;
+ case '5': type(KeyEvent.VK_5); break;
+ case '6': type(KeyEvent.VK_6); break;
+ case '7': type(KeyEvent.VK_7); break;
+ case '8': type(KeyEvent.VK_8); break;
+ case '9': type(KeyEvent.VK_9); break;
+ }
+ return;
+ }
+ if (Character.isWhitespace(c)) {
+ switch (c) {
+ case '\t': type(KeyEvent.VK_TAB); break;
+ case '\n': type(KeyEvent.VK_ENTER); break;
+ case '\f':
+ keyPress(KeyEvent.VK_CONTROL);
+ type(KeyEvent.VK_L);
+ keyRelease(KeyEvent.VK_CONTROL);
+ break;
+ case ' ': type(KeyEvent.VK_SPACE); break;
+ }
+ return;
+ }
+ if (Character.isISOControl(c)) {
+ keyPress(KeyEvent.VK_CONTROL);
+ type(c + ' ');
+ keyRelease(KeyEvent.VK_CONTROL);
+ return;
+ }
+ switch (c) {
+ case '!': type(KeyEvent.VK_EXCLAMATION_MARK); return;
+ case '@': type(KeyEvent.VK_AT); return;
+ case '#': type(KeyEvent.VK_NUMBER_SIGN); return;
+ case '$': type(KeyEvent.VK_DOLLAR); return;
+ case '%': break;
+ case '^': type(KeyEvent.VK_CIRCUMFLEX); return;
+ case '&': type(KeyEvent.VK_AMPERSAND); return;
+ case '*': type(KeyEvent.VK_ASTERISK); return;
+ case '(': type(KeyEvent.VK_LEFT_PARENTHESIS); return;
+ case ')': type(KeyEvent.VK_RIGHT_PARENTHESIS); return;
+ case '-': type(KeyEvent.VK_MINUS); return;
+ case '_': type(KeyEvent.VK_UNDERSCORE); return;
+ case '=': type(KeyEvent.VK_EQUALS); return;
+ case '+': type(KeyEvent.VK_PLUS); return;
+ case '\\': type(KeyEvent.VK_BACK_SLASH); return;
+ case '|': break;
+ case '`': type(KeyEvent.VK_BACK_QUOTE); return;
+ case '~': break;
+ case '[': type(KeyEvent.VK_OPEN_BRACKET); return;
+ case '{': type(KeyEvent.VK_BRACELEFT); return;
+ case '}': type(KeyEvent.VK_BRACERIGHT); return;
+ case ']': type(KeyEvent.VK_CLOSE_BRACKET); return;
+ case ';': type(KeyEvent.VK_SEMICOLON); return;
+ case ':': type(KeyEvent.VK_COLON); return;
+ case '\'': type(KeyEvent.VK_QUOTE); return;
+ case '"': type(KeyEvent.VK_QUOTEDBL); return;
+ case ',': type(KeyEvent.VK_COMMA); return;
+ case '<': type(KeyEvent.VK_LESS); return;
+ case '.': type(KeyEvent.VK_PERIOD); return;
+ case '>': type(KeyEvent.VK_GREATER); return;
+ case '/': type(KeyEvent.VK_SLASH); return;
+ case '?': break;
+ }
+ type(Character.getNumericValue(c) + 55);
+ } catch (Exception e) {
+ System.err.println("ProbeRobot.type: caught " + e.toString()
+ + " for character '" + 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());
+ }
+}