Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a JavaFX Alert with a check box for "Do not ask again"?

Tags:

javafx

I would like to use the standard JavaFX Alert class for a confirmation dialog that includes a check box for "Do not ask again". Is this possible, or do I have to create a custom Dialog from scratch?

I tried using the DialogPane.setExpandableContent() method, but that's not really what I want - this adds a Hide/Show button in the button bar, and the check box appears in the main body of the dialog, whereas I want the check box to appear in the button bar.

like image 843
ctg Avatar asked Apr 30 '16 00:04

ctg


People also ask

What is alert in Javafx?

An alert is a dialog which shows pre-built dialog types. You can create an alert by instantiating the javafx.scene.control.Alert class. This class is a subclass of the Dialog class.


Video Answer


1 Answers

Yes, it is possible, with a little bit of work. You can override DialogPane.createDetailsButton() to return any node you want in place of the Hide/Show button. The trick is that you need to reconstruct the Alert after that, because you will have got rid of the standard contents created by the Alert. You also need to fool the DialogPane into thinking there is expanded content so that it shows your checkbox. Here's an example of a factory method to create an Alert with an opt-out check box. The text and action of the check box are customizable.

public static Alert createAlertWithOptOut(AlertType type, String title, String headerText, 
               String message, String optOutMessage, Consumer<Boolean> optOutAction, 
               ButtonType... buttonTypes) {
   Alert alert = new Alert(type);
   // Need to force the alert to layout in order to grab the graphic,
    // as we are replacing the dialog pane with a custom pane
    alert.getDialogPane().applyCss();
    Node graphic = alert.getDialogPane().getGraphic();
    // Create a new dialog pane that has a checkbox instead of the hide/show details button
    // Use the supplied callback for the action of the checkbox
    alert.setDialogPane(new DialogPane() {
      @Override
      protected Node createDetailsButton() {
        CheckBox optOut = new CheckBox();
        optOut.setText(optOutMessage);
        optOut.setOnAction(e -> optOutAction.accept(optOut.isSelected()));
        return optOut;
      }
    });
    alert.getDialogPane().getButtonTypes().addAll(buttonTypes);
    alert.getDialogPane().setContentText(message);
    // Fool the dialog into thinking there is some expandable content
    // a Group won't take up any space if it has no children
    alert.getDialogPane().setExpandableContent(new Group());
    alert.getDialogPane().setExpanded(true);
    // Reset the dialog graphic using the default style
    alert.getDialogPane().setGraphic(graphic);
    alert.setTitle(title);
    alert.setHeaderText(headerText);
    return alert;
}

And here is an example of the factory method being used, where prefs is some preference store that saves the user's choice

    Alert alert = createAlertWithOptOut(AlertType.CONFIRMATION, "Exit", null, 
                  "Are you sure you wish to exit?", "Do not ask again", 
                  param -> prefs.put(KEY_AUTO_EXIT, param ? "Always" : "Never"), ButtonType.YES, ButtonType.NO);
    if (alert.showAndWait().filter(t -> t == ButtonType.YES).isPresent()) {
       System.exit();
    }

And here's what the dialog looks like:

enter image description here

like image 63
ctg Avatar answered Nov 14 '22 18:11

ctg