[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [albireo-dev] Participating more naturally in SWT tab order

Hi Gordon,

> Then it sounds like the tabbing is working correctly for you, at least 
> from Albireo's point of view. To check this, if you bring up the 
> standard Eclipse Error Log view, and set the focus inside, you should 
> see the same behavior.

Yes, that's it. The Eclipse Error Log view features a traversal chain that
consists of:
  tab panel - 6x main window toolbar - tab header - 2x tab toolbar

> For me, under Gtk, I get dotted rectangles surrounding the toolbar items 
> as I tab over them. This is with the GNOME desktop.

And for me these dotted rectangles are not visible. Probably a different
Gtk theme in use than for you.

> > Also, while doing this and similar manipulations, I got an endless recursion:
> > 
> >         at java.awt.ContainerOrderFocusTraversalPolicy.getLastComponent(ContainerOrderFocusTraversalPolicy.java:366)
> >         at javax.swing.DefaultFocusManager.getLastComponent(DefaultFocusManager.java:119)
> >         at javax.swing.LegacyGlueFocusTraversalPolicy.getLastComponent(LegacyGlueFocusTraversalPolicy.java:124)
> >         at java.awt.ContainerOrderFocusTraversalPolicy.getLastComponent(ContainerOrderFocusTraversalPolicy.java:366)
> 
> This is almost certainly the same as this problem (part 1):
> 
> http://dev.eclipse.org/mhonarc/lists/albireo-dev/msg00183.html
> 
> It should be easily fixable by manually setting the focus traversal 
> policy to the correct default for Gtk. I've fixed this only on Windows 
> so far.

OK, I'm changing the workaround to be enabled on all platforms, but also
submitting a bug report to the people responsible for the
org.eclipse.ui.internal.handlers.WidgetMethodHandler.
  https://bugs.eclipse.org/bugs/show_bug.cgi?id=228890

I can now always reproduce the problem: Launch the sample views as an Eclipse
application. Open the text fields view and the Error Log view, so that the
Error Log view is visible and the text fields view is hidden. Close Eclipse.
Re-run Eclipse. Click on the text fields view. -> endless recursion

	at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(SortingFocusTraversalPolicy.java:438)
	at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(LayoutFocusTraversalPolicy.java:148)
	at javax.swing.DefaultFocusManager.getFirstComponent(DefaultFocusManager.java:99)
	at javax.swing.LegacyGlueFocusTraversalPolicy.getFirstComponent(LegacyGlueFocusTraversalPolicy.java:115)
	at javax.swing.LegacyGlueFocusTraversalPolicy.getDefaultComponent(LegacyGlueFocusTraversalPolicy.java:133)
	at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(SortingFocusTraversalPolicy.java:438)

Your fix is not enough on Gtk, because the LegacyGlueFocusTraversalPolicy
is installed as the *default* FocusTraversalPolicy in the KeyboardFocusManager
and therefore also gets applied to the JApplet subclass (SwingControl$9)
and possibly others. Also, on Gtk - at least after setting the default
focus traversal policy - the frame's focus traversal policy is an instance
of java.awt.DefaultFocusTraversalPolicy; I don't see a reason to replace it
with an instance of javax.swing.LayoutFocusTraversalPolicy. I'm applying this.
Works for me also on Windows. Let me know if it breaks something.

Bruno


Index: src/org/eclipse/albireo/core/SwingControl.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/SwingControl.java,v
retrieving revision 1.68
diff -c -3 -r1.68 SwingControl.java
*** src/org/eclipse/albireo/core/SwingControl.java      24 Apr 2008 20:34:54 -0000      1.68
--- src/org/eclipse/albireo/core/SwingControl.java      25 Apr 2008 16:53:50 -0000
***************
*** 17,22 ****
--- 17,23 ----
  import java.awt.EventQueue;
  import java.awt.FocusTraversalPolicy;
  import java.awt.Frame;
+ import java.awt.KeyboardFocusManager;
  import java.awt.event.ComponentAdapter;
  import java.awt.event.ComponentEvent;
  import java.util.ArrayList;
***************
*** 259,278 ****
          // especially necessary to avoid an AWT leak bug (Sun bug 6411042).
          EventQueue.invokeLater(new Runnable() {
              public void run() {
!                 if (Platform.isWin32()) {
!                     // If the client is using the now-obsolete javax.swing.DefaultFocusManager
!                     // class under Windows, the default focus traversal policy may be changed from
!                     // LayoutFocusTraversalPolicy (set by the L&F) to LegacyGlueFocusTraversalPolicy. 
!                     // The latter policy causes stack overflow errors when setting focus on a JApplet 
!                     // in an embedded frame, so we force the policy to LayoutFocusTraversalPolicy here 
!                     // and later when the JApplet is created. It is especially important to do this since
!                     // the Eclipse workbench code itself uses DefaultFocusManager (see 
!                     // org.eclipse.ui.internal.handlers.WidgetMethodHandler).
!                     // TODO: can this be queried from the L&F?
!                     // TODO: other platforms?
                      frame.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
!                 }
!                 
                  rootPaneContainer = addRootPaneContainer(frame);
                  initPopupMenuSupport(rootPaneContainer.getRootPane());
  
--- 260,283 ----
          // especially necessary to avoid an AWT leak bug (Sun bug 6411042).
          EventQueue.invokeLater(new Runnable() {
              public void run() {
!                 // If the client is using the now-obsolete javax.swing.DefaultFocusManager
!                 // class under Windows, the default focus traversal policy may be changed from
!                 // LayoutFocusTraversalPolicy (set by the L&F) to LegacyGlueFocusTraversalPolicy. 
!                 // The latter policy causes stack overflow errors when setting focus on a JApplet 
!                 // in an embedded frame, so we force the policy to LayoutFocusTraversalPolicy here 
!                 // and later when the JApplet is created. It is especially important to do this since
!                 // the Eclipse workbench code itself uses DefaultFocusManager (see 
!                 // org.eclipse.ui.internal.handlers.WidgetMethodHandler).
!                 // TODO: can this be queried from the L&F?
!                 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
!                 if (kfm.getDefaultFocusTraversalPolicy().getClass().getName()
!                     == "javax.swing.LegacyGlueFocusTraversalPolicy")
!                     kfm.setDefaultFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
!                 if (frame.getFocusTraversalPolicy() != null
!                     && frame.getFocusTraversalPolicy().getClass().getName()
!                        == "javax.swing.LegacyGlueFocusTraversalPolicy")
                      frame.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
! 
                  rootPaneContainer = addRootPaneContainer(frame);
                  initPopupMenuSupport(rootPaneContainer.getRootPane());