Как отобразить сообщение об ошибке в диалоге с перехваченным исключением в фоновой задаче javaFX? - PullRequest
0 голосов
/ 03 декабря 2018

Я создаю пользовательский интерфейс javaFX с пользовательским взаимодействием между окнами, и я сталкиваюсь с проблемой, которую нигде не могу найти решения ...

Так что в основном я хочу открыть диалог с вводамикоторый может быть заполнен пользователем, после того как приложение запустит фоновую задачу с этой информацией, и во время выполнения задачи появится другое диалоговое окно (экран загрузки).НО !Во время выполнения задачи может произойти ошибка, и исключения могут быть перехвачены, если оно появляется, я хочу отобразить сообщение об исключении в другом диалоговом окне для пользователя.

Итак, во-первых, у меня есть диалог с входными данными:

// Init dialog
Dialog<String> inputDialog = new Dialog<>();
inputDialog.setTitle("Meshes generation parameters");
// Add validation buttons
inputDialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, 
ButtonType.CANCEL);
// Creating content
GridPane gridPane = new GridPane();
TextField width = new TextField("15000");
gridPane.add(new Label("Width (meters)"), 0, 0);
gridPane.add(width, 1, 0);
// Filling dialog
inputDialog.getDialogPane().setContent(gridPane);

// Returning result with OK button
inputDialog.setResultConverter(dialogButton -> {
        if (dialogButton == ButtonType.OK) {
            return width.getText();
        }
        return null;
    });

// Opens dialog until user close it or validate it.
Optional<String> result = inputDialog.showAndWait();

И затем, если результат срабатывает, я создаю задачу:

result.ifPresent(width -> {
// Creates task that will run in background
Task task= new Task() {
    @Override
    protected Object call() throws Exception {
        try {
            // Do things with 'width'
        } catch (Exception e) {
            system.out.println("Exception catched in task !");
            // Tried to open dialog from here but it never shows
        }
        return null;
    }
}; // End of task

// Open 'loading screen' dialog until task ends
ProgressDialog dialog = new ProgressDialog(meshesGeneration);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.setTitle("Please wait.");
dialog.setHeaderText("This may take some time, please wait.");
dialog.initStyle(StageStyle.UTILITY);
// Runs the task
new Thread(task).start();
dialog.showAndWait();

});

Все работает отлично, ProgressDialog показывает, пока задача не будет завершена, независимо от того, провалилась она или успешно выполнена.Я могу отобразить в консоли, что исключение было перехвачено, но диалог, созданный в перехватчике, никогда не отображается.

Я пробовал разные вещи, такие как:

task.setOnFailed(e -> {
    system.out.println(task.getException().getMessage()); // Nothing
});

Я также пытался добавить состояние или исключение внутри самой задачи ...

} catch (Exception e) {
    system.out.println("Exception caught in task !");
    failed();
    setException(e);
}

Но мне ничего не кажетсяслучилось ... Я даже получаю состояние SUCCEEDED с исключением beeing и nullPointerException для поиска task.getException () (вызов этих двух строк вне задачи в result.ifPresent {...)!

Я довольно нуб в многопоточности ... Я что-то пропустил?Любая помощь будет очень признателен, спасибо:)

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Код работает нормально, если вы правильно открываете диалоговое окно:

} catch (Exception e) {
    System.out.println("Exception caught in task!");
    Platform.runLater(() -> {
        Alert dialog = new Alert(AlertType.ERROR, "Error", ButtonType.OK);
        dialog.show();
    });
}

Стандартный подход для исключений, который запускает обработчик onFailed, хотя и выходит из метода call сисключение:

} catch (Exception e) {
    System.out.println("Exception caught in task!");
    throw e;
}

Вместо повторного выброса исключения вы можете просто удалить try-catch, но это больше не позволяет печатать сообщение на консоли внутри задачи.

task.setOnFailed(evt -> {
    System.out.println(task.getException().getMessage());
    Alert dialog = new Alert(AlertType.ERROR, "Error", ButtonType.OK);
    dialog.show();
});
0 голосов
/ 03 декабря 2018

Попробуйте отобразить его внутри Platform.runLater

...