在继续JavaFX之前更新UI并强行等待

时间:2016-02-12 18:19:39

标签: java multithreading javafx

我在这里展示了我欢迎场景的图像。

image

创建新项目按钮的当前行为如下所示:

Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
stage.hide();
Parent root = FXMLLoader.load(getClass().getResource("/view/scene/configure/NewProjectConfigureScene.fxml"));
Scene scene = new Scene(root);
stage.setTitle("Configure New Project Settings");
stage.setScene(scene);
stage.show();

用文字解释:按下按钮 - >我得到了舞台 - >隐藏当前场景 - >切换舞台以获得新场景 - >重新展示舞台。这种行为正在发挥作用。

我是GUI编程的新手,所以请在解释我需要的内容时请耐心等待。

我现在正在尝试添加一个小功能,当按下创建新项目按钮时,当前场景中会出现加载消息,我强制GUI等待几秒钟(所以在继续进入下一个场景之前,用户有时间看到这个“加载”消息。加载消息看起来像这样。

image

我真的想要实现此功能,因为加载消息后跟一个等待可能更直观,从而改善了我在使用该程序时的用户体验。

我最初的尝试是做以下事情:

statusText.setText("Please wait..."); // statusText is the "loading message"
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
try {
    Thread.sleep(2000);                
} catch(InterruptedException ex) {
    Thread.currentThread().interrupt();
}
stage.hide();

Parent root = FXMLLoader.load(getClass().getResource("/view/scene/configure/NewProjectConfigureScene.fxml"));
Scene scene = new Scene(root);
stage.setTitle("Configure New Project Settings");
stage.setScene(scene);
stage.show();

我刚刚阅读here,你永远无法睡眠UI线程,因为它会冻结整个应用程序。所以我一直在尝试上面链接的第一个答案中提到的方法,即使用javafx.concurrent.Task,但是我已经尝试了很长时间无济于事。

如何更新用户界面,强行等待几秒钟,然后显示新场景?

2 个答案:

答案 0 :(得分:10)

Instead of sleeping the thread, use a PauseTransition and load your new scene after the pause has finished.

createNewProject.setOnAction(event -> {
    statusText.setText("Please wait...");
    PauseTransition pause = new PauseTransition(
        Duration.seconds(1),
    );
    pause.setOnFinished(event -> {
        Parent root = FXMLLoader.load(
            getClass().getResource(
                "/view/scene/configure/NewProjectConfigureScene.fxml"
            )
        );
        Scene scene = new Scene(root);
        stage.setTitle("Configure New Project Settings");
        stage.setScene(scene);
        stage.sizeToScene();    
    });
    pause.play();
});

The above code assumes you have just a single stage, so you resize your "Welcome" stage to become the "Configure New Project Settings" stage.

答案 1 :(得分:0)

您应该尝试添加ControlsFX,这会有所帮助。

您可以执行以下操作:

   Service<T> service = new Service<T>(){
       @Override
       protected Task<T> createTask() {
       return new Task<T>() {
          @Override
          protected T call() throws Exception {
        //Do your processing here.                      }
          };
      }
    };
    service.setOnSucceeded(event -> {//do your processing});
    service.setOnFailed(event -> {//do your processing});              
    ProgressDialog pd = new ProgressDialog(service);
    pd.setContentText("Please wait while the window loads...");
    pd.initModality(Modality.WINDOW_MODAL);
    pd.initOwner(stage);
    service.start();

这会将您的代码放在后台线程上。 ControlsFX对话框随服务启动和停止。