Search code examples
javafxalert

Alerts in Javafx do not close when "x" button is pressed


Hi for a different javafx application I've been testing alerts and the only thing which doesn't work in pressing the "X" button for the alert box.

I have added a code below but if you don't have time to run it here is a GIF of explaining what issue I have with the alertbox: https://giant.gfycat.com/GeneralUntimelyBluewhale.webm

I am not quite sure how to upload gifs to the actual post so sorry for that.

Is there any way of fixing this issue?

Thanks

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Playground extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        VBox root = new VBox(100);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        Button button = new Button("Alert");
        button.setOnAction(event -> {
            ButtonType goodButton = new ButtonType("Good");
            ButtonType badButton = new ButtonType("Bad");
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "", goodButton, badButton);
            alert.showAndWait();

            if (alert.getResult().equals(goodButton)) {
                System.out.println("Good");
            } else if (alert.getResult().equals(badButton)) {
                System.out.println("Bad");
            }
        });

        // Add the buttons to the layout
        root.getChildren().addAll(button);

        // Show the Stage
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

Solution

  • As per the "Dialog Closing Rules" in the Dialog API documentation, the default "X" button works normally only if atleast one of the buttons is of type "CANCEL". So changing any one of your button to ButtonType.CANCEL should close your dialog on click of "X".

    If you are not interested in using built in buttons, then you have to explicitly handle the close request of dialog as per your requirement.

                ButtonType goodButton = new ButtonType("Good");
                ButtonType badButton = new ButtonType("Bad");
                Alert alert = new Alert(Alert.AlertType.ERROR,"",goodButton,badButton);
                Window window = alert.getDialogPane().getScene().getWindow();
                window.setOnCloseRequest(e -> alert.hide());
                Optional<ButtonType> result = alert.showAndWait();
                result.ifPresent(res->{
                    if (res.equals(goodButton)) {
                        System.out.println("Good");
                    } else if (res.equals(badButton)) {
                        System.out.println("Bad");
                    }
                });