Skip to content
This repository has been archived by the owner on Jun 24, 2021. It is now read-only.

JDK-8207377 Document behavior of getPixelColor on HiDPI. #140

Merged
merged 2 commits into from Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -116,8 +116,13 @@ public abstract class GlassRobot {
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
Expand Down
Expand Up @@ -251,7 +251,12 @@ public Color getPixelColor(double x, double y) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix looks good. There are two getPixelColor methods in Robot.java. Can you also update the docs for the other one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew I forgot something, lol.

/**
* 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
Expand Down
32 changes: 32 additions & 0 deletions tests/system/src/test/java/test/robot/javafx/scene/RobotTest.java
Expand Up @@ -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;
Expand Down Expand Up @@ -82,6 +83,7 @@ public static void main(String[] args) throws Exception {
test.testMouseClick();
test.testMouseWheel();
test.testPixelCapture();
test.testPixelCaptureAverage();
test.testScreenCapture();
exit();
}
Expand Down Expand Up @@ -228,6 +230,36 @@ public void testPixelCapture() throws Exception {
assertColorEquals(Color.CORNFLOWERBLUE, captureColor.get(), TOLERANCE);
}

@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);
Expand Down