1

How can I close the entire app when a TornadoFX window is closed?

With JavaFX it is usually:

val app = JFrame()
app.defaultCloseOperation = JFrame.EXIT_ON_CLOSE

Is there a way to detect on TornadoFX View closed?

BAR
  • 15,909
  • 27
  • 97
  • 185
  • 2
    [How to close a JavaFX application on window close?](https://stackoverflow.com/questions/12153622/how-to-close-a-javafx-application-on-window-close) – Abra Jan 16 '20 at 05:34
  • @Abra This is for a TornadoFX app. – BAR Jan 16 '20 at 17:02
  • "With JavaFX it is usually: `val app = JFrame() app.defaultCloseOperation = JFrame.EXIT_ON_CLOSE`" Except that's _Swing_, not _JavaFX_. Also, note that TornadoFX is, at its core, simply a Kotlin framework on top of JavaFX. – Slaw Jan 17 '20 at 19:10

1 Answers1

2

Usually, closing the primary stage activates the App class's stop() function. This is what you want to override to do your own shutdown routine:

class MyApp : App (FirstView::class) {
    override fun stop() {
        super.stop()
        /* Do your shutdown routine here  */
    }
}

However, I've had instances where that logic gets broken and only closing all program windows works. If you have a 'main window' that you want to ensure shuts down the program, add this in your App class as well:

override fun start(stage: Stage) {
   stage.setOnHiding { stop() }
}

Edit: I would use your IDE to look at what exactly the stop() function does for you, as well as look at the answers linked by Abra to see what the vanilla JavaFX Platform.exit() function does as TornadoFX is just JavaFX at its core, and this is most explicit shutdown of a JavaFX application. Some users in that thread reported that their program would still hang depending on what they were doing and suggested adding System.exit(0);, aka exitProcess(0) in Kotlin, to their shutdown routine to make sure the program dies.

Steph
  • 831
  • 6
  • 19
  • "Usually, closing the primary stage activates the App class's stop() function. [...] However, I've had instances where that logic gets broken and only closing all program windows works". That's not broken logic. As documented [here](https://openjfx.io/javadoc/13/javafx.graphics/javafx/application/Application.html) and [here](https://openjfx.io/javadoc/13/javafx.graphics/javafx/application/Platform.html#setImplicitExit(boolean)), if configured to implicitly exit, the shutdown procedure only starts when the **last** window is closed, not necessarily when the primary stage is closed. – Slaw Jan 17 '20 at 19:15
  • 2
    And if you want to explicitly stop the JavaFX runtime then you need to call [`Platform#exit()`](https://openjfx.io/javadoc/13/javafx.graphics/javafx/application/Platform.html#exit()). The `Application#stop()` method is just a life-cycle method that's invoked at the appropriate time; it doesn't activate that part of the life-cycle and should probably never be invoked manually. – Slaw Jan 17 '20 at 19:17
  • @Slaw that doesn't seem right. I've made programs that call the TornadoFX `App.stop()` function only when the primary stage window is closed, even if there are other windows open that don't have owners. – Steph Jan 17 '20 at 19:39
  • Then there was something wrong, possibly a bug in JavaFX itself, because that's not what's documented to happen. Personally, I've never encountered that problem. – Slaw Jan 17 '20 at 19:41
  • @Slaw I think you are confusing JavaFX's `Application#stop()` with TornadoFX's `App#stop()`. – Steph Jan 17 '20 at 19:43
  • Possibly. Though the KDocs show [`App`](https://tornadofx.io/dokka/tornadofx/tornadofx/-app/index.html) extends from `Application` and make no mention of changing how and when `stop()` is invoked. Not finding anything in the [Wiki](https://github.com/edvin/tornadofx/wiki) or [TornadoFX Guide](https://edvin.gitbooks.io/tornadofx-guide/content/) about a difference in behavior either, though I could have missed it. – Slaw Jan 17 '20 at 19:52
  • Yes, but there are two things to keep in mind: 1. JavaFX's `Application#stop()` method is an empty method. TornadoFX definitely adds its own functionality. 2. Stage handling is different due to TornadoFX's implementation. I haven't explored deeply into TornadoFX's lifecycle management but I wouldn't be surprised that it adds onto JavaFX handling of just when `stop()` is called. I also wouldn't be surprised if it's not full-proof, as TornadoFX requires proper calls to track stage life-cycles which are buggy anyways. – Steph Jan 17 '20 at 19:58
  • TornadoFX builds a framework, in Kotlin, on top of JavaFX. Part of this involves setting up container-like code which needs to be properly disposed of and which it appears to do in its implementation of the `stop()` method. If TornadoFX is changing how the life-cycle of JavaFX is handled I would consider that a bug. The `stop()` method should only be invoked when the entire application is exiting. As the `App` class seems to be TornadoFX's equivalent of `Application` in a plain JavaFX application, it doesn't make sense to invoke `stop()` when part of the application is still running. – Slaw Jan 17 '20 at 20:07