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

时间:2016-06-28 14:13:33

标签: java javafx

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

close事件处理程序存根看起来类似于以下内容:

foo.setOnCloseRequest(new EventHandler<WindowEvent>() 
  {      
    @Override
    public void handle(WindowEvent event)
    {          
      try
      {
        barController.exec(Action.DELETE, item);     
      } catch (Exception e)
      {
        e.printStackTrace();
      }
    }
  });

问题是,当我从Ubuntu中的栏中暂停程序时(例如),仍然会为每个窗口调用此事件;每次测试事件为WindowEvent.WINDOW_CLOSE_REQUEST时,用户或应用程序是否关闭了窗口。

简单地说:是否有某种方式来描绘&#34; onUserCloseWindow&#34;来自&#34; onCloseApplication&#34;?

3 个答案:

答案 0 :(得分:1)

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

  

关闭此窗口的外部请求

我认为你最好的选择就是实现你自己的窗口装饰here

答案 1 :(得分:1)

看起来,当您从任务栏(至少在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);
    }
}

答案 2 :(得分:0)

最好的方法似乎是测试舞台是否有焦点。按下X应始终聚焦。因此,如果在聚焦窗口上调用关闭请求,则发送删除请求。这似乎不考虑像“Alt-F4”这样的行为,但可以将其称为“特征”。它不是商业应用程序,只是我想为图形Linux环境编写的有用工具。

if (foo.focusedProperty().getValue()) {
            try
            {
              barController.exec(Action.DELETE, fooId);
            } catch (Exception e)
            {
              e.printStackTrace();
            }
          }