bhavesh bhavesh - 21 days ago 9
Java Question

Creating a JavaFX dialog inside a JavaFX task

I am trying to create a javafx input dialogue box, I am putting it inside a task but my code is not creating any dialogue box.

Task<Void> passwordBox = new Task<Void>() {
@Override
protected Void call() throws Exception {
TextInputDialog dialog = new TextInputDialog("walter");
dialog.setTitle("Text Input Dialog");
dialog.setHeaderText("Look, a Text Input Dialog");
dialog.setContentText("Please enter your name:");

// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
if (result.isPresent()){
System.out.println("Your name: " + result.get());
}

// The Java 8 way to get the response value (with lambda expression).
result.ifPresent(name -> System.out.println("Your name: " + name));
return null;
}
};
Thread pt = new Thread(passwordBox);
pt.start();


on debugging, it is going inside the following catch method of Task class

catch (final Throwable th) {
// Be sure to set the state after setting the cause of failure
// so that developers handling the state change events have a
// throwable to inspect when they get the FAILED state. Note
// that the other way around is not important -- when a developer
// observes the causeOfFailure is set to a non-null value, even
// though the state has not yet been updated, he can infer that
// it will be FAILED because it can be nothing other than FAILED
// in that circumstance.
task.runLater(() -> {
task._setException(th);
task.setState(State.FAILED);
});
// Some error occurred during the call (it might be
// an exception (either runtime or checked), or it might
// be an error. In any case, we capture the throwable,
// record it as the causeOfFailure, and then rethrow. However
// since the Callable interface requires that we throw an
// Exception (not Throwable), we have to wrap the exception
// if it is not already one.
if (th instanceof Exception) {
throw (Exception) th;
} else {
throw new Exception(th);
}


If I am not putting the dialogue box inside the task it is causing application to hang.

Answer Source

You have to ensure that the dialog is opened on the JavaFX Application Thread, as every GUI update must happen on this thread in JavaFX.

You can achieve it like:

Task<Void> passwordBox = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                Platform.runLater(new Runnable() {

                    @Override
                    public void run() {
                        TextInputDialog dialog = new TextInputDialog("walter");
                        dialog.setTitle("Text Input Dialog");
                        dialog.setHeaderText("Look, a Text Input Dialog");
                        dialog.setContentText("Please enter your name:");

                        // Traditional way to get the response value.
                        Optional<String> result = dialog.showAndWait();
                        if (result.isPresent()){
                            System.out.println("Your name: " + result.get());
                        }

                        // The Java 8 way to get the response value (with lambda expression).
                        result.ifPresent(name -> System.out.println("Your name: " + name));

                    }
                });

                return null;
            }
        };