Project: SWT
Bug 216431 SWT_AWT: sun.awt.EmbeddedFrame is activated incorrectly
Reported: 2008-01-24 08:46:39 | Status: resolved fixed

SWT activates the sun.awt.EmbeddedFrame by means of dispatching it the WINDOW_ACTIVATED & WINDOW_GAINED_FOCUS events (on opening an embedding shell). From AWT's perspective the EmbeddedFrame is a heavyweight component (particularly a toplevel window). A heavyweight component (in contrast to a lightweight) actually can't be focused by simply dispatching (or posting) it a focus event. Setting it a focused component should be made on the native level. The approach used by SWT has worked prior to JDK 1.5 but no longer works. Unfortunately, the only reason it worked was a bug in AWT. The bug has been fixed and then for activation of the EmbeddedFrame there has been introduced another (correct) way, namely the following method in the sun.awt.EmbeddedFrame class: /** * Synthesize native message to activate or deactivate EmbeddedFrame * window depending on the value of parameter <code>b</code>. * Peers should override this method if they are to implement * this functionality. * @param b if <code>true</code>, activates the window; * otherwise, deactivates the window */ public void synthesizeWindowActivation(boolean b) Since JDK 1.5, in order to activate the EmbeddedFrame this method should be called (with the parameter set to "true") instead of dispatching the WINDOW_ACTIVATED & WINDOW_GAINED_FOCUS events. This method serves to activate the EmbeddedFrame on the native level. It correctly generates appropriate activation & focus Java events that are dispatched asynchronously. The testcase below reproduces the problem. When it's run with JDK 1.4 the button is focused when the shell is opened, with JDK 1.5 it's not. -------------------------------------------- import java.awt.Frame; import javax.swing.JButton; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SwtAwtBridge { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); shell.setSize(100, 100); Frame swingFrame = SWT_AWT.new_Frame(new Composite(shell, SWT.EMBEDDED)); JButton button = new JButton("button"); swingFrame.add(button); button.requestFocusInWindow(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } } --------------------------------------------

Files changed in fix:
bundles/org.eclipse.swt/Eclipse SWT AWT/win32/org/eclipse/swt/awt/SWT_AWT.java