JDK7 和原生组件的焦点问题
我们有一个 swing 应用程序,它通过 JNIWrapper 嵌入了一个 IE ocx 组件.
We have a swing application which embeds a IE ocx component via JNIWrapper.
从 jdk6 切换到 jdk7 后,我们开始注意到焦点问题.当嵌入式 IE 显示带有文本字段的网页(例如 google 搜索页面)时,麻烦就开始了:
After switching from jdk6 to jdk7 we start noticing focus problems. When the embedded IE shows a web page with text fields (e.g. the google search page) than the trouble starts:
浏览器抓住"焦点,因此您可以开始在搜索文本字段中输入内容.键入的每个键都会进入 IE ocx.但是swing似乎忽略了这个焦点变化.即使我将焦点更改为 swing 文本字段(并且 swing 显示闪烁的输入光标),所有键入的键都会转到 IE ocx
The Browser 'catches' the focus, so u can start typing in the search text field. Every key typed goes to the IE ocx. But swing seems to ignore this focus change. Even if i change the focus to a swing text field (and swing shows the blinking input cursor), all typed keys goes to the IE ocx
修复"焦点的唯一方法是停用并激活主框架.之后,焦点似乎是一致的.但是如果我再次点击谷歌搜索文本字段,焦点又会被打破.
The only way to 'fix' the focus is to deacitvate and activate the main frame. after that the focus seems to be consistent. But if i click in the google search text field again, the focus is broken again.
jdk7 中的焦点处理似乎有很大的变化.来自 链接:
It seems there is a big change to focus handling in jdk7. From the link:
在 Windows 平台上,实现了综合焦点"的概念.这意味着焦点所有者组件仅模拟其可聚焦状态,而真正的本机焦点设置为焦点代理"组件.该组件接收键和输入法本机消息并将它们分派给焦点所有者.在 JDK7 之前,焦点代理组件是框架/对话框内的专用隐藏子组件.在 JDK7 中,框架/对话框本身充当焦点代理.现在它代理的焦点不仅是拥有窗口中的组件,还包括所有子组件.一个简单的窗口从不接收本机焦点并依赖于其所有者的焦点代理.这种机制对用户来说是透明的,但在调试时应加以考虑.
On the Windows platform, a concept of "synthetic focus" has been implemented. It means that a focus owner component only emulates its focusable state whereas real native focus is set to a "focus proxy" component. This component receives key and input method native messages and dispatches them to a focus owner. Prior to JDK7 a focus proxy component was a dedicated hidden child component inside a frame/dialog. In JDK7 a frame/dialog itself serves as a focus proxy. Now it proxies focus not only for components in an owned window but for all child components as well. A simple window never receives native focus and relies on focus proxy of its owner. This mechanism is transparent for a user but should be taken into account when debugging.
任何人都有修复"行为的想法?
Anyone has an idea to 'fix' the behavior?
编辑:这里有一些代码可以用 JxBrowser
EDIT: Here some code to reproduce the problem with JxBrowser
public static void main(String[] args) {
Browser browser = BrowserFactory.createBrowser(BrowserType.IE);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(browser.getComponent(), BorderLayout.CENTER);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
textField = new JTextField();
panel.add(textField);
textField.setColumns(10);
frame.setSize(700, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
browser.navigate("http://www.google.com");
}
推荐答案
所有 - 我们刚刚在另一个浏览器组件(DjProject Native Swing)中遇到了这个问题.在 Java 1.6 下一切正常,但在 Java-7 下,我们开始看到奇怪的问题,您可以在输入框中输入内容,但如果您向后选择以修复错字,则在单击鼠标后无法输入.要恢复,您必须从输入字段中选择,然后再返回以继续编辑.
All - We just experienced this problem with another browser component (DjProject Native Swing). Everything works fine under Java 1.6 but under Java-7 we started seeing weird problems where you can type into an input box but if you select backwards to fix a typo you could not type after making the mouse click. To recover you had to select out of the input field and then back in to continue your edit.
参见 http:///docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/awt.html#gdcqp特别是这里关于合成焦点和焦点代理的部分.
See http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/awt.html#gdcqp Particularly the part here about sythentic focus and focus proxies.
总之长话短说 - 在我们的例子中,我能够通过将鼠标侦听器附加到 JWebBrowser.getNativeComponent() 来找到解决方法.然后在 mousePressed 上执行 browser.requestFocus() 后跟 browser.getNativeComponent().requestFocusInWindow();
Anyway to cut a long story short - in our case I was able to find a work-around by attaching a mouse listener to the JWebBrowser.getNativeComponent(). Then on mousePressed execute a browser.requestFocus() followed by a browser.getNativeComponent().requestFocusInWindow();
希望这对遇到此问题的其他人有所帮助.
Hope this helps anyone else that comes across this.
相关文章