JavaFX - stage.show();以程序冻结结束



我试图写一个类打开一个外部程序,使一个阶段,说"请等待"与进度指示器,等待它完成,然后退出阶段。如果我使用primaryStage.showAndWait();,程序工作,但如果我使用primaryStage.show();,程序冻结,不会继续,直到类关闭。任何帮助都将非常感激。

package application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.io.IOException;

public class Wait {
public static void display(String prog, String progPath){
    Stage primaryStage=new Stage();

    primaryStage.setTitle("Please Wait");
    primaryStage.setMinWidth(350);
    ProgressIndicator indicator = new ProgressIndicator();
    Label label1=new Label();
    label1.setText("Please wait for "+prog+" to finish...");

    HBox layout=new HBox(20);
    layout.getChildren().addAll(indicator, label1);
    layout.setAlignment(Pos.CENTER);
    layout.setPadding(new Insets(20,20,20,20));
    Scene scene =new Scene(layout);
    primaryStage.setScene(scene);
    primaryStage.show();// WHY U NO WORK?!?!?!?!
    try {
        Process p = Runtime.getRuntime().exec(progPath);
        p.waitFor();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    primaryStage.close();
}
}

假设Wait.display()正在FX应用程序线程上执行(这是必需的,因为它创建并显示Stage),您的代码通过调用p.waitFor()来阻塞FX应用程序线程。由于FX应用程序线程被阻塞,它不能做任何常规工作,如渲染UI或响应用户输入。

你需要在后台线程中管理进程。一旦后台进程完成,使用Task将使在FX应用线程上执行代码变得容易:

public static void display(String prog, String progPath){
    Stage primaryStage=new Stage();
    primaryStage.setTitle("Please Wait");
    primaryStage.setMinWidth(350);
    ProgressIndicator indicator = new ProgressIndicator();
    Label label1=new Label();
    label1.setText("Please wait for "+prog+" to finish...");
    HBox layout=new HBox(20);
    layout.getChildren().addAll(indicator, label1);
    layout.setAlignment(Pos.CENTER);
    layout.setPadding(new Insets(20,20,20,20));
    Scene scene =new Scene(layout);
    primaryStage.setScene(scene);
    primaryStage.show();
    Task<Void> task = new Task<Void>() {
        @Override
        public Void call() throws Exception {
            try {
                Process p = Runtime.getRuntime().exec(progPath);
                p.waitFor();        
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
            return null;
    };
    task.setOnSucceeded(e -> primaryStage.close());
    Thread thread = new Thread(task);
    thread.setDaemon(true); // thread will not prevent application from exiting
    thread.start();
}

最新更新