**Deprecated!** Please read the → Article about the official JavaFX Dialogs!

With JDK version 8u40, the Dialogs were finally included in the official JavaFX. This means that the ControlsFX Dialogs described in this post will be deprecated!

In 2012 I back-ported an early example of a JavaFX 8 Dialog to JavaFX 2. You can read about it in the blog post JavaFX 2 Dialogs. I did hope that the Dialogs would be included in JavaFX 8, but they were not — at least not until JavaFX 8u40.

This blog post describes how to use the ControlsFX Dialogs. As said above, the ControlsFX Dialogs will be deprecated and included in the new JDK 8u40. So you should really be reading this article about the official Dialogs instead.

How To Use ControlsFX Dialogs

  1. Download the latest ControlsFX zip file from the ControlsFX Website. (It is also available as Maven dependency if you prefer to use Maven.)
    Important: The ControlsFX must be version 8.0.6_20 or greater to work with JDK 8u20 and above as there was a breaking change introduced in that version.

  2. Inside the zip file you should find a controlsfx-8.x.x.jar file. Add the jar file to your JavaFX 8 project (usually inside a lib subfolder).
    Note: ControlsFX will only work on JavaFX 8.0 or later. Make sure you are using JDK 8 or later in your project.

  3. Add the jar file to your project’s classpath: In Eclipse right-click on the jar file | Build Path | Add to Build Path. Now Eclipse knows about the library.

  4. Now ControlsFX is ready to be used. Add one of the following code snippets to create a Dialog.

Localizing the Dialogs

If you want to change the text of the buttons, you must add a localized properties file:

  1. Open the controlsfx-8.x.x.jar and make a copy of the file controlsfx.properties. This file contains the default English translation.
  2. Add your desired locale to the filname of the copied properties file. For example, my locale is de for language and CH for country. That results in controlsfx_de_CH.properties as my file name.
  3. Change the texts inside the properties file.
  4. Move the new properties file to your project, e.g. into your src folder or somewhere else on the classpath.
  5. It should already work for your system’s locale. If you want to change to a different locale, you can set the locale by calling Localization.setLocale(new Locale("de", "CH")).

Standard Dialogs

Information Dialog

JavaFX Information Dialog

Dialogs.create()
        .owner(stage)
        .title("Information Dialog")
        .masthead("Look, an Information Dialog")
        .message("I have a great message for you!")
        .showInformation();

Without Masthead

JavaFX Information Dialog without Masterhead

Dialogs.create()
        .owner(stage)
        .title("Information Dialog")
        .masthead(null)
        .message("I have a great message for you!")
        .showInformation();

Warning Dialog

JavaFX Warning Dialog

Dialogs.create()
        .owner(stage)
        .title("Warning Dialog")
        .masthead("Look, a Warning Dialog")
        .message("Careful with the next step!")
        .showWarning();

Error Dialog

JavaFX Error Dialog

Dialogs.create()
        .owner(stage)
        .title("Error Dialog")
        .masthead("Look, an Error Dialog")
        .message("Ooops, there was an error!")
        .showError();

Exception Dialog

JavaFX Exception Dialog

Dialogs.create()
        .owner(stage)
        .title("Exception Dialog")
        .masthead("Look, an Exception Dialog")
        .message("Ooops, there was an exception!")
        .showException(new FileNotFoundException("Could not find file blabla.txt"));

Confirm Dialog

JavaFX Confirm Dialog

Action response = Dialogs.create()
        .owner(stage)
        .title("Confirm Dialog")
        .masthead("Look, a Confirm Dialog")
        .message("Do you want to continue?")
        .showConfirm();

if (response == Dialog.Actions.YES) {
    // ... user chose YES
} else {
    // ... user chose NO, CANCEL, or closed the dialog
}

The response will either be Dialog.Actions.NO, Dialog.Actions.YES, or Dialog.Actions.CANCEL.

Confirm Dialog with Custom Actions

JavaFX Confirm Dialog with Custom Actions

If actions are provided, they completely replace the standard actions.

Action response = Dialogs.create()
        .owner(stage)
        .title("Confirm Dialog with Custom Actions")
        .masthead("Look, a Confirm Dialog with Custom Actions")
        .message("Are you ok with this?")
        .actions(Dialog.Actions.OK, Dialog.Actions.CANCEL)
        .showConfirm();

if (response == Dialog.Actions.OK) {
    // ... user chose OK
} else {
    // ... user chose CANCEL, or closed the dialog
}

Text Input Dialog

JavaFX Choice Input Dialog

Optional<String> response = Dialogs.create()
        .owner(stage)
        .title("Text Input Dialog")
        .masthead("Look, a Text Input Dialog")
        .message("Please enter your name:")
        .showTextInput("walter");

// One way to get the response value.
if (response.isPresent()) {
    System.out.println("Your name: " + response.get());
}

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

Choice Input Dialog

JavaFX Choice Input Dialog

List<String> choices = new ArrayList<>();
choices.add("a");
choices.add("b");
choices.add("c");

Optional<String> response = Dialogs.create()
        .owner(stage)
        .title("Choice Input Dialog")
        .masthead("Look, a Choice Input Dialog")
        .message("Choose your letter:")
        .showChoices(choices);

// One way to get the response value.
if (response.isPresent()) {
    System.out.println("The user chose: " + response.get());
}

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

Note: The response.isPresent() will return false if the user didn’t choose anything or cancelled the dialog.

Special Purpose Dialogs

JavaFX Command Link Dialog

List<CommandLink> links = new ArrayList<>();
links.add(new CommandLink("Go to the Zoo",
        "Here you will see zebras, monkeys, lions, elephants, and maybe also an alligator."));
links.add(new CommandLink("Go to the Circus",
        "Watch acrobats fly around and clowns, of course."));
links.add(new CommandLink("Stay Home",
        "Watch TV or play some board games with your siblings."));

Action response = Dialogs.create()
        .owner(stage)
        .title("Command Link Dialog")
        .masthead(null)
        .message("Where do you want to go?")
        .showCommandLinks(links.get(2), links);

System.out.println(response);

The response will either be one of the CommandLinks or Dialog.Actions.CANCEL.

Font Selector Dialog

JavaFX Font Selector Dialog

Optional<Font> response = Dialogs.create()
        .owner(stage)
        .masthead("Choose what you like")
        .showFontSelector(Font.font("Times New Roman"));

Progress Dialog

JavaFX Progress Dialog

Service<Void> service = new Service<Void>() {
    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            @Override
            protected Void call()
                    throws InterruptedException {
                updateMessage("Finding friends . . .");
                updateProgress(0, 10);
                for (int i = 0; i < 10; i++) {
                    Thread.sleep(300);
                    updateProgress(i + 1, 10);
                    updateMessage("Found " + (i + 1) + " friends!");
                }
                updateMessage("Found all.");
                return null;
            }
        };
    }
};

Dialogs.create()
        .owner(stage)
        .title("Progress Dialog")
        .masthead("Searching for friends")
        .showWorkerProgress(service);

service.start();

Custom Dialogs

Using the lower-level API of ControlsFX you can create custom dialogs.

Here is an example of how to create a login form:

JavaFX Custom Login Dialog

final TextField username = new TextField();
final PasswordField password = new PasswordField();
final Action actionLogin = new AbstractAction("Login") {
    // This method is called when the login button is clicked ...
    public void handle(ActionEvent ae) {
        Dialog d = (Dialog) ae.getSource();
        // Do the login here.
        d.hide();
    }
};

@Override
public void start(Stage stage) {
    // Create the custom dialog.
    Dialog dlg = new Dialog(stage, "Login Dialog");

    GridPane grid = new GridPane();
    grid.setHgap(10);
    grid.setVgap(10);
    grid.setPadding(new Insets(0, 10, 0, 10));

    username.setPromptText("Username");
    password.setPromptText("Password");

    grid.add(new Label("Username:"), 0, 0);
    grid.add(username, 1, 0);
    grid.add(new Label("Password:"), 0, 1);
    grid.add(password, 1, 1);

    ButtonBar.setType(actionLogin, ButtonType.OK_DONE);
    actionLogin.disabledProperty().set(true);

    // Do some validation (using the Java 8 lambda syntax).
    username.textProperty().addListener((observable, oldValue, newValue) -> {
        actionLogin.disabledProperty().set(newValue.trim().isEmpty());
    });

    dlg.setMasthead("Look, a Custom Login Dialog");
    dlg.setContent(grid);
    dlg.getActions().addAll(actionLogin, Dialog.Actions.CANCEL);

    // Request focus on the username field by default.
    Platform.runLater(() -> username.requestFocus());

    dlg.show();