JavaFX: запрашивать пользователя на основе задания и передавать результат? - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть простой графический интерфейс JavaFX, который запускает фоновую задачу при нажатии кнопки. Эта задача постоянно обновляет 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
}

В моем скрипте я обновляю текст, выполняяследующее:

output.setText(statusText+ "\n" + newStatus);

1 Ответ

1 голос
/ 08 ноября 2019

Фоновый поток может быть занят в ожидании. Это означает, что вы можете создать CompletableFuture, использовать Platform.runLater, чтобы создать предупреждение и отобразить его с помощью showAndWait, а затем заполнить будущее результатами. Сразу после этого вызова в фоновом потоке дождитесь результата, используя Future.get.

. В следующем примере генерируются случайные числа от 0 до 9 (включительно) и выводится 0-8 в TextArea. 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...