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);
+ }
+}