These are fundamentally different things.
A handler specified for a particular stage with setOnCloseRequest()
will be executed when the user requests to close that particular stage (typically by pressing the OS-specific "close" button in the window). It is invoked on the FX Application Thread, and will be called before the window actually closes. It's execution does not imply that the application is exiting, that the FX toolkit is being closed down, or that the Java Virtual Machine is exiting. A handler here may not only assume the FX toolkit is still running, but may modify the UI (since it is on the FX Application Thread) and may veto the request to close the window by consuming the event.
A shutdown hook is a user-provided thread that is executed when the Java Virtual Machine exits. It is its own thread, and is executed as part of the shutdown sequence. As such, it must not assume any other services are running. From the API docs:
They should also not rely blindly upon services that may have
registered their own shutdown hooks and therefore may themselves in
the process of shutting down. Attempts to use other thread-based
services such as the AWT event-dispatch thread, for example, may lead
to deadlocks.
The same caveat that applies to the AWT event dispatch thread also applies to the FX Application Thread.
In some very specific circumstances, the invocation of a setOnCloseRequested
handler may indicate that the JVM may soon be about to exit. These circumstances include all of the following, but I may have omitted something:
- The handler does not consume the event
- The stage is the last stage left open
Platform.isImplicitExit()
returns true
- No non-daemon threads are running, and none are started by the
Application
instance's stop()
method
Which you should use depends entirely on what you are trying to do. If the aim is to release resources started as part of you JavaFX Application that are only no longer needed when the application exits, I would not use either of these, but would override the Application.stop()
method.