我正在尝试编写一个类来打开一个外部程序,用一个进度指示器创建一个“请等待”的阶段,等待它完成,然后退出该阶段。如果我使用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();
}
}
答案 0 :(得分:2)
假设正在FX应用程序线程上执行Wait.display()
(这是必需的,因为它创建并显示Stage
),您的代码会通过调用p.waitFor()
来阻止FX应用程序线程。由于FX应用程序线程被阻止,它无法执行任何常规工作,例如呈现UI或响应用户输入。
您需要在后台线程中管理进程。使用Task
可以在后台进程完成后轻松在FX Application Thread上执行代码:
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();
}