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

我有一个简单的JavaFX GUI,它在单击按钮时触发后台任务。此任务使用其最新进度消息连续更新TextArea。我已经在下面演示了如何解决此问题。当任务遇到错误时会出现问题,并且需要用户决定如何进行。我的目标是通过用户选择“是”或“否”的警报来做出此决定。不过,我一直无法实现此功能。到目前为止,这是我尝试过的事情:

  • 在JavaFX主线程中创建一个Alert,将其传递给脚本,然后调用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
}

在我的脚本中,我通过执行以下操作来更新文本:

output.setText(statusText+ "\n" + newStatus);
wenjin666666 回答:JavaFX:根据Task提示用户,并传回结果?

后台线程可以保持繁忙等待状态。这意味着您可以创建一个CompletableFuture,使用Platform.runLater创建一个警报,并使用showAndWait显示它,然后用结果填充未来。在后台线程上进行此调用之后,立即使用Future.get等待结果。

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

@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();
}
本文链接:https://www.f2er.com/3141378.html

大家都在问