JavaFX - новый этап в задаче - PullRequest
0 голосов
/ 07 июня 2018

Я хочу открыть новое окно из задачи, но по какой-то причине после строки Stage stage = new Stage код перестает выполняться, но ошибки нет.

Task<Void> task = new Task<Void>() {

        @Override protected Void call() throws Exception {

            Parent root = FXMLLoader.load(getClass().getResource("sample2.fxml"));
            Stage stage = new Stage();
            System.out.println("Print");
            stage.setTitle("My New Stage Title");
            stage.setScene(new Scene(root, 100, 100));
            stage.show();
            return null;
        }
    };

Он никогда не печатает сообщение «Печать.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Ответ на вопрос

Причиной сбоя Task является то, что вы создаете Stage в потоке, отличном от потока приложения JavaFX.В Javadoc Stage говорится:

Объекты Stage должны создаваться и изменяться в потоке приложений JavaFX.

Это означает, что при попытке создать Stageв фоновом потоке, в котором запущен Task, будет IllegalStateException с сообщением о том, что вы не в потоке приложений JavaFX.Чтобы решить эту проблему, оберните весь код, который создает и / или изменяет Stage в вызове Platform.runLater(Runnable).

Примечание: Вероятно, было бы лучше не создавать Stage в Task вообще.Скорее, в вашем случае просто верните результат FXMLLoader.load(URL) и создайте Stage при обработке успеха Task.

Task<Parent> task = new Task<Parent>() {
    @Override
    protected Parent call() throws Exception {
        return FXMLLoader.load(getClass().getResource("sample2.fxml"));
    }
};

task.setOnSucceeded(event -> {
    Parent root = task.getValue();
    Stage stage = new Stage();
    stage.setScene(new Scene(root));
    stage.show();
};

Почему не отображается ошибка?

Вы говорите, что ошибки нет, но вы также не показываете код, который бы отображал ошибку, если она возникнет.При сбое Task он устанавливает причину сбоя в свойстве exception.Чтобы обработать случай сбоя Task, вы можете:

  • Прослушать свойство exception
  • Добавить EventHandler для обработки события WorkerStateEvent.WORKER_STATE_FAILED и запроситьexception свойство
    • Либо с использованием task.setOnFailed(EventHandler) или task.addEventXXX(EventType, EventHandler), где XXX равно либо Filter, либо Handler
  • Переопределить метод protected void failed()в вашей реализации Task и запросите свойство exception
    • Метод failed() всегда будет вызываться в потоке приложений JavaFX
  • Поймать и обработать исключениев методе call() перед повторным сбросом
  • Возможно, другие способы, о которых я сейчас не думаю
0 голосов

Вам нужен Исполнитель, чтобы начать цепочку

Executor exec = Executors.newCachedThreadPool(runnable -> {
    Thread t = new Thread(runnable);
    t.setDaemon(true);
    return t;
});

exec.execute(task);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...