I implemented the remaining missing pieces for the AccessibleJComponent,
so in theory accessibility for Swing should somewhat work now.
I came across some oddities, like AccessibleAWTContainer also having a
field accessibleContainerHandler, AccessibleAWTComponent having a field
accessibleAWTFocusHandler, which both seem to overlap with the
AccessibleJComponent fields. I suppose the AccessibleJComponent fields
were there first and are now left in place so that binary compatibility
is not affected. I added @specnotes all over the place.
Also, I reverted the getAccessibleStateSet() method to simply return
super. The only state handled that I attributed to JComponent is opaque,
I really didn't knew that java.awt.Component also has this property.
Since we already handle this in AccessibleAWTComponent, we do not need
to handle it here too.
2006-04-05 Roman Kennke <[EMAIL PROTECTED]>
* javax/swing/JComponent.java
(accessibleContext): Fixed API doc for this field.
(AccessibleJComponent.AccessibleFocusHandler): Fixed API docs.
(AccessibleJComponent.AccessibleFocusHandler.focusGained):
Implemented and added API docs.
(AccessibleJComponent.AccessibleFocusHandler.focusLost):
Implemented and added API docs.
(AccessibleJComponent.AccessibleContainerHandler): Fixed API docs.
(AccessibleJComponent.AccessibleContainerHandler.componentAdded):
Implemented and added API docs.
(AccessibleJComponent.AccessibleContainerHandler.componentRemoved):
Implemented and added API docs.
(AccessibleJComponent.accessibleContainerHandler): Added API docs.
(AccessibleJComponent.accessibleFocusHandler): Added API docs.
(AccessibleJComponent.addPropertyChangeListener): Added API docs.
(AccessibleJComponent.removePropertyChangeListener): Added API
docs.
(AccessibleJComponent.getAccessibleStateSet): Simply return
super here. Added comment about this.
/Roman
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.112
diff -u -1 -0 -r1.112 JComponent.java
--- javax/swing/JComponent.java 5 Apr 2006 18:56:04 -0000 1.112
+++ javax/swing/JComponent.java 5 Apr 2006 21:39:26 -0000
@@ -98,85 +98,170 @@
* implemented elsewhere.
*
* @author Ronald Veldema (rveldema&064;cs.vu.nl)
* @author Graydon Hoare (graydon&064;redhat.com)
*/
public abstract class JComponent extends Container implements Serializable
{
private static final long serialVersionUID = -7908749299918704233L;
/**
- * Accessibility support is currently missing.
+ * The accessible context of this <code>JComponent</code>.
*/
protected AccessibleContext accessibleContext;
/**
* Basic accessibility support for <code>JComponent</code> derived
* widgets.
*/
public abstract class AccessibleJComponent
extends AccessibleAWTContainer
implements AccessibleExtendedComponent
{
/**
- * Accessibility support for <code>JComponent</code>'s focus handler.
+ * Receives notification if the focus on the JComponent changes and
+ * fires appropriate PropertyChangeEvents to listeners registered with
+ * the AccessibleJComponent.
*/
protected class AccessibleFocusHandler
implements FocusListener
{
+ /**
+ * Creates a new AccessibleFocusHandler.
+ */
protected AccessibleFocusHandler()
{
- // TODO: Implement this properly.
+ // Nothing to do here.
}
+
+ /**
+ * Receives notification when the JComponent gained focus and fires
+ * a PropertyChangeEvent to listeners registered on the
+ * AccessibleJComponent with a property name of
+ * [EMAIL PROTECTED] AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and a new value
+ * of [EMAIL PROTECTED] AccessibleState#FOCUSED}.
+ */
public void focusGained(FocusEvent event)
{
- // TODO: Implement this properly.
+ AccessibleJComponent.this.firePropertyChange
+ (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+ AccessibleState.FOCUSED);
}
+
+ /**
+ * Receives notification when the JComponent lost focus and fires
+ * a PropertyChangeEvent to listeners registered on the
+ * AccessibleJComponent with a property name of
+ * [EMAIL PROTECTED] AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and an old value
+ * of [EMAIL PROTECTED] AccessibleState#FOCUSED}.
+ */
public void focusLost(FocusEvent valevent)
{
- // TODO: Implement this properly.
+ AccessibleJComponent.this.firePropertyChange
+ (AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ AccessibleState.FOCUSED, null);
}
}
/**
- * Accessibility support for <code>JComponent</code>'s container handler.
+ * Receives notification if there are child components are added or removed
+ * from the JComponent and fires appropriate PropertyChangeEvents to
+ * interested listeners on the AccessibleJComponent.
*/
protected class AccessibleContainerHandler
implements ContainerListener
{
+ /**
+ * Creates a new AccessibleContainerHandler.
+ */
protected AccessibleContainerHandler()
{
- // TODO: Implement this properly.
+ // Nothing to do here.
}
+
+ /**
+ * Receives notification when a child component is added to the
+ * JComponent and fires a PropertyChangeEvent on listeners registered
+ * with the AccessibleJComponent with a property name of
+ * [EMAIL PROTECTED] AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
+ *
+ * @param event the container event
+ */
public void componentAdded(ContainerEvent event)
{
- // TODO: Implement this properly.
+ Component c = event.getChild();
+ if (c != null && c instanceof Accessible)
+ {
+ AccessibleContext childCtx = c.getAccessibleContext();
+ AccessibleJComponent.this.firePropertyChange
+ (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, null, childCtx);
+ }
}
- public void componentRemoved(ContainerEvent valevent)
+
+ /**
+ * Receives notification when a child component is removed from the
+ * JComponent and fires a PropertyChangeEvent on listeners registered
+ * with the AccessibleJComponent with a property name of
+ * [EMAIL PROTECTED] AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
+ *
+ * @param event the container event
+ */
+ public void componentRemoved(ContainerEvent event)
{
- // TODO: Implement this properly.
+ Component c = event.getChild();
+ if (c != null && c instanceof Accessible)
+ {
+ AccessibleContext childCtx = c.getAccessibleContext();
+ AccessibleJComponent.this.firePropertyChange
+ (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, childCtx, null);
+ }
}
}
private static final long serialVersionUID = -7047089700479897799L;
-
+
+ /**
+ * Receives notification when a child component is added to the
+ * JComponent and fires a PropertyChangeEvent on listeners registered
+ * with the AccessibleJComponent.
+ *
+ * @specnote AccessibleAWTContainer has a protected field with the same
+ * name. Looks like a bug or nasty misdesign to me.
+ */
protected ContainerListener accessibleContainerHandler;
+
+ /**
+ * Receives notification if the focus on the JComponent changes and
+ * fires appropriate PropertyChangeEvents to listeners registered with
+ * the AccessibleJComponent.
+ *
+ * @specnote AccessibleAWTComponent has a protected field
+ * accessibleAWTFocusHandler. Looks like a bug or nasty misdesign
+ * to me.
+ */
protected FocusListener accessibleFocusHandler;
+ /**
+ * Creates a new AccessibleJComponent.
+ */
protected AccessibleJComponent()
{
- // nothing to do here
+ // Nothing to do here.
}
/**
* Adds a property change listener to the list of registered listeners.
*
+ * This sets up the [EMAIL PROTECTED] #accessibleContainerHandler} and
+ * [EMAIL PROTECTED] #accessibleFocusHandler} fields and calls
+ * <code>super.addPropertyChangeListener(listener)</code>.
+ *
* @param listener the listener to add
*/
public void addPropertyChangeListener(PropertyChangeListener listener)
{
// Tests seem to indicate that this method also sets up the other two
// handlers.
if (accessibleContainerHandler == null)
{
accessibleContainerHandler = new AccessibleContainerHandler();
addContainerListener(accessibleContainerHandler);
@@ -185,20 +270,24 @@
{
accessibleFocusHandler = new AccessibleFocusHandler();
addFocusListener(accessibleFocusHandler);
}
super.addPropertyChangeListener(listener);
}
/**
* Removes a property change listener from the list of registered listeners.
*
+ * This uninstalls the [EMAIL PROTECTED] #accessibleContainerHandler} and
+ * [EMAIL PROTECTED] #accessibleFocusHandler} fields and calls
+ * <code>super.removePropertyChangeListener(listener)</code>.
+ *
* @param listener the listener to remove
*/
public void removePropertyChangeListener(PropertyChangeListener listener)
{
// Tests seem to indicate that this method also resets the other two
// handlers.
if (accessibleContainerHandler != null)
{
removeContainerListener(accessibleContainerHandler);
accessibleContainerHandler = null;
@@ -241,26 +330,24 @@
return super.getAccessibleChild(i);
}
/**
* Returns the accessible state set of this component.
*
* @return the accessible state set of this component
*/
public AccessibleStateSet getAccessibleStateSet()
{
- AccessibleStateSet state = super.getAccessibleStateSet();
- if (isOpaque())
- {
- state.add(AccessibleState.OPAQUE);
- }
- return state;
+ // 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();
}
/**
* 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.
*