如何应对来自另一个应用程序的焦点获取?

3

我的JavaFX 8应用程序需要在获取焦点时执行doStuff()。这很简单:

primaryStage.focusedProperty().addListener((observable, wasFocused, nowFocused) -> {
    doStuff();
});

然而,当我显示对话框并且用户关闭它时,doStuff()会触发。我希望它只在用户从另一个应用程序切换到我的应用程序时触发,例如从浏览器中使用Alt+Tab
换句话说,我想要在其他应用程序窗口失去焦点并且我的应用程序窗口获得焦点时才触发doStuff()
这种情况可能吗?
编辑:由FibreFoXAppelemac发布的答案需要在显示对话框之前显式执行额外的步骤。这个解决方案远非完美,因为我(或一般开发人员)必须在显示对话框之前记住这一步骤。忘记它会引入难以找到的错误。
自动扩展Dialog不是一个选项,因为我想使用已经扩展原始Dialog的内置对话框。
这是一个很基本的功能,如果在JavaFX中没有简单实现它的方法,我会很惊讶。
2个回答

1
我建议在您的对话框中添加监听器,这样就可以在对话框刚关闭/失去焦点时不执行doStuff()。
我能想到的最简单的方法是在对话框关闭时设置一个Instant(使用Instant.now),如果应用程序重新获得焦点,则创建另一个Instant,并检查Duration.between(instantLostFocusDialog, instantGainedFocusApp).getSeconds()是否超过1秒(或者添加getNano()以更具体)。只有在这种情况下才会执行doStuff()

为每个对话框都这样做听起来不太有趣。我希望有一种自动处理它的方法。 - gronostaj
嗯,我建议创建一个Instant的(ArrayList)列表用于对话框,创建一个小的子类用于监听器,并实现将Instant添加到该列表中,然后检查每个Instant。虽然不是非常高效,但我认为这会起作用。 - Appelemac

1
当打开这样的对话框时,您可以使用全局布尔值,并且只有当该全局开关为true/false/您选择的任何状态时,您才能对该状态进行反应。
public class GlobalDialogMemory{
    public static boolean dialogShown = false;
}

当使用CDI时,您可以注入应用程序范围内的当前实例(但是您应该使用getter/setter和非静态布尔值代替;)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接