public class Dialog<R>
  Comment     Returned-by     Constructor-argument     Method-argument     Field-type     Type-bound     Links  

A Dialog in JavaFX wraps a DialogPane and provides the necessary API to present it to end users. In JavaFX 8u40, this essentially means that the DialogPane is shown to users inside a Stage, but future releases may offer alternative options (such as 'lightweight' or 'internal' dialogs). This API therefore is intentionally ignorant of the underlying implementation, and attempts to present a common API for all possible implementations.

The Dialog class has a single generic type, R, which is used to represent the type of the result property (and also, how to convert from ButtonType to R, through the use of the result converter Callback).

Critical note: It is critical that all developers who choose to create their own dialogs by extending the Dialog class understand the importance of the result converter property. A result converter must always be set, whenever the R type is not Void or ButtonType. If this is not heeded, developers will find that they get ClassCastExceptions in their code, for failure to convert from ButtonType via the result converter.

It is likely that most developers would be better served using either the Alert class (for pre-defined, notification-style alerts), or either of the two pre-built dialogs (TextInputDialog and ChoiceDialog), depending on their needs.

Once a Dialog is instantiated, the next step is to configure it. Almost all properties on Dialog are not related to the content of the Dialog, the only exceptions are contentTextProperty(), headerTextProperty(), and graphicProperty(), and these properties are simply forwarding API onto the respective properties on the DialogPane stored in the dialog pane property. These three properties are forwarded from DialogPane for developer convenience. For developers wanting to configure their dialog, they will in many cases be required to use code along the lines of dialog.getDialogPane().setExpandableContent(node).

After configuring these properties, all that remains is to consider whether the buttons (created using ButtonType and the DialogPane.createButton(ButtonType) method) are fully configured. Developers will quickly find that the amount of configurability offered via the ButtonType class is minimal. This is intentional, but does not mean that developers can not modify the buttons created by the ButtonType that have been specified. To do this, developers simply call the DialogPane.lookupButton(ButtonType) method with the ButtonType (assuming it has already been set in the DialogPane.getButtonTypes() list. The returned Node is typically of type Button, but this depends on if the DialogPane.createButton(ButtonType) method has been overridden. A typical approach is therefore along the following lines:

 ButtonType loginButtonType = new ButtonType("Login", ButtonData.OK_DONE);
 Dialog<String> dialog = new Dialog<>();
 dialog.getDialogPane().getButtonTypes().add(loginButtonType);
 boolean disabled = false; // computed based on content of text fields, for example
 dialog.getDialogPane().lookupButton(loginButtonType).setDisable(disabled);

Once a Dialog is instantiated and fully configured, the next step is to show it. More often than not, dialogs are shown in a modal and blocking fashion. 'Modal' means that the dialog prevents user interaction with the owning application whilst it is showing, and 'blocking' means that code execution stops at the point in which the dialog is shown. This means that you can show a dialog, await the user response, and then continue running the code that directly follows the show call, giving developers the ability to immediately deal with the user input from the dialog (if relevant).

JavaFX dialogs are modal by default (you can change this via the initModality(javafx.stage.Modality) API). To specify whether you want blocking or non-blocking dialogs, developers simply choose to call showAndWait() or show() (respectively). By default most developers should choose to use showAndWait(), given the ease of coding in these situations. Shown below is three code snippets, showing three equally valid ways of showing a dialog:

Option 1: The 'traditional' approach

 Optional<ButtonType> result = dialog.showAndWait();
 if (result.isPresent() && result.get() == ButtonType.OK) {
     formatSystem();
 }

Option 2: The traditional + Optional approach

 dialog.showAndWait().ifPresent(response -> {
     if (response == ButtonType.OK) {
         formatSystem();
     
 });}

Option 3: The fully lambda approach

 dialog.showAndWait()
      .filter(response -> response == ButtonType.OK)
      .ifPresent(response -> formatSystem());

There is no better or worse option of the three listed above, so developers are encouraged to work to their own style preferences. The purpose of showing the above is to help introduce developers to the Optional API, which is new in Java 8 and may be foreign to many developers.

Dialog Validation / Intercepting Button Actions

In some circumstances it is desirable to prevent a dialog from closing until some aspect of the dialog becomes internally consistent (e.g. a form inside the dialog has all fields in a valid state). To do this, users of the dialogs API should become familiar with the DialogPane.lookupButton(ButtonType) method. By passing in a ButtonType (that has already been set in the button types list), users will be returned a Node that is typically of type Button (but this depends on if the DialogPane.createButton(ButtonType) method has been overridden). With this button, users may add an event filter that is called before the button does its usual event handling, and as such users may prevent the event handling by consuming the event. Here's a simplified example:

 final Button btOk = (Button) dlg.getDialogPane().lookupButton(ButtonType.OK);
 btOk.addEventFilter(ActionEvent.ACTION, event -> {
     if (!validateAndStore()) {
         event.consume();
     
 });}

Dialog Closing Rules

It is important to understand what happens when a Dialog is closed, and also how a Dialog can be closed, especially in abnormal closing situations (such as when the 'X' button is clicked in a dialogs title bar, or when operating system specific keyboard shortcuts (such as alt-F4 on Windows) are entered). Fortunately, the outcome is well-defined in these situations, and can be best summarised in the following bullet points:

implements EventTarget

Parameters:
<R>    The return type of the dialog, via the result property.

See also:
Alert, TextInputDialog, ChoiceDialog

Since:  JavaFX 8u40