2013-11-14 74 views
3

我知道这通常不是必需的,但对于我的测试框架,我需要能够替换舞台使用的场景(这是必要的,因为我不想为每个测试分叉一个新的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

+0

隐藏,再次显示窗口,解决了问题,但是我想避免使用一个非常暴力的解决方案。 – Renato

+0

我认为这是特定于您的操作系统。我使用Java7u45和Java8b115在Windows 7上运行了您的应用程序,并且所有报告的点值都具有相同的x和y坐标。 – jewelsea

+0

谢谢。我也证实这并不影响Windows。 – Renato

回答

2

这是JavaFX的用于Linux的know bug。它在尚未发布的JavaFX 2更新中得到修复(请参阅链接中的修订版本字段)。

除了您提到的解决方法之外,替代解决方案可能是替换场景的根节点。我知道这适用于这个目的(至少在Windows上)。

+0

谢谢。我之前正在替换根目录,但我需要替换整个场景才能重新启动一个或多个创建自己场景的应用程序,因此,替换根目录并不是一个完整的解决方案。 – Renato

+0

由minisu引用的RT-19352错误在18个月前被修复,我认为它现在已经被包含在一个已发布的JavaFX版本中,但也许minisu是正确的,它还没有被包含进来(我对这个问题留了言论在问题追踪器要求澄清,你可以[检查问题的答复](https://javafx-jira.kenai.com/browse/RT-19352)以获得明确的答案)。无论如何,我不确定Renato是否遇到完全相同的问题,因此Renato可能仍然值得在错误跟踪器中提交一个新问题。 – jewelsea

+0

感谢您的建议。我再次检查了Windows 7中没有发生这个问题。我同意你的看法,我的问题似乎与RT-19352不一样。场景更新正确,只是其位置报告不正确。我会提交一个错误。 – Renato