I currently have the following situation:
I have created a JavaFX application, which contains a screen from which I open a dialog (just by clicking a button on the screen). Then, the user gives input and clicks the apply button. The user input is then sent to a method, which opens some sort of progress dialog (for showing the user the status of the synchronization, which is not important for the problem). I will call this dialog 'MyDialog'. MyDialog is built with the following code:
Dialog<Void> dialog = new Dialog<>();
dialog.initOwner(null);
dialog.initStyle(StageStyle.UNDECORATED);
dialog.setHeaderText("Nieuw product synchroniseren...");
dialog.setResizable(false);
//Load dialog FXML file into the Pane
FXMLLoader fxmlloader = new FXMLLoader();
fxmlloader.setLocation(getClass().getResource("dialogs/MyDialogContent.fxml"));
try {
dialog.getDialogPane().setContent(fxmlloader.load());
} catch (IOException e) {
Functions.createExceptionDialog(e);
}
MyDialogContentController childController = fxmlloader.getController();
final ButtonType canceledButtonType = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
dialog.getDialogPane().getButtonTypes().add(canceledButtonType);
This works just fine. The ProgressBar, which is shown in MyDialog, indicated the progress of a task. The task is started from a thread. This thread is started from the controller of the upper screen. From within the task, I would like to show an additional dialog at some point, to get some user validation. I will call this dialog 'AlertDialog'. This is the code for that part (which is placed in the Controller of the upper screen, and not in the Controller of MyDialog):
Task<Object> task = new Task<Object>() {
@Override
protected Object call() {
//Show choice dialog
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.initOwner(null);
alert.initStyle(StageStyle.UNDECORATED);
ButtonType buttonTypeOne = new ButtonType("One");
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");
ButtonType buttonTypeCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree, buttonTypeCancel);
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == buttonTypeOne){
//User chose "One";
} else if (result.get() == buttonTypeTwo) {
// ... user chose "Two"
} else if (result.get() == buttonTypeThree) {
// ... user chose "Three"
} else {
// ... user chose CANCEL or closed the dialog
}
}
}
Unfortunately, the AlertDialog is not showing, and I get the following error:
Exception in thread "Thread-10" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-10
I already tried the following solutions:
- Place the AlertDialog code in the MyDialogController, and then call it from the task.
- Start the thread from MyDialogController, instead of starting in from the upper screen controller. And then call it by 'childController.thread'.
Both of these solutions did not work. I expect it has something to do with loading the FXML file in the DialogPane, and therefore with the thread and from where it is started.
So the questions in this situation are:
Why do I get this error?
Has the error something to do with the AlertDialog not showing?
Should my approach for this part of the code be different? (e.g. without loading an external FXML file in a dialog)
Any help is greatly appreciated!