changeset 11003:202fc7cbc4d5

8207377: Document the behavior of Robot::getPixelColor with HiDPI Reviewed-by: kcr
author mennen
date Tue, 24 Jul 2018 15:18:52 -0700
parents 504705a06aa3
children 343ad315df2e
files modules/javafx.graphics/src/main/java/com/sun/glass/ui/GlassRobot.java modules/javafx.graphics/src/main/java/javafx/scene/robot/Robot.java tests/system/src/test/java/test/robot/javafx/scene/RobotTest.java
diffstat 3 files changed, 52 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/GlassRobot.java	Tue Jul 24 09:02:55 2018 -0700
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/GlassRobot.java	Tue Jul 24 15:18:52 2018 -0700
@@ -117,8 +117,13 @@
     public abstract void mouseWheel(int wheelAmt);
 
     /**
-     * Returns the {@link Color} of the pixel at the specified screen coordinates
-     * relative to the primary screen.
+     * 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 Screen#getOutputScaleX()}, {@link 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
--- a/modules/javafx.graphics/src/main/java/javafx/scene/robot/Robot.java	Tue Jul 24 09:02:55 2018 -0700
+++ b/modules/javafx.graphics/src/main/java/javafx/scene/robot/Robot.java	Tue Jul 24 15:18:52 2018 -0700
@@ -237,8 +237,13 @@
     }
 
     /**
-     * Returns the {@link Color} of the pixel at the specified screen coordinates
-     * relative to the primary screen.
+     * 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
@@ -252,7 +257,12 @@
 
     /**
      * Returns the {@link Color} of the pixel at the screen coordinates relative to the
-     * primary screen specified by {@code location}.
+     * 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
--- a/tests/system/src/test/java/test/robot/javafx/scene/RobotTest.java	Tue Jul 24 09:02:55 2018 -0700
+++ b/tests/system/src/test/java/test/robot/javafx/scene/RobotTest.java	Tue Jul 24 15:18:52 2018 -0700
@@ -31,6 +31,7 @@
 import javafx.application.Application;
 import javafx.application.Platform;
 import javafx.beans.InvalidationListener;
+import javafx.geometry.Insets;
 import javafx.geometry.Point2D;
 import javafx.scene.Scene;
 import javafx.scene.control.Button;
@@ -82,6 +83,7 @@
         test.testMouseClick();
         test.testMouseWheel();
         test.testPixelCapture();
+        test.testPixelCaptureAverage();
         test.testScreenCapture();
         exit();
     }
@@ -229,6 +231,36 @@
     }
 
     @Test
+    public void testPixelCaptureAverage() throws Exception {
+        CountDownLatch setSceneLatch = new CountDownLatch(1);
+        Pane pane = new StackPane();
+        InvalidationListener invalidationListener = observable -> setSceneLatch.countDown();
+        Util.runAndWait(() -> {
+            pane.setBackground(new Background(new BackgroundFill(Color.RED, null, new Insets(0, 0, 0, 0)),
+                    new BackgroundFill(Color.BLUE, null, new Insets(0, 0, 0, SIZE / 2))));
+            scene = new Scene(pane, SIZE, SIZE);
+            stage.sceneProperty().addListener(observable -> {
+                setSceneLatch.countDown();
+                stage.sceneProperty().removeListener(invalidationListener);
+            });
+            stage.setScene(scene);
+        });
+        waitForLatch(setSceneLatch, 5, "Timeout while waiting for scene to be set on stage.");
+        AtomicReference<Color> captureColor = new AtomicReference<>();
+        Thread.sleep(1000);
+        Util.runAndWait(() -> {
+            int x = (int) stage.getX();
+            int y = (int) stage.getY();
+            // Subtracting one pixel from x makes the result RED, so we are on the border.
+            // If the implementation of getPixelColor is ever chaged to interpolate the
+            // colors on HiDPI screens, this test will fail and the resulting color will
+            // be some combination of RED and BLUE (purple?).
+            captureColor.set(robot.getPixelColor(x + SIZE / 2, y + SIZE / 2));
+        });
+        assertColorEquals(Color.BLUE, captureColor.get(), TOLERANCE);
+    }
+
+    @Test
     public void testScreenCapture() throws Exception {
         CountDownLatch setSceneLatch = new CountDownLatch(1);
         Pane pane = new StackPane();