Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[albireo-dev] Relaxed isFocusable() check

In the setFocus/forceFocus methods of SwingControl, we attempt to return a meaningful value when the underlying Swing component cannot take the focus. I've improved this check. Previously it only looked at the top level Swing component's isFocusable() method, but it really should look at all children. If any child is focuable, it should return true, and it should attempt to transfer focus.

See also: http://dev.eclipse.org/newslists/news.eclipse.technology.albireo/msg00080.html

### Eclipse Workspace Patch 1.0
#P org.eclipse.albireo.core
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.90
diff -u -r1.90 SwingControl.java
--- src/org/eclipse/albireo/core/SwingControl.java	16 Sep 2008 17:52:54 -0000	1.90
+++ src/org/eclipse/albireo/core/SwingControl.java	22 Sep 2008 19:07:17 -0000
@@ -1407,16 +1407,41 @@
      * @return the result of running the focus setter, or true if it was deferred
      */
     protected boolean handleFocusOperation(final RunnableWithResult focusSetter) {
-        // isFocusable() should be safe to call from the SWT thread. 
-        if ((swingComponent != null) && !swingComponent.isFocusable()) {
-            // Fail if the underlying swing component is not focusable
-            return false;
+        if (hasFocusableComponent(swingComponent)) {
+            focusSetter.run();
+            return ((Boolean)focusSetter.getResult()).booleanValue();
         } else {
-          focusSetter.run();
-          return ((Boolean)focusSetter.getResult()).booleanValue();
+            // Fail if no underlying swing component is not focusable
+            return false;
         }
     }
     
+    /**
+     * Looks for at least one focusable component in the containment hierarchy of
+     * the given component. The component itself is also checked. 
+     * 
+     * @param c the component
+     * @return true if the component is focusable or contains at least child that is focusable
+     */
+    protected boolean hasFocusableComponent(Component c) {
+        if (c == null) {
+            return false;
+        }
+        // isFocusable() should be safe to call from the SWT thread.
+        if (c.isFocusable()) {
+            return true;
+        }
+        if (c instanceof Container) {
+            Component[] children = ((Container)c).getComponents();
+            for (int i = 0; i < children.length; i++) {
+                if (hasFocusableComponent(children[i])) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private boolean superSetFocus() {
         return super.setFocus();
     }

Back to the top