Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
}

}

like image 715
user3878223 Avatar asked Jul 21 '15 13:07

user3878223


1 Answers

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).

like image 84
jewelsea Avatar answered Nov 11 '22 10:11

jewelsea