/*
 * Copyright (c) 2010, 2018, 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 javafx.scene.robot;

import static com.sun.javafx.FXPermissions.CREATE_ROBOT_PERMISSION;

import java.util.Objects;

import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.paint.Color;

import com.sun.glass.ui.Application;
import com.sun.glass.ui.GlassRobot;
import com.sun.javafx.tk.Toolkit;

A Robot is used for simulating user interaction such as typing keys on the keyboard and using the mouse as well as capturing graphical information without requiring a Scene instance. Robot objects must be constructed and used on the JavaFX Application Thread.
Since:11
/** * A {@code Robot} is used for simulating user interaction such as * typing keys on the keyboard and using the mouse as well as capturing * graphical information without requiring a {@link javafx.scene.Scene} * instance. Robot objects must be constructed and used on the JavaFX * Application Thread. * * @since 11 */
public final class Robot { private final GlassRobot peer;
Constructs a new Robot that can be used for simulating user interactions. If a security manager is present, the application must have the FXPermission "createRobot" permission in order to construct a Robot object.
Throws:
/** * Constructs a new {@code Robot} that can be used for simulating user * interactions. If a security manager is present, the application must * have the {@link javafx.util.FXPermission} {@code "createRobot"} permission * in order to construct a {@code Robot} object. * * @throws IllegalStateException if this object is constructed on a thread * other than the JavaFX Application Thread. * @throws SecurityException if a security manager exists and the application * does not have the {@link javafx.util.FXPermission} {@code "createRobot"} * permission. */
public Robot() { Application.checkEventThread(); // Ensure we have proper permission for creating a robot. final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(CREATE_ROBOT_PERMISSION); } peer = Toolkit.getToolkit().createRobot(); peer.create(); }
Presses the specified KeyCode key.
Params:
  • keyCode – the key to press
Throws:
/** * Presses the specified {@link KeyCode} key. * * @param keyCode the key to press * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if keyCode is {@literal null}. */
public void keyPress(KeyCode keyCode) { Objects.requireNonNull(keyCode, "keyCode must not be null"); peer.keyPress(keyCode); }
Releases the specified KeyCode key.
Params:
  • keyCode – the key to release
Throws:
/** * Releases the specified {@link KeyCode} key. * * @param keyCode the key to release * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if keyCode is {@literal null}. */
public void keyRelease(KeyCode keyCode) { Objects.requireNonNull(keyCode, "keyCode must not be null"); peer.keyRelease(keyCode); }
Types the specified KeyCode key.
Params:
  • keyCode – the key to type
Throws:
Implementation Requirements:This is a convenience method that is equivalent to calling keyPress(KeyCode) followed by keyRelease(KeyCode).
/** * Types the specified {@link KeyCode} key. * * @implSpec This is a convenience method that is equivalent to calling * {@link #keyPress(KeyCode)} followed by {@link #keyRelease(KeyCode)}. * @param keyCode the key to type * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if keyCode is {@literal null}. */
public void keyType(KeyCode keyCode) { Objects.requireNonNull(keyCode, "keyCode must not be null"); keyPress(keyCode); keyRelease(keyCode); }
Returns the current mouse x position in screen coordinates.
Throws:
Returns:the current mouse x position
/** * Returns the current mouse {@code x} position in screen coordinates. * * @return the current mouse {@code x} position * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public double getMouseX() { return peer.getMouseX(); }
Returns the current mouse y position in screen coordinates.
Throws:
Returns:the current mouse y position
/** * Returns the current mouse {@code y} position in screen coordinates. * * @return the current mouse {@code y} position * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public double getMouseY() { return peer.getMouseY(); }
Returns the current mouse (x,y) screen coordinates as a Point2D.
Throws:
Returns:the current mouse (x,y) screen coordinates
/** * Returns the current mouse (x,y) screen coordinates as a {@link Point2D}. * * @return the current mouse (x,y) screen coordinates * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public Point2D getMousePosition() { return new Point2D(getMouseX(), getMouseY()); }
Moves the mouse to the specified (x,y) screen coordinates relative to the primary screen.
Params:
  • x – screen coordinate x to move the mouse to
  • y – screen coordinate y to move the mouse to
Throws:
/** * Moves the mouse to the specified (x,y) screen coordinates relative to * the primary screen. * * @param x screen coordinate x to move the mouse to * @param y screen coordinate y to move the mouse to * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public void mouseMove(double x, double y) { peer.mouseMove(x, y); }
Moves the mouse to the (x,y) screen coordinates, relative to the primary screen, specified by the given location.
Params:
  • location – the (x,y) coordinates to move the mouse to
Throws:
/** * Moves the mouse to the (x,y) screen coordinates, relative to the primary * screen, specified by the given {@code location}. * * @param location the (x,y) coordinates to move the mouse to * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if location is {@literal null}. */
public final void mouseMove(Point2D location) { Objects.requireNonNull(location); mouseMove(location.getX(), location.getY()); }
Presses the specified MouseButtons.
Params:
  • buttons – the mouse buttons to press
Throws:
/** * Presses the specified {@link MouseButton}s. * * @param buttons the mouse buttons to press * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if buttons is {@literal null}. */
public void mousePress(MouseButton... buttons) { Objects.requireNonNull(buttons, "buttons must not be null"); peer.mousePress(buttons); }
Releases the specified MouseButtons.
Params:
  • buttons – the mouse buttons to release
Throws:
/** * Releases the specified {@link MouseButton}s. * * @param buttons the mouse buttons to release * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if buttons is {@literal null}. */
public void mouseRelease(MouseButton... buttons) { Objects.requireNonNull(buttons, "buttons must not be null"); peer.mouseRelease(buttons); }
Clicks the specified MouseButtons.
Params:
  • buttons – the mouse buttons to click
Throws:
Implementation Requirements:This is a convenience method that is equivalent to calling mousePress(MouseButton...) followed by mouseRelease(MouseButton...).
/** * Clicks the specified {@link MouseButton}s. * * @implSpec This is a convenience method that is equivalent to calling * {@link #mousePress(MouseButton...)} followed by {@link #mouseRelease(MouseButton...)}. * @param buttons the mouse buttons to click * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if buttons is {@literal null}. */
public void mouseClick(MouseButton... buttons) { Objects.requireNonNull(buttons, "buttons must not be null"); mousePress(buttons); mouseRelease(buttons); }
Scrolls the mouse wheel by the specified amount of wheel clicks. A positive wheelAmt scrolls the wheel towards the user (down) whereas negative amounts scrolls the wheel away from the user (up).
Params:
  • wheelAmt – the (signed) amount of clicks to scroll the wheel
Throws:
/** * Scrolls the mouse wheel by the specified amount of wheel clicks. A positive * {@code wheelAmt} scrolls the wheel towards the user (down) whereas negative * amounts scrolls the wheel away from the user (up). * * @param wheelAmt the (signed) amount of clicks to scroll the wheel * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public void mouseWheel(int wheelAmt) { peer.mouseWheel(wheelAmt); }
Returns the Color of the pixel at the screen coordinates relative to the primary screen specified by location. Regardless of the scale of the screen (Screen.getOutputScaleX(), Screen.getOutputScaleY()), this method only samples a single pixel. For example, on a HiDPI screen with output scale 2, the screen unit at the point (x,y) may have 4 pixels. In this case the color returned is the color of the top, left pixel. Color values are not averaged when a screen unit is made up of more than one pixel.
Params:
  • x – the x coordinate to get the pixel color from
  • y – the y coordinate to get the pixel color from
Throws:
Returns:the pixel color at the specified screen coordinates
/** * Returns the {@link Color} of the pixel at the screen coordinates relative to the * primary screen specified by {@code location}. Regardless of the scale of the screen * ({@link javafx.stage.Screen#getOutputScaleX()}, {@link javafx.stage.Screen#getOutputScaleY()}), * this method only samples a single pixel. For example, on a HiDPI screen with output * scale 2, the screen unit at the point (x,y) may have 4 pixels. In this case the color * returned is the color of the top, left pixel. Color values are <em>not</em> * averaged when a screen unit is made up of more than one pixel. * * @param x the x coordinate to get the pixel color from * @param y the y coordinate to get the pixel color from * @return the pixel color at the specified screen coordinates * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public Color getPixelColor(double x, double y) { return peer.getPixelColor(x, y); }
Returns the Color of the pixel at the screen coordinates relative to the primary screen specified by location. Regardless of the scale of the screen (Screen.getOutputScaleX(), Screen.getOutputScaleY()), this method only samples a single pixel. For example, on a HiDPI screen with output scale 2, the screen unit at the point (x,y) may have 4 pixels. In this case the color returned is the color of the top, left pixel. Color values are not averaged when a screen unit is made up of more than one pixel.
Params:
  • location – the (x,y) coordinates to get the pixel color from
Throws:
Returns:the pixel color at the specified screen coordinates
/** * Returns the {@link Color} of the pixel at the screen coordinates relative to the * primary screen specified by {@code location}. Regardless of the scale of the screen * ({@link javafx.stage.Screen#getOutputScaleX()}, {@link javafx.stage.Screen#getOutputScaleY()}), * this method only samples a single pixel. For example, on a HiDPI screen with output * scale 2, the screen unit at the point (x,y) may have 4 pixels. In this case the color * returned is the color of the top, left pixel. Color values are <em>not</em> * averaged when a screen unit is made up of more than one pixel. * * @param location the (x,y) coordinates to get the pixel color from * @return the pixel color at the specified screen coordinates * @throws NullPointerException if the given {@code location} is {@literal null} * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public Color getPixelColor(Point2D location) { return getPixelColor(location.getX(), location.getY()); }
Returns a WritableImage containing the specified rectangular area relative to the primary screen. If the given image is null, or if the given image is not the required size, a new WritableImage will be created and returned. Otherwise, the given image is re-used.

If the scaleToFit argument is false, the returned Image object dimensions may differ from the requested width and height depending on how many physical pixels the area occupies on the screen. For example, in HiDPI mode on the Mac (aka Retina display) the pixels are doubled, and thus a screen capture of an area of size (10x10) pixels will result in an Image with dimensions (20x20). Calling code should use the returned images's Image.getWidth() and Image.getHeight() methods to determine the actual image size.

If scaleToFit is true, the returned Image is of the requested size. Note that in this case the image will be scaled in order to fit to the requested dimensions if necessary, such as when running on a HiDPI display.

Params:
  • image – either null or a WritableImage that will be used to place the screen capture in
  • x – the starting x-position of the rectangular area to capture
  • y – the starting y-position of the rectangular area to capture
  • width – the width of the rectangular area to capture
  • height – the height of the rectangular area to capture
  • scaleToFit – If true, the returned Image will be scaled to fit the request dimensions (if necessary). Otherwise, the size of the returned image will depend on the output scale (DPI) of the primary screen.
Throws:
Returns:the screen capture of the specified region as a WritableImage
/** * Returns a {@link WritableImage} containing the specified rectangular area relative * to the primary screen. If the given {@code image} is {@literal null}, or if the given * {@code image} is not the required size, a new {@code WritableImage} will be created * and returned. Otherwise, the given {@code image} is re-used. * <p> * If the {@code scaleToFit} argument is {@literal false}, the returned * {@code Image} object dimensions may differ from the requested {@code width} * and {@code height} depending on how many physical pixels the area occupies * on the screen. For example, in HiDPI mode on the Mac (aka Retina display) the * pixels are doubled, and thus a screen capture of an area of size (10x10) pixels * will result in an {@code Image} with dimensions (20x20). Calling code should * use the returned images's {@link Image#getWidth()} and {@link Image#getHeight()} * methods to determine the actual image size. * <p> * If {@code scaleToFit} is {@literal true}, the returned {@code Image} is of * the requested size. Note that in this case the image will be scaled in * order to fit to the requested dimensions if necessary, such as when running * on a HiDPI display. * * @param image either {@literal null} or a {@code WritableImage} that will * be used to place the screen capture in * @param x the starting x-position of the rectangular area to capture * @param y the starting y-position of the rectangular area to capture * @param width the width of the rectangular area to capture * @param height the height of the rectangular area to capture * @param scaleToFit If {@literal true}, the returned {@code Image} will be * scaled to fit the request dimensions (if necessary). Otherwise, the size * of the returned image will depend on the output scale (DPI) of the primary * screen. * @return the screen capture of the specified {@code region} as a {@link WritableImage} * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public WritableImage getScreenCapture(WritableImage image, double x, double y, double width, double height, boolean scaleToFit) { return peer.getScreenCapture(image, x, y, width, height, scaleToFit); }
Returns a WritableImage containing the specified rectangular area relative to the primary screen. If the given image is null, or if the given image is not the required size, a new WritableImage will be created and returned. Otherwise, the given image is re-used.
Params:
  • image – either null or a WritableImage that will be used to place the screen capture in
  • x – the starting x-position of the rectangular area to capture
  • y – the starting y-position of the rectangular area to capture
  • width – the width of the rectangular area to capture
  • height – the height of the rectangular area to capture
Throws:
Implementation Requirements:This method is equivalent to calling getScreenCapture(x, y, width, height, true), that is, this method scales the image to fit the requested size.
Returns:the screen capture of the specified region as a WritableImage
/** * Returns a {@link WritableImage} containing the specified rectangular area relative * to the primary screen. If the given {@code image} is {@literal null}, or if the given * {@code image} is not the required size, a new {@code WritableImage} will be created * and returned. Otherwise, the given {@code image} is re-used. * * @implSpec This method is equivalent to calling {@code getScreenCapture(x, y, width, height, true)}, * that is, this method scales the image to fit the requested size. * @param image either {@literal null} or a {@code WritableImage} that will * be used to place the screen capture in * @param x the starting x-position of the rectangular area to capture * @param y the starting y-position of the rectangular area to capture * @param width the width of the rectangular area to capture * @param height the height of the rectangular area to capture * @return the screen capture of the specified {@code region} as a {@link WritableImage} * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. */
public WritableImage getScreenCapture(WritableImage image, double x, double y, double width, double height) { return getScreenCapture(image, x, y, width, height, true); }
Returns a WritableImage containing the specified rectangular area relative to the primary screen. If the given image is null, or if the given image is not the required size, a new WritableImage will be created and returned. Otherwise, the given image is re-used.
Params:
  • image – either null or a WritableImage that will be used to place the screen capture in
  • region – the rectangular area of the screen to capture
Throws:
Implementation Requirements:This method is equivalent to calling getScreenCapture(image, region, true), that is, this method scales the image to fit the requested size.
Returns:the screen capture of the specified region as a WritableImage
/** * Returns a {@link WritableImage} containing the specified rectangular area relative * to the primary screen. If the given {@code image} is {@literal null}, or if the given * {@code image} is not the required size, a new {@code WritableImage} will be created * and returned. Otherwise, the given {@code image} is re-used. * * @implSpec This method is equivalent to calling {@code getScreenCapture(image, region, true)}, * that is, this method scales the image to fit the requested size. * @param image either {@literal null} or a {@code WritableImage} that will * be used to place the screen capture in * @param region the rectangular area of the screen to capture * @return the screen capture of the specified {@code region} as a {@link WritableImage} * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if region is {@literal null}. */
public WritableImage getScreenCapture(WritableImage image, Rectangle2D region) { Objects.requireNonNull(region); return getScreenCapture(image, region.getMinX(), region.getMinY(), region.getWidth(), region.getHeight(), true); }
Returns a WritableImage containing the specified rectangular area relative to the primary screen. If the given image is null, or if the given image is not the required size, a new WritableImage will be created and returned. Otherwise, the given image is re-used.

If the scaleToFit argument is false, the returned Image object dimensions may differ from the requested width and height depending on how many physical pixels the area occupies on the screen. For example, in HiDPI mode on the Mac (aka Retina display) the pixels are doubled, and thus a screen capture of an area of size (10x10) pixels will result in an Image with dimensions (20x20). Calling code should use the returned images's Image.getWidth() and Image.getHeight() methods to determine the actual image size.

If scaleToFit is true, the returned Image is of the requested size. Note that in this case the image will be scaled in order to fit to the requested dimensions if necessary, such as when running on a HiDPI display.

Params:
  • image – either null or a WritableImage that will be used to place the screen capture in
  • region – the rectangular area of the screen to capture
  • scaleToFit – if true, the returned Image will be scaled to fit the request dimensions (if necessary). Otherwise, the size of the returned image will depend on the output scale (DPI) of the primary screen.
Throws:
Returns:the screen capture of the specified region as a WritableImage
/** * Returns a {@link WritableImage} containing the specified rectangular area relative to * the primary screen. If the given {@code image} is {@literal null}, or if the given * {@code image} is not the required size, a new {@code WritableImage} will be created * and returned. Otherwise, the given {@code image} is re-used. * <p> * If the {@code scaleToFit} argument is {@literal false}, the returned * {@code Image} object dimensions may differ from the requested {@code width} * and {@code height} depending on how many physical pixels the area occupies * on the screen. For example, in HiDPI mode on the Mac (aka Retina display) the * pixels are doubled, and thus a screen capture of an area of size (10x10) pixels * will result in an {@code Image} with dimensions (20x20). Calling code should * use the returned images's {@link Image#getWidth()} and {@link Image#getHeight()} * methods to determine the actual image size. * <p> * If {@code scaleToFit} is {@literal true}, the returned {@code Image} is of * the requested size. Note that in this case the image will be scaled in * order to fit to the requested dimensions if necessary, such as when running * on a HiDPI display. * * @param image either {@literal null} or a {@code WritableImage} that will * be used to place the screen capture in * @param region the rectangular area of the screen to capture * @param scaleToFit if {@literal true}, the returned {@code Image} will be * scaled to fit the request dimensions (if necessary). Otherwise, the size * of the returned image will depend on the output scale (DPI) of the primary * screen. * @return the screen capture of the specified {@code region} as a {@link WritableImage} * @throws IllegalStateException if this method is called on a thread * other than the JavaFX Application Thread. * @throws NullPointerException if region is {@literal null}. */
public WritableImage getScreenCapture(WritableImage image, Rectangle2D region, boolean scaleToFit) { Objects.requireNonNull(region); return getScreenCapture(image, region.getMinX(), region.getMinY(), region.getWidth(), region.getHeight(), scaleToFit); } }