当用户试图退出程序时,程序能够有机会进行确认和清理的工作。因此,正确的程序退出过程应该包含一些步骤

  1. 增加Button或菜单,让用户发布希望退出程序的信号。
  2. (可选)显示窗口,确认用户真的希望退出程序。
  3. 执行必要的清理工作,如:关闭文件和其他资源。
  4. 执行primary stage的close方法,关闭应用程序。

虽然我们做了上述工作,但用户依然可以通过直接点击窗口右上角X的方式绕过我们精心设计的代码,直接关闭程序。幸运的是,JavaFX提供了机会让我们阻止这样的事发生。

当用户试图关闭窗口时,JavaFX会产生一个CloseRequest事件,并发送给窗口对应的舞台。我们可以调用Stage类的setOnCloseRequest方法,为这个事件提供一个事件处理器。当用户关闭窗口的时候,这个事件管理器就会被调用。

直接的方法就是让我们的Close按钮和CloseRequest事件共享相同的事件处理器

btnClose.setOnAction(e -> btnClose_Click())
primaryStage.setOnCloseRequest(e -> btnClose_Click())

如果事件处理器中包含确认步骤,确认的结果可能是用户放弃关闭程序。但是,对于CloseRequest事件,程序依然会被关闭。这是因为事件处理器如果没有调用close方法关闭stage,那么CloseRequest事件会按照预定的顺序继续传播到该事件的下一个处理器,因此程序还是会被关闭。为了阻止事件的传播,我们调用事件的consume方法,这样就避免了JavaFX在事件处理后自动关闭stage。

处理两种关闭事件差异的简单方法是,总是消费掉CloseRequest事件

btnClose.setOnAction(e -> btnClose_Click())
primaryStage.setOnCloseRequest(
        e -> {
        e.consume()
        btnClose_Click()})