A DESCRIPTION OF THE REQUEST :
The Dialog class is hard-coded to do the following:
A Dialog can be closed if and only if the DialogPane contains a ButtonType with ButtonData equal to CANCEL_CLOSE, or if the ButtonType is a cancel button. This is found in the 'requestPermissionToClose' method of the HeavyweightDialog class.
When a user hits library the Escape button on their keyboard, the Dialog is immediately closed, assuming the above holds true. Also, the close action of the Dialog in this case is equivalent to having selected the relevant button.
JUSTIFICATION :
The ControlsFX library makes use of the Dialog class to generate a reusable Wizard. This works great, except for the fact that when a user accidentally taps the Escape button, the wizard closes without any recourse. For a normal dialog box that exists only to provide feedback to the user, or to request permission to do something, the current behavior makes sense.
I've attempted to work around this problem by attaching an event handler to the Dialog instance (via setOnCloseRequest()) to display another Dialog to confirm that the user actually wishes to dismiss the wizard, but this presented itself with other problems:
Hitting the Escape key very quickly dismissed the new Dialog that appeared, making it effectively useless.
Selecting the OS-specific close button on the window triggered the confirmation dialog, however the Dialog would close regardless of any attempt to consume the event.
Selecting the Finish button at the end of the wizard also triggers the confirmation dialog box.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like to see something similar to the following:
Allow a programmer to specify some way of defining a custom 'requestPermissionToClose' function, possibly via some form of functional Interface. This would allow me to programatically decide if it makes sense to prevent a user from closing the dialog box. This would need to be configurable for each DialogPane in the Dialog (one per page in the Wizard)
Allow a programmer to optionally disable the default behavior of allowing a Dialog instance to be closed via the Escape key, and/or to allow the programmer the ability to interject and confirm that the user actually wishes to do so.
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogEvent;
import javafx.stage.Stage;
public class DialogDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.getDialogPane().setContentText("This is a Wizard");
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.NEXT, ButtonType.PREVIOUS, ButtonType.CANCEL);
dialog.setOnCloseRequest(this::confirmClose);
dialog.showAndWait();
}
private void confirmClose(DialogEvent dialogEvent) {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.setContentText("Are you sure you wish to close the Wizard?");
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
dialog.showAndWait().ifPresent(buttonType -> {
if (buttonType != ButtonType.YES) {
dialogEvent.consume();
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not been able to come up with a suitable workaround, short of re-writing a complete implementation of the Dialog class with the above recommendations.
The Dialog class is hard-coded to do the following:
A Dialog can be closed if and only if the DialogPane contains a ButtonType with ButtonData equal to CANCEL_CLOSE, or if the ButtonType is a cancel button. This is found in the 'requestPermissionToClose' method of the HeavyweightDialog class.
When a user hits library the Escape button on their keyboard, the Dialog is immediately closed, assuming the above holds true. Also, the close action of the Dialog in this case is equivalent to having selected the relevant button.
JUSTIFICATION :
The ControlsFX library makes use of the Dialog class to generate a reusable Wizard. This works great, except for the fact that when a user accidentally taps the Escape button, the wizard closes without any recourse. For a normal dialog box that exists only to provide feedback to the user, or to request permission to do something, the current behavior makes sense.
I've attempted to work around this problem by attaching an event handler to the Dialog instance (via setOnCloseRequest()) to display another Dialog to confirm that the user actually wishes to dismiss the wizard, but this presented itself with other problems:
Hitting the Escape key very quickly dismissed the new Dialog that appeared, making it effectively useless.
Selecting the OS-specific close button on the window triggered the confirmation dialog, however the Dialog would close regardless of any attempt to consume the event.
Selecting the Finish button at the end of the wizard also triggers the confirmation dialog box.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like to see something similar to the following:
Allow a programmer to specify some way of defining a custom 'requestPermissionToClose' function, possibly via some form of functional Interface. This would allow me to programatically decide if it makes sense to prevent a user from closing the dialog box. This would need to be configurable for each DialogPane in the Dialog (one per page in the Wizard)
Allow a programmer to optionally disable the default behavior of allowing a Dialog instance to be closed via the Escape key, and/or to allow the programmer the ability to interject and confirm that the user actually wishes to do so.
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogEvent;
import javafx.stage.Stage;
public class DialogDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.getDialogPane().setContentText("This is a Wizard");
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.NEXT, ButtonType.PREVIOUS, ButtonType.CANCEL);
dialog.setOnCloseRequest(this::confirmClose);
dialog.showAndWait();
}
private void confirmClose(DialogEvent dialogEvent) {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.setContentText("Are you sure you wish to close the Wizard?");
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
dialog.showAndWait().ifPresent(buttonType -> {
if (buttonType != ButtonType.YES) {
dialogEvent.consume();
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I have not been able to come up with a suitable workaround, short of re-writing a complete implementation of the Dialog class with the above recommendations.