我有一个打开多个窗口的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;?
答案 0 :(得分:1)
答案 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();
}
}