diff options
Diffstat (limited to 'libjava/java/awt/Robot.java')
-rw-r--r-- | libjava/java/awt/Robot.java | 366 |
1 files changed, 319 insertions, 47 deletions
diff --git a/libjava/java/awt/Robot.java b/libjava/java/awt/Robot.java index f633fc0b354..49726c8a192 100644 --- a/libjava/java/awt/Robot.java +++ b/libjava/java/awt/Robot.java @@ -1,5 +1,5 @@ -/* Robot.java -- - Copyright (C) 2002 Free Software Foundation, Inc. +/* Robot.java -- a native input event generator + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,112 +38,384 @@ exception statement from your version. */ package java.awt; +import gnu.java.awt.ClasspathToolkit; + +import java.awt.event.InputEvent; import java.awt.image.BufferedImage; +import java.awt.peer.RobotPeer; /** + * The Robot class is used to simulate user interaction with graphical + * programs. It can generate native windowing system input events and + * retrieve image data from the current screen. Robot is used to test + * the AWT and Swing library implementations; it can also be used to + * create self-running demo programs. + * + * Since Robot generates native windowing system events, rather than + * simply inserting {@link AWTEvents} on the AWT event queue, its use + * is not restricted to Java programs. It can be to programatically + * drive any graphical application. + * + * This implementation requires an X server that supports the XTest + * extension. + * + * @author Thomas Fitzsimmons (fitzsim@redhat.com) + * * @since 1.3 */ -/** STUB CLASS ONLY */ public class Robot { - private GraphicsDevice screen; private boolean waitForIdle; private int autoDelay; - + private RobotPeer peer; + /** - * Creates a <code>Robot</code> object. - * - * @exception AWTException If GraphicsEnvironment.isHeadless() returns true. - * @exception SecurityException If createRobot permission is not granted. + * Construct a Robot object that operates on the default screen. + * + * @exception AWTException if GraphicsEnvironment.isHeadless() + * returns true or if the X server does not support the XTest + * extension + * @exception SecurityException if createRobot permission is not + * granted */ - public Robot() throws AWTException + public Robot () throws AWTException { - throw new Error("not implemented"); + if (GraphicsEnvironment.isHeadless ()) + throw new AWTException ("Robot: headless graphics environment"); + + SecurityManager sm = System.getSecurityManager (); + if (sm != null) + sm.checkPermission (new AWTPermission ("createRobot")); + + ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit (); + + // createRobot will throw AWTException if XTest is not supported. + peer = tk.createRobot (GraphicsEnvironment.getLocalGraphicsEnvironment () + .getDefaultScreenDevice ()); } /** - * Creates a <code>Robot</code> object. - * - * @exception AWTException If GraphicsEnvironment.isHeadless() returns true. - * @exception IllegalArgumentException If <code>screen</code> is not a screen - * GraphicsDevice. - * @exception SecurityException If createRobot permission is not granted. + * Construct a Robot object that operates on the specified screen. + * + * @exception AWTException if GraphicsEnvironment.isHeadless() + * returns true or if the X server does not support the XTest + * extension + * @exception IllegalArgumentException if screen is not a screen + * GraphicsDevice + * @exception SecurityException if createRobot permission is not + * granted */ - public Robot(GraphicsDevice screen) throws AWTException + public Robot (GraphicsDevice screen) throws AWTException { - this(); - this.screen = screen; + if (GraphicsEnvironment.isHeadless ()) + throw new AWTException ("Robot: headless graphics environment"); + + if (screen.getType () != GraphicsDevice.TYPE_RASTER_SCREEN) + throw new IllegalArgumentException ("Robot: graphics" + + " device is not a screen"); + + SecurityManager sm = System.getSecurityManager (); + if (sm != null) + sm.checkPermission (new AWTPermission ("createRobot")); + + ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit (); + + // createRobot will throw AWTException if XTest is not supported. + peer = tk.createRobot (screen); } + /** + * Move the mouse pointer to absolute coordinates (x, y). + * + * @param x the destination x coordinate + * @param y the destination y coordinate + */ public void mouseMove(int x, int y) { + peer.mouseMove (x, y); + + if (waitForIdle) + waitForIdle (); + + if (autoDelay > 0) + delay (autoDelay); } - public void mousePress(int buttons) + /** + * Press one or more mouse buttons. + * + * @param buttons the buttons to press; a bitmask of one or more of + * these {@link InputEvent} fields: + * + * <ul> + * <li>BUTTON1_MASK</li> + * <li>BUTTON2_MASK</li> + * <li>BUTTON3_MASK</li> + * </ul> + * + * @exception IllegalArgumentException if the button mask is invalid + */ + public void mousePress (int buttons) { + if ((buttons & InputEvent.BUTTON1_MASK) == 0 + && (buttons & InputEvent.BUTTON2_MASK) == 0 + && (buttons & InputEvent.BUTTON3_MASK) == 0) + throw new IllegalArgumentException ("Robot: mousePress:" + + " invalid button mask"); + + peer.mousePress (buttons); + + if (waitForIdle) + waitForIdle (); + + if (autoDelay > 0) + delay (autoDelay); } + /** + * Release one or more mouse buttons. + * + * @param buttons the buttons to release; a bitmask of one or more + * of these {@link InputEvent} fields: + * + * <ul> + * <li>BUTTON1_MASK</li> + * <li>BUTTON2_MASK</li> + * <li>BUTTON3_MASK</li> + * </ul> + * + * @exception IllegalArgumentException if the button mask is invalid + */ public void mouseRelease(int buttons) { + if ((buttons & InputEvent.BUTTON1_MASK) == 0 + && (buttons & InputEvent.BUTTON2_MASK) == 0 + && (buttons & InputEvent.BUTTON3_MASK) == 0) + throw new IllegalArgumentException ("Robot: mouseRelease:" + + " invalid button mask"); + + peer.mouseRelease (buttons); + + if (waitForIdle) + waitForIdle (); + + if (autoDelay > 0) + delay (autoDelay); } - public void mouseWheel(int wheelAmt) + /** + * Rotate the mouse scroll wheel. + * + * @param wheelAmt number of steps to rotate mouse wheel. negative + * to rotate wheel up (away from the user), positive to rotate wheel + * down (toward the user). + * + * @since 1.4 + */ + public void mouseWheel (int wheelAmt) { + peer.mouseWheel (wheelAmt); + + if (waitForIdle) + waitForIdle (); + + if (autoDelay > 0) + delay (autoDelay); } - public void keyPress(int keycode) + /** + * Press a key. + * + * @param keycode key to press, a {@link KeyEvent} VK_ constant + * + * @exception IllegalArgumentException if keycode is not a valid key + */ + public void keyPress (int keycode) { + peer.keyPress (keycode); + + if (waitForIdle) + waitForIdle (); + + if (autoDelay > 0) + delay (autoDelay); } - public void keyRelease(int keycode) + /** + * Release a key. + * + * @param keycode key to release, a {@link KeyEvent} VK_ constant + * + * @exception IllegalArgumentException if keycode is not a valid key + */ + public void keyRelease (int keycode) { + peer.keyRelease (keycode); + + if (waitForIdle) + waitForIdle (); + + if (autoDelay > 0) + delay (autoDelay); } - - public Color getPixelColor(int x, int y) + + /** + * Return the color of the pixel at the given screen coordinates. + * + * @param x the x coordinate of the pixel + * @param y the y coordinate of the pixel + * + * @return the Color of the pixel at screen coodinates <code>(x, y)</code> + */ + public Color getPixelColor (int x, int y) { - return null; + return new Color (peer.getRGBPixel (x, y)); } - public BufferedImage createScreenCapture(Rectangle screen) + /** + * Create an image containing pixels read from the screen. The + * image does not include the mouse pointer. + * + * @param screenRect the rectangle of pixels to capture, in screen + * coordinates + * + * @return a BufferedImage containing the requested pixels + * + * @exception IllegalArgumentException if requested width and height + * are not both greater than zero + * @exception SecurityException if readDisplayPixels permission is + * not granted + */ + public BufferedImage createScreenCapture (Rectangle screenRect) { - return null; + if (screenRect.width <= 0) + throw new IllegalArgumentException ("Robot: capture width is <= 0"); + + if (screenRect.height <= 0) + throw new IllegalArgumentException ("Robot: capture height is <= 0"); + + SecurityManager sm = System.getSecurityManager (); + if (sm != null) + sm.checkPermission (new AWTPermission ("readDisplayPixels")); + + int[] pixels = peer.getRGBPixels (screenRect); + + BufferedImage bufferedImage = + new BufferedImage (screenRect.width, screenRect.height, + BufferedImage.TYPE_INT_ARGB); + + bufferedImage.setRGB (0, 0, screenRect.width, screenRect.height, + pixels, 0, screenRect.width); + + return bufferedImage; } - - public boolean isAutoWaitForIdle() + + /** + * Check if this Robot automatically calls {@link waitForIdle} after + * generating an event. + * + * @return true if waitForIdle is automatically called + */ + public boolean isAutoWaitForIdle () { return waitForIdle; } - - public void setAutoWaitForIdle(boolean value) + + /** + * Set whether or not this Robot automatically calls {@link + * waitForIdle} after generating an event. + * + * @param isOn true if waitForIdle should be called automatically + */ + public void setAutoWaitForIdle (boolean isOn) { - waitForIdle = value; + waitForIdle = isOn; } - - public int getAutoDelay() + + /** + * Retrieve the length of time this Robot sleeps after generating an + * event. + * + * @return the length of time in milliseconds + */ + public int getAutoDelay () { return autoDelay; } - - public void setAutoDelay(int ms) + + /** + * Set the length of time this Robot sleeps after generating an + * event. + * + * @param ms the length of time in milliseconds + * + * @exception IllegalArgumentException if ms is not between 0 and + * 60,000 milliseconds inclusive + */ + public void setAutoDelay (int ms) { - if (ms < 0 || ms > 60000) - throw new IllegalArgumentException(); - + if (ms <= 0 || ms >= 60000) + throw new IllegalArgumentException ("Robot: delay length out-of-bounds"); + autoDelay = ms; } - public void delay(int ms) + /** + * Sleep for a specified length of time. + * + * @param ms the length of time in milliseconds + * + * @exception IllegalArgumentException if ms is not between 0 and + * 60,000 milliseconds inclusive + */ + public void delay (int ms) { if (ms < 0 || ms > 60000) - throw new IllegalArgumentException(); + throw new IllegalArgumentException ("Robot: delay length out-of-bounds"); + + try + { + Thread.sleep (ms); + } + catch (InterruptedException e) + { + System.err.println ("Robot: delay interrupted"); + } } - public void waitForIdle() + /** + * Wait until the event dispatch thread is idle. + */ + public void waitForIdle () { + if (EventQueue.isDispatchThread ()) + throw new IllegalThreadStateException ("Robot: waitForIdle called from " + + "the event dispatch thread"); + + EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue (); + + while (q.peekEvent () != null) + { + try + { + wait (); + } + catch (InterruptedException e) + { + System.err.println ("Robot: waitForIdle interrupted"); + } + } } - public String toString() + /** + * Return a string representation of this Robot. + * + * @return a string representation + */ + public String toString () { - return "unimplemented"; + return getClass ().getName () + + "[ autoDelay = " + autoDelay + ", autoWaitForIdle = " + + waitForIdle + " ]"; } -} // class Robot +} |