Community
Participate
Working Groups
If an SWT and Swing component is in the same window the SWT component will not give up focus to the Swing component. The following code creates a window with two components. The top component is a Swing JTextField component and the bottom component is a SWT Text component. To see the problem do the following: 1. Click in the top component (the lightweight). It should have keyboard focus. Type a few characters to verify. 2. Click in the bottom component (the heavyweight). It should have keyboard focus. Type a few characters to verify. 3. Now click in the top component. It will not get focus. 4. Switch to another application, then switch back to this test frame. At this point the Swing component will have keyboard focus. 5. Click in the bottom component. It will have focus. 6. Clicking in the top component will not give it focus. Sometimes the top component gets into a wierd state where it displays the text cursor, but any characters typed are delivered to the bottom component. The above behavior was seen with the 1.3.1_03 JRE and the swt-win32-2026.dll version of SWT and the M5 release of SWT running on Windows 2000. This code does not exhibit focus problems when running on the 1.4.0 JRE. ----------------------------------------- /* * Demonstrates a focus bug between SWT and Swing components. * To compile: Include swt.jar in the classpath. * To run: Include -Djava.library.path=<path to swt-win32-XXXX.dll> on the command line */ import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Panel; import javax.swing.*; import org.eclipse.swt.SWT; import org.eclipse.swt.internal.awt.win32.SWT_AWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class BugTest { private DisplayThread displayThread; public BugTest() { displayThread = new DisplayThread(); displayThread.start(); JFrame frame = new JFrame(); frame.setSize( 500, 500 ); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.getContentPane().setLayout( new BoxLayout( frame.getContentPane(), BoxLayout.Y_AXIS ) ); frame.setVisible( true ); frame.getContentPane().add( createLightweight() ); frame.getContentPane().add( createHeavyweight() ); frame.validate(); } private JPanel createLightweight() { JPanel panel = new JPanel(); panel.setLayout( new BorderLayout() ); panel.add( new JTextField( 30 ), BorderLayout.CENTER ); return panel; } private Panel createHeavyweight() { return new MyPanel(); } public static void main(String[] args) { new BugTest(); } private class MyPanel extends Panel { private Canvas canvas; public MyPanel() { canvas = new Canvas(); setLayout( new BorderLayout() ); add( canvas, BorderLayout.CENTER ); } public void addNotify() { super.addNotify(); displayThread.getDisplay().syncExec( new Runnable() { public void run() { Shell shell = SWT_AWT.new_Shell( displayThread.getDisplay(), canvas ); shell.setLayout( new FillLayout() ); Text text = new Text( shell, SWT.MULTI ); } } ); } } private class DisplayThread extends Thread { private Display display; public void run() { display = Display.getDefault(); swtEventLoop(); } private void swtEventLoop() { while( true ) { if (!display.readAndDispatch()) { display.sleep(); } } } public Display getDisplay() { return display; } } }
Matt, In the newsgroup you said you saw this comment on the sun web site: "Prior to Java 2 Standard Edition, JDK 1.4, the AWT focus subsystem was inadequate. It suffered from major design and API problems, as well as over a hundred open bugs. Many of these bugs were caused by platform inconsistencies, or incompatibilities between the native focus system for heavyweights and the Java focus system for lightweights." http://java.sun.com/j2se/1.4/docs/api/java/awt/doc-files/FocusSpec.html I just want to capture this info here as part of the investigation.
We need to have an indepth look at the SWT/AWT integration after R2.0.
Post 2.0. Re-opening bug reports for review.
Still happens in 2.1 RC1.
Is this still a problem in the latest?
Yes, this is still a problem in latest. Note that it only happens with JDK1.3.1 and when embedding SWT in AWT (not the other way).
I ran into this same issue with Java 7 and Java 8. My workaround is to attach an AWT focus event listener and disable the SWT component when a Swing component gains focus. Here is the relevant code stub: private class FocusListener implements AWTEventListener { @Override public void eventDispatched(AWTEvent e) { boolean focus = false; if (e.getSource() instanceof Component) { focus = isAncestorOf((Component) e.getSource()); } display.asyncExec(new Runnable() { @Override public void run() { shell.setEnabled(focus); if (focus) { frame.setFocus(); } } }); } } Toolkit.getDefaultToolkit().addAWTEventListener( focusListener, AWTEvent.FOCUS_EVENT_MASK);
could you show the implementation of the method isAncestorOf((Component) e.getSource());
(In reply to Alessandro D\\\'Ottavio from comment #8) > could you show the implementation of the method > > > isAncestorOf((Component) e.getSource()); It's provided by AWT: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/awt/Container.java#Container.isAncestorOf%28java.awt.Component%29
We have the same problem with SWT components when trying to upgrade our Swing application from Java 6 to Java 8. The workaround suggested above did solve the focus issue, but causes some other issues with clicking on the SWT component (we sometimes had to click twice to get the cursor on the correct position in the SWT component, for instance when embedding the IE browser). We found another workaround for the problem though by adding an SWT FocusListener to the SWT component. If the SWT component gets the focus, we clear the AWT focusowner. For instance, in your example, add the following right after creating the Text component: text.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); } @Override public void focusLost(FocusEvent e) { } }); -- Maarten
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.