为了确定哪个组件拥有焦点,我通常调用KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()
,但当BrowserView处于焦点时,它会返回null。为什么会这样?jxBrowser有其他方法吗?
默认情况下,JxBrowser使用重量级模式。在重量级渲染模式中,单独的进程处理渲染,焦点所有者位于另一个BrowserContext中。这就是调用KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()
返回null的原因。若要解决此问题,请考虑使用轻量级模式。您可以在JxBrowser手册中找到有关渲染模式的详细信息:https://jxbrowser.support.teamdev.com/support/solutions/articles/9000013069-lightweight-or-heavyweight
EDIT:在重量级渲染模式中,我们将本机窗口嵌入到Java应用程序中。JavaFX和Swing在焦点转移方面有不同的实现。在JavaFX中,我们不清除焦点所有者,因此您可以通过Scene.focusOwnerProperty((获得它。在Swing中,当嵌入式本地窗口接收到焦点时,我们必须清除全局焦点所有者,否则,我们以后将无法将焦点转移到其他Swing组件。然而,我们使用内部Java API设置了最近的焦点所有者。如果必须使用重量级渲染模式,则可以使用反射获取最近的焦点所有者。我已经更新了答案来演示这种方法。
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中,我注意到"getMostCentrFocusOwner.setAccessible(true("将引发以下错误。
java.lang.reflect.InaccessableObjectException:无法使静态同步的java.awt.Component java.awt.KeyboardFocusManager.getMostCentrFocusOwner(java.awt.Window(可访问:模块java.desktop不"打开java.awt";至未命名模块
我使用以下内容来返回活动的BrowserView
public static Component getMostRecentFocusOwner() {
KeyboardFocusManager focusManager
= KeyboardFocusManager.getCurrentKeyboardFocusManager();
return focusManager.getFocusOwner().getParent();
}