Reputation: 39
I am building javaFX user-interface with user interaction between the windows and I'm running into an issue I can't find solution anywhere...
So basically I want to open a dialog with inputs that can be filled by user, once done the app launch a background task with these informations, and an other dialog show up while the task is running (a loading screen). BUT ! Error can occurs during the task and exceptions can be catched, if it appens I want to display the exception message in another dialog for the user.
So, in a first place I have my dialog with input(s) :
// 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();
And then if the result is triggered I create a task :
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();
});
Everything is working great, the ProgressDialog shows until the task is finished no matter if it fails or succeed. I can display in console that the exception has been catched, but the dialog created in the catch never shows.
I tried different things like :
task.setOnFailed(e -> {
system.out.println(task.getException().getMessage()); // Nothing
});
I also tried to add state or exception inside the task itself ...
} catch (Exception e) {
system.out.println("Exception caught in task !");
failed();
setException(e);
}
But I nothing seems to happend... I even get a SUCCEEDED state with the exception beeing catched and a nullPointerException for searching task.getException() (Calling thos two lines outside the task in the result.ifPresent{...)!
I'm pretty noob in multithreading... Did I miss something ? Any help will be very appreciated, thank you :)
Upvotes: 0
Views: 2710
Reputation: 82461
The code works fine assuming you're opening the dialog properly:
} catch (Exception e) {
System.out.println("Exception caught in task!");
Platform.runLater(() -> {
Alert dialog = new Alert(AlertType.ERROR, "Error", ButtonType.OK);
dialog.show();
});
}
The standard approach for exceptions that triggers the onFailed
handler though is exiting the call
method with an exception:
} catch (Exception e) {
System.out.println("Exception caught in task!");
throw e;
}
Instead of rethrowing the exception you could simply remove the try-catch, but this no longer allows you to print the message to the console inside the task.
task.setOnFailed(evt -> {
System.out.println(task.getException().getMessage());
Alert dialog = new Alert(AlertType.ERROR, "Error", ButtonType.OK);
dialog.show();
});
Upvotes: 1