How can I fire internal close request?

前端 未结 1 1143
被撕碎了的回忆
被撕碎了的回忆 2020-12-06 06:15

I have trouble when closing a window in JavaFX.

I define my setOnCloseRequest as I wanted and it works when I click the x in the window. However, I als

相关标签:
1条回答
  • 2020-12-06 07:04

    Solution

    Fire an event from your internal close request (on the button push), so that the application thinks it received an external close request. Then your close request logic can be identical whether the request came from an external event or an internal one.

    private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
            // close event handling logic.
            // consume the event if you wish to cancel the close operation.
    }
    
    ...
    
    stage.setOnCloseRequest(confirmCloseEventHandler);
    
    Button closeButton = new Button("Close Application");
    closeButton.setOnAction(event ->
            stage.fireEvent(
                    new WindowEvent(
                            stage,
                            WindowEvent.WINDOW_CLOSE_REQUEST
                    )
            )
    );
    

    Note

    This is a Java 8+ solution, for JavaFX 2, you will need to convert the lambda functions in anonymous inner classes and will be unable to use the Alert dialog box but will need to provide your own alert dialog system as JavaFX 2 does not feature an in-built one. I strongly recommend upgrading to Java 8+ rather than staying with JavaFX 2.

    Sample UI

    close app

    close confirm

    Sample Code

    The sample code will show the user a close confirmation alert and cancel the close request if the user does not confirm the close.

    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);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题