How to force JavaFX application close request programmatically


Question

I have been using javafx.stage.Window.setOnCloseRequest(EventHandler<WindowEvent> arg0) to run some code as I close my application. Now I would like to force a close request in my code, so this very same algorithm is run.

I tried stage.close(), Platform.exit() and System.exit() to no avail; they all close the application, but directly. Is there a smooth way to do this without making a Robot press Alt + F4? (I can also imagine making a function out of the algorithm and calling it in setOnCloseRequest() and wherever else I might need it).

1
7
6/30/2014 5:55:01 AM

Accepted Answer

You can get the event handler from the stage and invoke it.

stage.getOnCloseRequest()
    .handle(
        new WindowEvent(
            stage,
            WindowEvent.WINDOW_CLOSE_REQUEST
        )
    )

But probably what you want to do is not just invoke your custom close request handler function, but rather fire a close request event which will run your handler and any other close event handlers for the window, (so, by default it will also close the window).

stage.fireEvent(
    new WindowEvent(
        stage,
        WindowEvent.WINDOW_CLOSE_REQUEST
    )
)

Sample App

Run the sample below (Java 8) to see the difference between the behavior of the two approaches:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

public class CloseMonitor extends Application {
    @Override
    public void start(Stage stage) {
        stage.setOnCloseRequest(
                event -> System.out.println("Close Requested")
        );

        Button handleClose = new Button("Handle Close Request");
        handleClose.setOnAction(
                event -> stage.getOnCloseRequest()
                        .handle(
                                new WindowEvent(
                                        stage,
                                        WindowEvent.WINDOW_CLOSE_REQUEST
                                )
                        )
        );
        handleClose.setMaxWidth(Double.MAX_VALUE);

        Button fireClose = new Button("Fire Close Request");
        fireClose.setOnAction(
                event -> stage.fireEvent(
                        new WindowEvent(
                                stage,
                                WindowEvent.WINDOW_CLOSE_REQUEST
                        )
                )
        );
        fireClose.setMaxWidth(Double.MAX_VALUE);

        stage.setScene(
                new Scene(
                        new VBox(
                                10,
                                handleClose,
                                fireClose    
                        )
                )
        );
        stage.show();
        stage.sizeToScene();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
23
6/30/2014 9:12:34 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon