**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_20
or greater to work withJDK 8u20
and above as there was a breaking change introduced in that version.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 alib
subfolder).
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.jar
and 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
de
for language andCH
for country. That results incontrolsfx_de_CH.properties
as my file name. - Change the texts inside the properties file.
- Move the new properties file to your project, e.g. into your
src
folder 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 CommandLink
s 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();