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

JavaFX-stage.show();以程序冻结告终,java,javafx-8,Java,Javafx 8,我试图编写一个类来打开一个外部程序,制作一个带有进度指示器的“请等待”阶段,等待它完成,然后退出该阶段。如果我使用primaryStage.showAndWait()程序可以运行,但是如果我使用primaryStage.show()程序冻结,在类关闭之前不会继续。任何帮助都将不胜感激 package application; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene;

我试图编写一个类来打开一个外部程序,制作一个带有进度指示器的“请等待”阶段,等待它完成,然后退出该阶段。如果我使用
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();

}
}

假设正在FX应用程序线程上执行
Wait.display()
(这是必需的,因为它创建并显示了一个
阶段
),您的代码通过调用
p.waitFor()
来阻止FX应用程序线程。由于FX应用程序线程被阻塞,它无法执行任何常规工作,例如呈现UI或响应用户输入

您需要在后台线程中管理进程。后台处理完成后,使用将使在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();
}
publicstaticvoid显示(stringprog,stringprogpath){
阶段primaryStage=新阶段();
primaryStage.setTitle(“请稍候”);
初级阶段设置最小宽度(350);
ProgressIndicator=新的ProgressIndicator();
标签标签1=新标签();
标签1.setText(“请等待“+prog+”完成…”);
HBox布局=新HBox(20);
layout.getChildren().addAll(指示器,标签1);
布局。设置对齐(位置中心);
布局。设置填充(新插图(20,20,20,20));
场景=新场景(布局);
初级阶段。场景(场景);
primaryStage.show();
任务=新任务(){
@凌驾
public Void call()引发异常{
试一试{
进程p=Runtime.getRuntime().exec(progPath);
p、 waitFor();
}捕获(IOException | InterruptedException e){
e、 printStackTrace();
}
返回null;
};
task.setonSucceed(e->primaryStage.close());
线程线程=新线程(任务);
setDaemon(true);//线程不会阻止应用程序退出
thread.start();
}

您的JavaFX应用程序的主类是
Wait
吗?@ItachiUchiha不,是AM。Wait只是一个我想多次调用以创建场景的类。效果很好。谢谢!请注意,在catch语句之后您确实需要
返回null;
否则会出错。是的,很抱歉……修复了它。