Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX:根据任务提示用户,并传回结果?_Java_Javafx - Fatal编程技术网

JavaFX:根据任务提示用户,并传回结果?

JavaFX:根据任务提示用户,并传回结果?,java,javafx,Java,Javafx,我有一个简单的JavaFXGUI,可以在点击按钮时触发后台任务。此任务使用最新的进度消息持续更新TextArea。我已经在下面演示了如何解决这个问题。当任务遇到错误时会出现问题,需要用户决定如何继续。我的目标是通过警报做出这个决定,用户选择是或否。不过,我一直无法实现这个功能。以下是我迄今为止所做的尝试: 在JavaFX主线程中创建警报,将其传递给脚本,然后调用showAndWait。这导致了一个错误,表明我不在JavaFX线程中 UpdateMessage()等。将脚本扩展为任务时,我不断遇

我有一个简单的JavaFXGUI,可以在点击按钮时触发后台任务。此任务使用最新的进度消息持续更新TextArea。我已经在下面演示了如何解决这个问题。当任务遇到错误时会出现问题,需要用户决定如何继续。我的目标是通过警报做出这个决定,用户选择是或否。不过,我一直无法实现这个功能。以下是我迄今为止所做的尝试:

  • 在JavaFX主线程中创建警报,将其传递给脚本,然后调用showAndWait。这导致了一个错误,表明我不在JavaFX线程中
  • UpdateMessage()等。将脚本扩展为任务时,我不断遇到NullPointerException
  • 从脚本创建新的JavaFX实例
谢谢你的帮助

使用EventHandler创建按钮:

private Button createButton() {
    Button btn = new Button();
    btn.setText("Run");
    btn.setPrefWidth(100);
    EventHandler<ActionEvent> buildWindow = new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent e) {
            TextArea output = buildCenterTextArea();
            Task task = new Task<Void>() {
                @Override public Void call() {
                    callScript(output); // Calls script
                    return null;
                }
            };
            new Thread(task).start();
        }
    };
    btn.setOnAction(buildWindow);
    return btn;
}

private void buildCenterTextArea() {
    // Builds a text area which the script updates with status
    TextArea output = new TextArea();
    output.setEditable(false);
    this.borderpane.setCenter(output);
    return output
}

后台线程可以一直忙着等待。这意味着您可以创建一个
CompletableFuture
,使用
Platform.runLater
创建一个警报,并使用show和wait显示它,然后用结果填充future。在后台线程上进行此调用之后,使用
Future.get
等待结果

以下示例生成0到9(含)之间的随机数,并将0-8打印到
文本区域<代码>9
是一个模拟错误,会询问用户是否应继续执行任务

@Override
public void start(Stage stage) throws IOException {
    TextArea ta = new TextArea();

    Thread thread = new Thread(() -> {
        Random rand = new Random();
        while (true) {
            int i = rand.nextInt(10);
            if (i == 9) {
                CompletableFuture<ButtonType> future = new CompletableFuture<>();

                // ask for user input
                Platform.runLater(() -> {
                    Alert alert = new Alert(AlertType.CONFIRMATION);
                    alert.setContentText("An error occured. Continue?");
                    future.complete(alert.showAndWait().orElse(ButtonType.CANCEL)); // publish result
                });
                try {
                    if (future.get() == ButtonType.CANCEL) { // wait for user input on background thread
                        break;
                    }
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                    break;
                }
            } else {
                Platform.runLater(() ->ta.appendText(Integer.toString(i) + "\n"));
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    });
    thread.setDaemon(true);
    thread.start();

    Scene scene = new Scene(new VBox(ta));


    stage.setScene(scene);
    stage.show();
}
@覆盖
public void start(Stage)引发IOException{
TextArea ta=新TextArea();
线程=新线程(()->{
Random rand=新的Random();
while(true){
int i=兰特·耐克斯汀(10);
如果(i==9){
CompletableFuture=新的CompletableFuture();
//请求用户输入
Platform.runLater(()->{
警报警报=新警报(警报类型.确认);
alert.setContentText(“发生错误。是否继续?”);
future.complete(alert.showAndWait().orElse(ButtonType.CANCEL));//发布结果
});
试一试{
如果(future.get()==ButtonType.CANCEL){//在后台线程上等待用户输入
打破
}
}捕获(中断异常|执行异常e){
e、 printStackTrace();
打破
}
}否则{
Platform.runLater(()->ta.appendText(Integer.toString(i)+“\n”);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
打破
}
}
}
});
setDaemon(true);
thread.start();
场景=新场景(新VBox(ta));
舞台场景;
stage.show();
}

这里可能会有帮助:后台线程可以一直忙着等待。这意味着您可以创建一个
CompletableFuture
,使用
Platform.runLater
创建一个警报,并使用
show和wait
显示它,然后用结果填充future。在后台线程上进行此调用之后,使用
Future.get
等待结果。。。
@Override
public void start(Stage stage) throws IOException {
    TextArea ta = new TextArea();

    Thread thread = new Thread(() -> {
        Random rand = new Random();
        while (true) {
            int i = rand.nextInt(10);
            if (i == 9) {
                CompletableFuture<ButtonType> future = new CompletableFuture<>();

                // ask for user input
                Platform.runLater(() -> {
                    Alert alert = new Alert(AlertType.CONFIRMATION);
                    alert.setContentText("An error occured. Continue?");
                    future.complete(alert.showAndWait().orElse(ButtonType.CANCEL)); // publish result
                });
                try {
                    if (future.get() == ButtonType.CANCEL) { // wait for user input on background thread
                        break;
                    }
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                    break;
                }
            } else {
                Platform.runLater(() ->ta.appendText(Integer.toString(i) + "\n"));
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    });
    thread.setDaemon(true);
    thread.start();

    Scene scene = new Scene(new VBox(ta));


    stage.setScene(scene);
    stage.show();
}