aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/awt/Robot.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/awt/Robot.java')
-rw-r--r--libjava/java/awt/Robot.java368
1 files changed, 321 insertions, 47 deletions
diff --git a/libjava/java/awt/Robot.java b/libjava/java/awt/Robot.java
index f633fc0b354..23b6f810442 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,386 @@ exception statement from your version. */
package java.awt;
+import gnu.java.awt.ClasspathToolkit;
+
+import java.lang.reflect.InvocationTargetException;
+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 used 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 all events currently on the event queue have been
+ * dispatched.
+ */
+ public void waitForIdle ()
{
+ if (EventQueue.isDispatchThread ())
+ throw new IllegalThreadStateException ("Robot: waitForIdle called from "
+ + "the event dispatch thread");
+
+ EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ try
+ {
+ q.invokeAndWait (new Runnable () { public void run () { } });
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println ("Robot: waitForIdle interrupted");
+ }
+ catch (InvocationTargetException e)
+ {
+ System.err.println ("Robot: waitForIdle cannot invoke target");
+ }
}
- 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
+}