user3878223
user3878223

Reputation: 441

Alert Box For When User Attempts to close application using setOnCloseRequest in JavaFx

I am trying to prompt the user to confirm they want to close a program before exiting. In the event a task is still being executed, I wanted to confirm that the still wish to exit or give them a chance to allow the task to finish before exiting. I used setOnCloseRequest, but it did not work. Ive used event.consume which just seemed to disable the [x] button. Any suggestions are appreciated. I found a similar question here that did not work for me -> JavaFX stage.setOnCloseRequest without function?

Public class Sample extends Application {
      @Override
    public void start(Stage stage) throws Exception {

    stage.setOnCloseRequest(event -> {
        NewScanView checkScan = new NewScanView();
        boolean isScanning = checkScan.isScanning();

            Alert alert = new Alert(AlertType.CONFIRMATION);
            alert.setTitle("Close Confirmation");
            alert.setHeaderText("Cancel Creation");
            alert.setContentText("Are you sure you want to cancel creation?");
        if (isWorking == true){

            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK){
                stage.close();
            }

            if(result.get()==ButtonType.CANCEL){
                alert.close();
            }

        }


    });
    stage.setHeight(600);
    stage.setWidth(800);
    stage.setTitle("Title");
    stage.show();

}

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

}

Upvotes: 9

Views: 14367

Answers (2)

jewelsea
jewelsea

Reputation: 159536

This answer is based on the answer to Javafx internal close request. That question is different from this question, but the answer is very similar.

main dialog

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.StackPane;
import javafx.stage.*;
import javafx.stage.WindowEvent;

import java.util.Optional;

public class CloseConfirm extends Application {

    private Stage mainStage;

    @Override
    public void start(Stage stage) throws Exception {
        this.mainStage = stage;
        stage.setOnCloseRequest(confirmCloseEventHandler);

        Button closeButton = new Button("Close Application");
        closeButton.setOnAction(event ->
                stage.fireEvent(
                        new WindowEvent(
                                stage,
                                WindowEvent.WINDOW_CLOSE_REQUEST
                        )
                )
        );

        StackPane layout = new StackPane(closeButton);
        layout.setPadding(new Insets(10));

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
        Alert closeConfirmation = new Alert(
                Alert.AlertType.CONFIRMATION,
                "Are you sure you want to exit?"
        );
        Button exitButton = (Button) closeConfirmation.getDialogPane().lookupButton(
                ButtonType.OK
        );
        exitButton.setText("Exit");
        closeConfirmation.setHeaderText("Confirm Exit");
        closeConfirmation.initModality(Modality.APPLICATION_MODAL);
        closeConfirmation.initOwner(mainStage);

        // normally, you would just use the default alert positioning,
        // but for this simple sample the main stage is small,
        // so explicitly position the alert so that the main window can still be seen.
        closeConfirmation.setX(mainStage.getX());
        closeConfirmation.setY(mainStage.getY() + mainStage.getHeight());

        Optional<ButtonType> closeResponse = closeConfirmation.showAndWait();
        if (!ButtonType.OK.equals(closeResponse.get())) {
            event.consume();
        }
    };

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

}

The answer does use event.consume(), which you said you tried and did not work for you (though I'm not sure why not as it works fine for me with this sample code).

Upvotes: 11

SomeStudent
SomeStudent

Reputation: 3048

Try creating a popup box (if you haven't) that upon clicking exit will prompt the user. If they select "Ok" then call the exit method, otherwise return to whatever it is you are doing.

Here's a webpage that contains an example as as to how to write your popup as the docs are utter garbage. https://gist.github.com/jewelsea/1926196

Upvotes: 0

Related Questions