import com.sun.glass.ui.Robot; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.stage.Stage; import javafx.util.Duration; /** * Test program to show a bug in reading the initial window position of a * decorated, secondary stage on Ubuntu 14.04. This worked on earlier versions * of Ubuntu and also works fine on Mac and Windows. */ public class StagePositionBug extends Application { private static final int WIDTH = 400; private static final int HEIGHT = 300; private static final int CENTER_X = WIDTH / 2; private static final int CENTER_Y = HEIGHT / 2; private Robot robot; private void printStats(Scene scene) { double sceneX = scene.getX(); double sceneY = scene.getY(); double stageX = scene.getWindow().getX(); double stageY = scene.getWindow().getY(); System.err.println(""); System.err.println("Scene pos: " + sceneX + ", " + sceneY); System.err.println("Stage pos: " + stageX + ", " + stageY); System.err.println("Inner pos (computed): " + (stageX+sceneX) + ", " + (stageY+sceneY)); } private void moveCursorToCenter(Scene scene) { int centerX = CENTER_X; int centerY = CENTER_Y; centerX += scene.getX() + scene.getWindow().getX(); centerY += scene.getY() + scene.getWindow().getY(); robot.mouseMove(centerX, centerY); } @Override public void start(Stage unusedPrimaryStage) { robot = com.sun.glass.ui.Application.GetApplication().createRobot(); // Create a new Stage, ignoring the primary stage final Stage stage = new Stage(); // Uncomment the following and the problem goes away problem // stage.setX(100); // stage.setY(100); Group root = new Group(); final Scene scene = new Scene(root, 400, 300); ChangeListener listener = (o, oldVal, newVal) -> printStats(scene); stage.xProperty().addListener(listener); stage.yProperty().addListener(listener); scene.xProperty().addListener(listener); scene.yProperty().addListener(listener); final Label label = new Label("Waiting..."); label.setLayoutX(5); label.setLayoutY(5); final Button button = new Button("Reposition cursor"); button.setLayoutX(5); button.setLayoutY(30); button.setDisable(true); Circle circ = new Circle(CENTER_X, CENTER_Y, 1, Color.RED); root.getChildren().addAll(label, button, circ); stage.setScene(scene); stage.show(); KeyFrame kf = new KeyFrame(Duration.millis(750), e -> { moveCursorToCenter(scene); label.setText("Cursor should now be centered on red circle"); button.setDisable(false); }); final Timeline t = new Timeline(kf); t.play(); button.setOnAction(e -> { button.setDisable(true); label.setText("Waiting..."); t.playFromStart(); }); } public static void main(String[] args) { Application.launch(args); } }