**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
-
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 version8.0.6_20or greater to work withJDK 8u20and above as there was a breaking change introduced in that version. -
Inside the zip file you should find a
controlsfx-8.x.x.jarfile. Add the jar file to your JavaFX 8 project (usually inside alibsubfolder).
Note: ControlsFX will only work on JavaFX 8.0 or later. Make sure you are using JDK 8 or later in your project. -
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.
-
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:
- Open the
controlsfx-8.x.x.jarand make a copy of the filecontrolsfx.properties. This file contains the default English translation. - Add your desired locale to the filname of the copied properties file. For example, my locale is
defor language andCHfor country. That results incontrolsfx_de_CH.propertiesas my file name. - Change the texts inside the properties file.
- Move the new properties file to your project, e.g. into your
srcfolder or somewhere else on the classpath. - 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

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

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

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

Dialogs.create()
.owner(stage)
.title("Error Dialog")
.masthead("Look, an Error Dialog")
.message("Ooops, there was an error!")
.showError();
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

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

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

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

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
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

Optional<Font> response = Dialogs.create()
.owner(stage)
.masthead("Choose what you like")
.showFontSelector(Font.font("Times New Roman"));
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:

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();