我知道这通常不是必需的,但对于我的测试框架,我需要能够替换舞台使用的场景(这是必要的,因为我不想为每个测试分叉一个新的JVM,显然,我们无法重新启动JavaFX应用程序,至少在JavaFX 2中不能)。如何在舞台中更换场景后获取正确的场景位置?
但是,这打破了我的测试,因为这样做后,场景开始报告一个不正确的位置(所以我无法找到我的节点绝对位置在屏幕上)。
下面是重现问题的完整代码。我相信这是JavaFX的一个错误,但我想知道是否有人能先看到任何问题,或者帮我解决方法:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.concurrent.CountDownLatch;
public class BugWithScene {
static CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
Application.launch(MyApp.class);
}
}).start();
latch.await();
// sleep a little so we can see the Scene changing
Thread.sleep(500);
Platform.runLater(new Runnable() {
@Override
public void run() {
printSceneLocation();
// here we replace the Scene - and now the Scene location becomes 0,0
MyApp.stage.setScene(createColorfulScene(Color.BLUE));
printSceneLocation();
}
});
}
public static void printSceneLocation() {
System.out.println(new Point2D(MyApp.stage.getScene().getX(), MyApp.stage.getScene().getY()));
}
public static Scene createColorfulScene(Color color) {
VBox root = new VBox();
root.setSpacing(0);
root.getChildren().setAll(new Rectangle(40, 50, color));
return new Scene(root, 50, 60);
}
public static class MyApp extends Application {
static Stage stage;
@Override
public void start(Stage stage) throws Exception {
stage.setScene(createColorfulScene(Color.RED));
stage.show();
MyApp.stage = stage;
latch.countDown();
}
}
}
运行这段代码打印如下:
Point2D [x = 3.0, y = 24.0]
Point2D [x = 0.0, y = 0.0]
我预计第二点应该与第一点相同。第一个是正确的(将鼠标移动到窗口的绝对坐标,这个坐标移到了这个数量上,你会到达预期的地方),第二个是错误的。
这可能是Linux特有的,不知道......试过Linux Mint的15,与Java 1.7.0_45-B18
隐藏,再次显示窗口,解决了问题,但是我想避免使用一个非常暴力的解决方案。 – Renato
我认为这是特定于您的操作系统。我使用Java7u45和Java8b115在Windows 7上运行了您的应用程序,并且所有报告的点值都具有相同的x和y坐标。 – jewelsea
谢谢。我也证实这并不影响Windows。 – Renato