JavaFX测试应用程序是作为一个整体关闭还是仅关闭单个窗口

JavaFX测试应用程序是作为一个整体关闭还是仅关闭单个窗口,java,javafx,Java,Javafx,我有一个JavaFX应用程序,可以打开多个窗口。当焦点从窗口丢失时,窗口内的数据将记录到数据库中。 当用户想要关闭窗口时,应该触发一个事件处理程序,请求从数据库中删除元组。 我只希望在用户主动单击窗口右上角的x时发生这种情况,而在应用程序完全退出(例如,如果程序从操作系统启动栏或等效工具退出)或以其他方式停止时,不 关闭事件处理程序存根类似于以下内容: foo.setOnCloseRequest(new EventHandler<WindowEvent>() {

我有一个JavaFX应用程序,可以打开多个窗口。当焦点从窗口丢失时,窗口内的数据将记录到数据库中。 当用户想要关闭窗口时,应该触发一个事件处理程序,请求从数据库中删除元组。 我只希望在用户主动单击窗口右上角的x时发生这种情况,而在应用程序完全退出(例如,如果程序从操作系统启动栏或等效工具退出)或以其他方式停止时,

关闭事件处理程序存根类似于以下内容:

foo.setOnCloseRequest(new EventHandler<WindowEvent>() 
  {      
    @Override
    public void handle(WindowEvent event)
    {          
      try
      {
        barController.exec(Action.DELETE, item);     
      } catch (Exception e)
      {
        e.printStackTrace();
      }
    }
  });
foo.setOnCloseRequest(新的EventHandler()
{      
@凌驾
公共无效句柄(WindowEvent事件)
{          
尝试
{
barController.exec(Action.DELETE,item);
}捕获(例外e)
{
e、 printStackTrace();
}
}
});
问题是,当我在Ubuntu的工具栏上停止程序时(例如),每个窗口仍然会调用这个事件;每次测试事件都是
WindowEvent.WINDOW\u CLOSE\u REQUEST
,无论用户或应用程序是否关闭了窗口


简单地说:是否有某种方式可以将“onUserCloseWindow”与“onCloseApplication”区分开来

当使用本机窗口装饰时,我认为没有办法区分这些类型的事件。从应用程序的角度来看,它们都是

关闭此窗口的外部请求


我认为您最好的选择是实现您自己的窗口装饰,如前所述。

当使用本机窗口装饰时,我认为没有办法区分这些类型的事件。从应用程序的角度来看,它们都是

关闭此窗口的外部请求


我认为您最好的选择是实现您自己的窗口装饰,如前所述。

当您从任务栏(至少在Mac上)关闭所有者窗口时,似乎会在事件传递到其他子窗口之前收到关闭请求事件。因此,您可以检测所有者的关闭请求事件,设置一个标志,当其他窗口接收到关闭请求时,它们可以在执行处理之前检查标志是否已设置。如果设置了该标志,则它是一个任务栏或用户启动的整个应用程序关闭,否则它是一个用户启动的仅关闭一个辅助窗口的关闭

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Eventacity extends Application {
    private boolean isPrimaryClosing = false;

    @Override
    public void start(Stage primary) {
        primary.setScene(new Scene(new Group(), 200, 200));
        primary.setTitle("Main");
        addEventHandlers(primary);
        primary.show();

        for (int i = 0; i < 3; i++) {
            Stage secondary = new Stage();
            secondary.setTitle("Secondary " + i);
            secondary.setScene(new Scene(new Group(), 100, 100));
            secondary.setX(primary.getX() + (i+1) * 25);
            secondary.setY(primary.getY() + (i+1) * 25);

            secondary.initOwner(primary);
            addEventHandlers(secondary);

            secondary.show();
        }
    }

    private void addEventHandlers(Stage stage) {
        stage.setOnCloseRequest(event -> {
            if (stage.getOwner() == null) {
                isPrimaryClosing = true;
            }

            System.out.println(
                    "Close Request:   " + stage.getTitle()
            );
            System.out.println(
                    "Primary Closing: " + isPrimaryClosing
            );

            if (!isPrimaryClosing) {
                // delete data from database.
            }
        });
        stage.setOnHiding(event -> System.out.println(
                "Hiding:          " + stage.getTitle())
        );
        stage.setOnHidden(event -> System.out.println(
                "Hid:             " + stage.getTitle())
        );
        stage.setOnShowing(event -> System.out.println(
                "Showing:         " + stage.getTitle())
        );
        stage.setOnShown(event -> System.out.println(
                "Showed:          " + stage.getTitle())
        );
    }

    public static void main(String[] args) {
        launch(args);
    }
}
导入javafx.application.application;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.stage.stage;
公共类事件扩展应用程序{
私有布尔值isPrimaryClosing=false;
@凌驾
公共作废开始(阶段主要){
setScene(新场景(新组(),200200));
主要。设置标题(“主要”);
加法器(主);
primary.show();
对于(int i=0;i<3;i++){
第二阶段=新阶段();
二级。设置标题(“二级”+i);
secondary.setScene(新场景(newgroup(),100100));
secondary.setX(primary.getX()+(i+1)*25);
secondary.setY(primary.getY()+(i+1)*25);
次要所有者(主要);
加法器(二级);
secondary.show();
}
}
私人无效加法器(阶段){
stage.setOnCloseRequest(事件->{
if(stage.getOwner()==null){
isPrimaryClosing=true;
}
System.out.println(
“关闭请求:”+stage.getTitle()
);
System.out.println(
“主关闭:”+IsPrimary关闭
);
如果(!isPrimary Closing){
//从数据库中删除数据。
}
});
stage.setOnHiding(事件->System.out.println(
隐藏:“+stage.getTitle())
);
stage.setOnHidden(事件->System.out.println(
“Hid:+stage.getTitle())
);
stage.setOnShowing(事件->System.out.println(
显示:“+stage.getTitle())
);
stage.setOnShown(事件->System.out.println(
显示:“+stage.getTitle())
);
}
公共静态void main(字符串[]args){
发射(args);
}
}

当您从任务栏(至少在Mac上)关闭所有者窗口时,似乎会在事件传递到其他子窗口之前收到关闭请求事件。因此,您可以检测所有者的关闭请求事件,设置一个标志,当其他窗口接收到关闭请求时,它们可以在执行处理之前检查标志是否已设置。如果设置了该标志,则它是一个任务栏或用户启动的整个应用程序关闭,否则它是一个用户启动的仅关闭一个辅助窗口的关闭

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Eventacity extends Application {
    private boolean isPrimaryClosing = false;

    @Override
    public void start(Stage primary) {
        primary.setScene(new Scene(new Group(), 200, 200));
        primary.setTitle("Main");
        addEventHandlers(primary);
        primary.show();

        for (int i = 0; i < 3; i++) {
            Stage secondary = new Stage();
            secondary.setTitle("Secondary " + i);
            secondary.setScene(new Scene(new Group(), 100, 100));
            secondary.setX(primary.getX() + (i+1) * 25);
            secondary.setY(primary.getY() + (i+1) * 25);

            secondary.initOwner(primary);
            addEventHandlers(secondary);

            secondary.show();
        }
    }

    private void addEventHandlers(Stage stage) {
        stage.setOnCloseRequest(event -> {
            if (stage.getOwner() == null) {
                isPrimaryClosing = true;
            }

            System.out.println(
                    "Close Request:   " + stage.getTitle()
            );
            System.out.println(
                    "Primary Closing: " + isPrimaryClosing
            );

            if (!isPrimaryClosing) {
                // delete data from database.
            }
        });
        stage.setOnHiding(event -> System.out.println(
                "Hiding:          " + stage.getTitle())
        );
        stage.setOnHidden(event -> System.out.println(
                "Hid:             " + stage.getTitle())
        );
        stage.setOnShowing(event -> System.out.println(
                "Showing:         " + stage.getTitle())
        );
        stage.setOnShown(event -> System.out.println(
                "Showed:          " + stage.getTitle())
        );
    }

    public static void main(String[] args) {
        launch(args);
    }
}
导入javafx.application.application;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.stage.stage;
公共类事件扩展应用程序{
私有布尔值isPrimaryClosing=false;
@凌驾
公共作废开始(阶段主要){
setScene(新场景(新组(),200200));
主要。设置标题(“主要”);
加法器(主);
primary.show();
对于(int i=0;i<3;i++){
第二阶段=新阶段();
二级。设置标题(“二级”+i);
secondary.setScene(新场景(newgroup(),100100));
secondary.setX(primary.getX()+(i+1)*25);
secondary.setY(primary.getY()+(i+1)*25);
次要所有者(主要);
加法器(二级);
secondary.show();
}
}
私人无效加法器(阶段){
stage.setonclosure