在舞台中替换场景后如何获取正确的场景位置?

3
我知道这通常是不必要的,但对于我的测试框架,我需要能够替换由Stage使用的Scene(这是必需的,因为我不想为每个单独的测试分支出一个新的JVM,显然我们不能在JavaFX 2中重新启动JavaFX应用程序)。
然而,这会导致我的测试失败,因为在这样做之后,Scene会报告一个错误的位置(所以我无法找到我的节点在屏幕上的绝对位置)。
以下是完整的代码来再现这个问题。我相信这是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
我认为这与您的操作系统有关。我在Windows 7上使用Java7u45和Java8b115运行了您的应用程序,所有报告的点值都具有相同的x和y坐标。 - jewelsea
谢谢。我也确认这不会影响Windows。 - Renato
1个回答

2

这是JavaFX在Linux下的一个已知bug,它已经在尚未发布的JavaFX 2更新版本中修复(请查看链接中的“修复版本”字段)。

除了你提到的解决方法之外,另一个可行的解决方案是替换场景的根节点。我知道这对于这个目的可以起作用(至少在Windows上是如此)。


谢谢。之前我是替换根节点,但现在我需要替换整个场景以便重新启动一个或多个应用程序,这些应用程序会创建自己的场景,因此替换根节点并不是完整的解决方案。 - Renato
minisu提到的RT-19352错误已经在18个月前修复了,我认为它现在应该已经包含在发布的JavaFX版本中了,但也许minisu是正确的,它还没有被包含(我在问题跟踪器中留下了一条评论请求澄清,您可以查看问题以获取答案)。无论如何,我不确定Renato是否遇到了完全相同的问题,因此对于Renato来说,提交一个新的问题仍然是值得的。 - jewelsea
谢谢您的建议。我已经仔细检查了,这个问题在Windows 7中并没有发生。我同意您的看法,我的问题似乎与RT-19352不同。场景被正确更新,只是位置报告不正确。我会提交一个错误报告。 - Renato
在JavaFX的JIRA中创建了一个新问题:RT-34307,https://javafx-jira.kenai.com/browse/RT-34307 - Renato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接