This patch fixes some things in JComponent and Component:
1. yesterday I got confused regarding the handling of the opaque
property wrt the accessibility method getAccessibleStateSet(). As it
turns out, this property is _not_ handled at all in
AccessibleAWTComponent, regardless of the value of the property. It's
only handled by the AccessibleJComponent.getAccessibleStateSet().
Probably that is because only in JComponent this property is a kind of
state that can change.

2. I implemented the remaining stubs in JComponent. These are all
methods that are left over from obsolete/deprecated APIs and only there
for compatibility. I implemented them using the newer APIs. For the
set/getNextFocusableComponent() methods I introduced a new helper class,
that maps this behaviour to a special FocusTraversPolicy.

2006-04-06  Roman Kennke  <[EMAIL PROTECTED]>

        * java/awt/Component.java
        (AccessibleAWTComponent.getAccessibleStateSet): Don't handle
opaque
        state here. This is only done in JComponent.
        * javax/swing/JComponent.java
        (AccessibleJComponent.getAccessibleStateSet): Handle opaque flag
        here.
        (getNextFocusableComponent): Implemented stub method.
        (grabFocus): Implemented stub method.
        (unregisterKeyboardAction): Implemented stub method.
        (setNextFocusableComponent): Implemented stub method.
        * javax/swing/CompatibilityFocusTraversalPolicy.java: New file.
        This is a helper class for providing compatibility with the
older
        Swing focus API.

/Roman

Index: java/awt/Component.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v
retrieving revision 1.111
diff -u -1 -0 -r1.111 Component.java
--- java/awt/Component.java	5 Apr 2006 10:31:26 -0000	1.111
+++ java/awt/Component.java	6 Apr 2006 10:10:00 -0000
@@ -5418,22 +5418,24 @@
      */
     public AccessibleStateSet getAccessibleStateSet()
     {
       AccessibleStateSet s = new AccessibleStateSet();
       if (Component.this.isEnabled())
         s.add(AccessibleState.ENABLED);
       if (isFocusable())
         s.add(AccessibleState.FOCUSABLE);
       if (isFocusOwner())
         s.add(AccessibleState.FOCUSED);
-      if (isOpaque())
-        s.add(AccessibleState.OPAQUE);
+      // Note: While the java.awt.Component has an 'opaque' property, it
+      // seems that it is not added to the accessible state set here, even
+      // if this property is true. However, it is handled for
+      // javax.swing.JComponent, so we add it there.
       if (Component.this.isShowing())
         s.add(AccessibleState.SHOWING);
       if (Component.this.isVisible())
         s.add(AccessibleState.VISIBLE);
       return s;
     }
 
     /**
      * Returns the parent of this component, if it is accessible.
      *
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.113
diff -u -1 -0 -r1.113 JComponent.java
--- javax/swing/JComponent.java	5 Apr 2006 21:45:36 -0000	1.113
+++ javax/swing/JComponent.java	6 Apr 2006 10:10:00 -0000
@@ -330,24 +330,28 @@
       return super.getAccessibleChild(i);
     }
 
     /**
      * Returns the accessible state set of this component.
      *
      * @return the accessible state set of this component
      */
     public AccessibleStateSet getAccessibleStateSet()
     {
-      // TODO: The only JComponent property that is (theoretically) handled
-      // here seems to be 'opaque'. However, we already handle this in
-      // AccessibleAWTComponent and do not need to handle it here too.
-      return super.getAccessibleStateSet();
+      // Note: While the java.awt.Component has an 'opaque' property, it
+      // seems that it is not added to the accessible state set there, even
+      // if this property is true. However, it is handled for JComponent, so
+      // we add it here.
+      AccessibleStateSet state = super.getAccessibleStateSet();
+      if (isOpaque())
+        state.add(AccessibleState.OPAQUE);
+      return state;
     }
 
     /**
      * Returns the localized name for this object. Generally this should
      * almost never return [EMAIL PROTECTED] Component#getName()} since that is not
      * a localized name. If the object is some kind of text component (like
      * a menu item), then the value of the object may be returned. Also, if
      * the object has a tooltip, the value of the tooltip may also be
      * appropriate.
      *
@@ -1386,21 +1390,26 @@
   /**
    * Return the value of the <code>nextFocusableComponent</code> property.
    *
    * @return The current value of the property, or <code>null</code>
    * if none has been set.
    * 
    * @deprecated See [EMAIL PROTECTED] java.awt.FocusTraversalPolicy}
    */
   public Component getNextFocusableComponent()
   {
-    return null;
+    Container focusRoot = this;
+    if (! this.isFocusCycleRoot())
+      focusRoot = getFocusCycleRootAncestor();
+
+    FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
+    return policy.getComponentAfter(focusRoot, this);
   }
 
   /**
    * Return the set of [EMAIL PROTECTED] KeyStroke} objects which are registered
    * to initiate actions on this component.
    *
    * @return An array of the registered keystrokes
    */
   public KeyStroke[] getRegisteredKeyStrokes()
   {
@@ -1580,21 +1589,21 @@
    * focus to the top level ancestor of this component. Only works on
    * displayable, focusable, visible components.</p>
    *
    * <p>This method should not be called by clients; it is intended for
    * focus implementations. Use [EMAIL PROTECTED] Component#requestFocus()} instead.</p>
    *
    * @see Component#requestFocus()
    */
   public void grabFocus()
   {
-    // TODO: Implement this properly.
+    requestFocus();
   }
 
   /**
    * Get the value of the [EMAIL PROTECTED] #doubleBuffered} property.
    *
    * @return The property's current value
    */
   public boolean isDoubleBuffered()
   {
     return doubleBuffered;
@@ -2568,21 +2577,34 @@
    * Remove a keyboard action registry.
    *
    * @param aKeyStroke The keystroke to unregister
    *
    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
    * @see #getConditionForKeyStroke
    * @see #resetKeyboardActions
    */
   public void unregisterKeyboardAction(KeyStroke aKeyStroke)
   {
-    // FIXME: Must be implemented.
+    ActionMap am = getActionMap();
+    // This loops through the conditions WHEN_FOCUSED,
+    // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT and WHEN_IN_FOCUSED_WINDOW.
+    for (int cond = 0; cond < 3; cond++)
+      {
+        InputMap im = getInputMap(cond);
+        if (im != null)
+          {
+            Object action = im.get(aKeyStroke);
+            if (action != null && am != null)
+              am.remove(action);
+            im.remove(aKeyStroke);
+          }
+      }
   }
 
 
   /**
    * Reset all keyboard action registries.
    *
    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
    * @see #unregisterKeyboardAction
    * @see #getConditionForKeyStroke
    */
@@ -2846,21 +2868,43 @@
    * Set the specified component to be the next component in the 
    * focus cycle, overriding the [EMAIL PROTECTED] FocusTraversalPolicy} for
    * this component.
    *
    * @param aComponent The component to set as the next focusable
    *
    * @deprecated Use FocusTraversalPolicy instead
    */
   public void setNextFocusableComponent(Component aComponent)
   {
-    // TODO: Implement this properly.
+    Container focusRoot = this;
+    if (! this.isFocusCycleRoot())
+      focusRoot = getFocusCycleRootAncestor();
+
+    FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
+    if (policy instanceof CompatibilityFocusTraversalPolicy)
+      {
+        policy = new CompatibilityFocusTraversalPolicy(policy);
+        focusRoot.setFocusTraversalPolicy(policy);
+      }
+    CompatibilityFocusTraversalPolicy p =
+      (CompatibilityFocusTraversalPolicy) policy;
+
+    Component old = getNextFocusableComponent();
+    if (old != null)
+      {
+        p.removeNextFocusableComponent(this, old);
+      }
+
+    if (aComponent != null)
+      {
+        p.addNextFocusableComponent(this, aComponent);
+      }
   }
 
   /**
    * Set the value of the [EMAIL PROTECTED] #requestFocusEnabled} property.
    *
    * @param e The new value of the property
    */
   public void setRequestFocusEnabled(boolean e)
   {
     requestFocusEnabled = e;
Index: javax/swing/CompatibilityFocusTraversalPolicy.java
===================================================================
RCS file: javax/swing/CompatibilityFocusTraversalPolicy.java
diff -N javax/swing/CompatibilityFocusTraversalPolicy.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/CompatibilityFocusTraversalPolicy.java	6 Apr 2006 10:10:00 -0000
@@ -0,0 +1,164 @@
+/* CompatibilityFocusTraversalPolicy.java -- Provides compatibility to old
+                                             focus API
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.FocusTraversalPolicy;
+import java.util.HashMap;
+
+/**
+ * Provides compatibility to the older focus API in
+ * [EMAIL PROTECTED] JComponent#setNextFocusableComponent(Component)}.
+ *
+ * @author Roman Kennke ([EMAIL PROTECTED])
+ */
+class CompatibilityFocusTraversalPolicy
+  extends FocusTraversalPolicy
+{
+
+  /**
+   * The focus traversal policy that has been installed on the focus cycle
+   * root before, and to which we fall back.
+   */
+  private FocusTraversalPolicy fallback;
+
+  /**
+   * Maps components to their next focused components.
+   */
+  private HashMap forward;
+
+  /**
+   * Maps components to their previous focused components.
+   */
+  private HashMap backward;
+
+  /**
+   * Creates a new CompatibilityFocusTraversalPolicy with the specified
+   * policy as fallback.
+   *
+   * @param p the fallback policy
+   */
+  CompatibilityFocusTraversalPolicy(FocusTraversalPolicy p)
+  {
+    fallback = p;
+    forward = new HashMap();
+    backward = new HashMap();
+  }
+
+  public Component getComponentAfter(Container root, Component current)
+  {
+    Component next = (Component) forward.get(current);
+    if (next == null && fallback != null)
+      next = fallback.getComponentAfter(root, current);
+    return next;
+  }
+
+  public Component getComponentBefore(Container root, Component current)
+  {
+    Component previous = (Component) backward.get(current);
+    if (previous == null && fallback != null)
+      previous = fallback.getComponentAfter(root, current);
+    return previous;
+  }
+
+  public Component getFirstComponent(Container root)
+  {
+    Component first = null;
+    if (fallback != null)
+      first = fallback.getFirstComponent(root);
+    return first;
+  }
+
+  public Component getLastComponent(Container root)
+  {
+    Component last = null;
+    if (fallback != null)
+      last = fallback.getLastComponent(root);
+    return last;
+  }
+
+  public Component getDefaultComponent(Container root)
+  {
+    Component def = null;
+    if (fallback != null)
+      def = fallback.getDefaultComponent(root);
+    return def;
+  }
+
+  /**
+   * Sets a next focused component for a specified component. This is called
+   * by [EMAIL PROTECTED] JComponent#setNextFocusableComponent(Component)}.
+   *
+   * @param current the current component
+   * @param next the next focused component
+   */
+  void setNextFocusableComponent(Component current, Component next)
+  {
+    forward.put(current, next);
+    backward.put(next, current);
+  }
+
+  /**
+   * Sets a next focused component for a specified component. This is called
+   * by [EMAIL PROTECTED] JComponent#setNextFocusableComponent(Component)}.
+   *
+   * @param current the current component
+   * @param next the next focused component
+   */
+  void addNextFocusableComponent(Component current, Component next)
+  {
+    forward.put(current, next);
+    backward.put(next, current);
+  }
+
+  /**
+   * Removes a focused component mapping. This is called
+   * by [EMAIL PROTECTED] JComponent#setNextFocusableComponent(Component)}.
+   *
+   * @param current the current component
+   * @param next the next focused component
+   */
+  void removeNextFocusableComponent(Component current, Component next)
+  {
+    forward.remove(current);
+    backward.remove(next);
+  }
+}

Reply via email to