Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Focus problems with JDK7 and native components

We have a swing application which embeds a IE ocx component via JNIWrapper.

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:

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.

It seems there is a big change to focus handling in jdk7. From the link:

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?

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");
}
like image 500
mabr Avatar asked Apr 19 '12 14:04

mabr


1 Answers

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.

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.

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.

like image 132
Adrian Avatar answered Sep 21 '22 14:09

Adrian