相当于 JavaFx 中的 FocusEvent.getOppositeComponent

2022-09-04 22:16:03

在我的 JavaFx 应用程序中,我想在主帧获得焦点时调用一个方法。但是,我只想在焦点在我的应用程序之外并返回的情况下做出反应(例如,当对话框关闭时)。。

当应用程序在Swing中时,我可以使用该方法

FocusEvent.getOppositeComponent

(这对应于失去焦点的元素),如果它为空,我知道焦点以前在我的应用程序之外。

我没有在JavaFX中找到任何等效的东西。

我尝试通过在窗口上添加事件过滤器来查看窗口事件:

primaryStage.addEventFilter(Event.ANY, e -> System.out.println("event " + e));

但它不跟踪焦点事件。


答案 1

JavaFX中没有等效项。焦点更改作为每个窗口的布尔属性单独处理,因此您只能判断窗口是接收焦点还是丢失焦点。如果将侦听器注册到应用程序中的所有窗口,则可以判断其中一个窗口在另一个窗口获得焦点时是否丢失了焦点。

JavaFX 中没有“FocusEvent”,您可以在 Event 中找到列出的所有事件类型。

您可以在此处请求该功能。


答案 2

我终于找到了一种半满意的方法来处理这个问题,使用JavaFX中的事件顺序,所以我把它作为一个答案发布,以防它可以帮助其他人。

当窗口 w1 关闭,将焦点提供给窗口 w2 时,事件顺序如下:

  1. w1 接收事件WINDOW_HIDING
  2. w2 焦点属性更改为 true
  3. w1 接收事件WINDOW_HIDDEN

因此,我编写了以下代码,以便我知道焦点是否来自内部窗口:

public class MainStage {
    private Stage primaryStage;
    private AtomicBoolean triggerEventOnFocusGain = new AtomicBoolean(true);

    ...

    primaryStage.focusedProperty.addListener((prop, oldVal, newVal) -> {
        if(newVal.booleanValue() && triggerEventOnFocusGain.get()) {
            doStuff();
        }
    });
}

public class SomeDialog {
    private MainStage mainStage;
    private Window dialogWindow;

    ...

    dialogWindow.addEventHandler(WindowEvent.WINDOW_HIDING, event ->
        mainStage.setTriggerEventOnFocusGain(false));
    dialogWindow.addEventHandler(WindowEvent.WINDOW_HIDDEN, event ->
        mainStage.setTriggerEventOnFocusGain(true));
}

唯一的问题是我必须对所有内部窗口/对话框执行此操作。

就我而言,我最终决定,我只能为少数几个对话而离开,对于这些对话来说,触发事件将是有问题的,并忽略其他对话。

当然,另一种方法是引入执行上述代码的所有视图类的公共抽象父级。