如何在 java swing 中获得聚焦的 jxBrowser

How to get the focused jxBrowser in java swing

为了确定哪个组件拥有焦点,我通常调用 KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(),但是当 BrowserView 处于焦点时,它 returns 为空。 为什么会这样? jxBrowser 有替代方法吗?

默认情况下,JxBrowser 使用重量级模式。在重量级渲染模式下,单独的进程处理渲染,焦点所有者在另一个 BrowserContext 中。这就是为什么调用 KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() returns 为空的原因。 要解决此问题,请考虑使用轻量级模式。您可以在 JxBrowser 指南中找到有关渲染模式的更多信息:https://jxbrowser.support.teamdev.com/support/solutions/articles/9000013069-lightweight-or-heavyweight


编辑:在重量级渲染模式下,我们将本机 window 嵌入到您的 Java 应用程序中。 JavaFX 和 Swing 在焦点转移方面有不同的实现。在JavaFX中我们不清除焦点所有者,因此您可以通过Scene.focusOwnerProperty()获取。在Swing中我们必须在embedded nativewindow获得焦点时清除global focus owner,否则之后我们将无法将焦点转移到其他Swing组件。但是,我们使用内部 Java API 设置最近的焦点所有者。如果非要使用重量级渲染模式,可以使用反射获取最近的focus owner。我已经更新了答案以演示这种方法。

public static Component getMostRecentFocusOwner(Window window) {
    try {
        KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        Method getMostRecentFocusOwner = KeyboardFocusManager.class.getDeclaredMethod("getMostRecentFocusOwner", Window.class);
        getMostRecentFocusOwner.setAccessible(true);
        return (Component) getMostRecentFocusOwner.invoke(focusManager, window);
    } catch (Exception ignored) {}
    return null;
}

在 Java 16 中,我注意到“getMostRecentFocusOwner.setAccessible(true);”将抛出以下错误。

java.lang.reflect.InaccessibleObjectException: 无法使静态同步 java.awt.Component java.awt.KeyboardFocusManager.getMostRecentFocusOwner(java.awt.Window) 可访问:模块 java.desktop 不“打开 java.awt " 到未命名的模块

我已使用以下内容代替 return 活动 BrowserView

public static Component getMostRecentFocusOwner() {
     KeyboardFocusManager focusManager
     = KeyboardFocusManager.getCurrentKeyboardFocusManager();
         return focusManager.getFocusOwner().getParent();
}