Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent or cancel exit JavaFX 2

When exiting a JavaFX program I'm overriding Application.stop() in order to check for unsaved changes. This works okay, but it would be nice to give the user the option to cancel the operation.

like image 834
T-and-M Mike Avatar asked Dec 05 '12 16:12

T-and-M Mike


1 Answers

Application.stop() is last-chance-saloon in other words although it does trap the exit, it's a bit late to revoke the exit process.

Better is to set a listener for the close request which can be cancelled by consuming the event.

In the application class:

public void start(Stage stage) throws Exception {
    FXMLLoader ldr = new FXMLLoader(getClass()
                .getResource("Application.fxml"));
    Parent root = (Parent) ldr.load();
    appCtrl = (ApplicationController) ldr.getController();

    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();

    scene.getWindow().setOnCloseRequest(new EventHandler<WindowEvent>() {
        public void handle(WindowEvent ev) {
            if (!appCtrl.shutdown()) {
                ev.consume();
            }
        }
    });
}

and then in the application controller, referenced as appCtrl above:

/** reference to the top-level pane                               */
@FXML
private AnchorPane mainAppPane;

public boolean shutdown() {
    if (model.isChanged()) {
        DialogResult userChoice =
                ConfirmDialog.showYesNoCancelDialog("Changes Detected",
                "Do you want to save the changes?  Cancel revokes the "
                + "exit request.",
                mainAppPane.getScene().getWindow());

        if (userChoice == DialogResult.YES) {
            fileSave(null);

            if (model.isChanged()) {
                // cancelled out of the save, so return to the app
                return false;
            }
        }

        return userChoice == DialogResult.NO;
    }

    return true;
}

noting: mainAppPane is referenced in the FXML ( using the JavaFX Scene Builder in this case ) to allow access to the scene and window; the dialog is one extended from https://github.com/4ntoine/JavaFxDialog and fileSave is the event handler for File -> Save menu item. For the File -> Exit menu item:

@FXML
private void fileExitAction(ActionEvent ev) {
    if (shutdown()) {
        Platform.exit();
    }
}

Hope this helps someone!

like image 87
T-and-M Mike Avatar answered Nov 07 '22 11:11

T-and-M Mike