." This
can help an assistive technologies tailor themselves for your
application. For example, an assistive technology for the blind user
could be designed to navigate the HTML tags of a web document.
[127]5.4 Changing Data Models and Cell Renderers
The root component class is called JComponent and is a descendant of
the AWT container class. JComponent is the root class of almost all
JFC classes.
The design of each component is based on the Model-View-Controller
(MVC) architecture. Each component is broken into three parts:
* Model or "data" portion of the component.
* User Interface or "look and feel" portion, also called the view.
* Controller portion, which manipulates the components.
Implementation of the Accessibility API is triggered from the "data
portion" of each JFC component. This lets you implement an accessible
application without affecting its "look and feel."
When developing your application using the JFC, it is important that
you avoid modifying or replacing the "data model portion" of each
component with your own. You run the risk of improperly implementing
methods that are required to support the interfaces and this could
break the accessibility features of the component.
Another JFC concept is a cell renderer. A cell renderer is an
interface that a JFC component uses to define a component drawing
object within a list of elements. For example, the JFC uses
ListCellRenderers for JList elements and TableCellRenderers for JTable
elements. For a given cell renderer, a method is provided to return a
component configured for a given element, like
getListCellRendererComponent in the JList component.
If you change the cell renderer for a JFC component, make sure it
implements Accessible. If you implement your cell renderer on an
existing JFC component, you can configure your cell renderer for the
given element and reuse an already accessible component. An example of
this is how JList uses JLabel to render its children.
[128]5.5 Creating New Components Based on the JFC
If you need to build completely new components, use JComponent because
you pick up accessibility information and methods from its internal
abstract class AccessibleJComponent. AccessibleJComponent, in fact
implements [129]AccessibleComponent, see section 6.2.1.6..
To complete the implementation of the Accessibility API on your
JComponent, follow the guidelines in [130]section 6.0 The
Accessibility API.
[131]5.6 Requesting the Focus
There are a number of ways to request the focus in the JFC. The
standard way is to have a particular component execute the
java.awt.Component requestFocus method. In most cases, this is done
automatically for you in Swing by implementing the [132]Keyboard
Usability Issues, see section 6.3.5..
Swing might not automatically request the focus when you give your
Java application the focus by activating your window. This occurs when
you are running another application and you click on your Java
application with the mouse, or you use Alt+F6 to switch to your
window. When this happens, your application becomes "active", but does
not necessarily receive the focus. Correct this by creating a "default
focus" of your choosing. Two methods of achieving this are as follows:
Using the Window Activation Trigger to Set the Focus:
JFrame jf = new JFrame(); //Create a Frame
JButton myButton = new JButton(); //Create a JButton Component
//(could use a different component)
//Add the button the root pane
jf.getRootPane().add(myButtton);
// Add a Window listener to the JFrame that requests the button to have focus
// when the window is activated
jf.addWindowListener(new java.awt.event.WindowListener() {
void windowActivate() {
myButton.requestFocus(); //Note: Do this if focus
// has never been set before in your window
.
// Swing remembers the last focus set.
}
...
}
jf.show(); // Show the Window
Using the javax.swing.JRootPane setDefaultButton Method:
If you want a JButton to have the default focus in a window, you can
use the JRootPane component of any JFrame to set the focus to a
default button found in the JRootPane as follows:
JFrame jf = new JFrame(); //Create a frame
JButton myButton = new JButton();
//Create a JButton Component
jf.getRootPane().add(myButtton); // Add the button the root Pane
jf.getRootPane().setDefaultButton(myButtton); // Give the button the default fo
cus
jf.show(); // Show the window
[133]5.7 Providing an Accessible Layout
Developers typically add components to their application by
considering only the visual layout, and not the logical layout that a
blind user or asssistive technology reads. For example, in most cases,
you would not want your menu bar to be read last. Most component
libraries today do not allow you, the developer, to define the logical
ordering.
Until a better solution is devised, we recommend that when adding
components to containers, add them in the logical order as they should
be read on the screen. For example, if you are using an AWT border
layout, you could add components as follows:
public class BorderTest extends Frame implements Accessible{
public BorderTest () {
AccessiblePanel p = new AccessiblePanel();
p.setLayout(new BorderLayout();
p.add(new MyAccessibleButton("Left");
p.add(new MyAcessibleButton("Bottom");
p.add(new MyAcessibleButton("Right");
p.add(new MyAcessibleButton("Top");
add("North", p);
}
AccessibleContext getAccesibleContext() {
...
}
}
Child enumeration in Java enumerates the children in the order that
you added them. By merely changing the order in which you add the
components, you can enable the assistive technology to read the
components in the appropriate order, as shown in the following sample
code, and still accomplish the same visual effect:
p.add(new MyAcessibleButton("Top");
p.add(new MyAccessibleButton("Left");
p.add(new MyAcessibleButton("Right");
p.add(new MyAcessibleButton("Bottom");
[134]5.8 Preparing for Future JFC Accessibility Features
One feature not available in the first Java Accessibility API is
support for tables. An AccessibleTable interface is now under review.
Its first implementation will be on JTable. If possible, it is
recommended that when using tables in your application, you use the
JTable class provided in the JFC. When the AccessibleTable interface
is implemented, your application should be able to pick up the table
accessibility information.
Another Accessibility API extension being reviewed is an
AccessibleDocument interface for advanced dyslexic and mobility
impaired access. Watch the IBM and Sun web sites for announcements
about these interfaces.
[135]6.0 The Accessibility API
The Java Accessibility API is a set of interfaces and classes designed
by the Sun Microsystems Accessibility Group, IBM Special Needs
Systems, Trace Research and Development Center of the University of
Wisconsin at Madison, and other leading accessibility organizations.
The Java Accessibility API defines a common signature, which can be
implemented on application components, giving them a known interface
to allow assistive technologies to extract the accessibility
information from the application.
The Java Accessibility API is shipped with JFC and can be found in the
javax.accessibility package. JFC runs with the latest JDK 1.1.x. The
Java Accessibility API is now integrated into JDK 1.2.
[136]6.1 Interface Accessible
This section covers what a Java interface is and how you use the
interface to give objects an accessible signature.
[137]6.1.1 Interfaces
For those new to Java, an interface is a defined signature of methods
and properties that can be implemented by a particular class. As a
developer, if you were to "implement" the interface on your particular
class, you would need to provide all the methods and properties as
defined by the signature. Failure to meet the interface specification
would result in compilation errors.
In Java, an assistive technology can examine if an object is an
instance of a particular interface using the instanceof operator. The
first interface we will describe tells us whether an object has
implemented the basic Accessibility API.
[138]6.1.2 Using Interface Accessible
Accessible is an interface that you need to apply to your class file
to let assistive technologies know if you have implemented the
Accessibility API. The following Java code example shows you how to
implement Accessible on your own custom component.
import java.awt;
import javax.accessibility;
class MyButton implements Accessible extends Component{
AccessibleContext getAccessibleContext() {
...
}
}
Figure 4.0 Implementation of Accessible
The Accessible interface provides a method that returns the
AccessibleContext. The AccessibleContext provides the most basic
accessibility information needed for any component.
The object that getAccessibleContext() returns also implements more
detailed accessibility information based on the role of the GUI class
being used. Some of the methods that AccessibleContext defines, return
a null value because they really do not apply. For example, there is
no reason to implement the AccessibleText interface on a scroll bar.
One way to maintain the AccessibleContext is by keeping an internal
class inside your GUI class file, which keeps track of the
accessibility information. When asked to provide the
AccessibleContext, you simply provide the reference to your internal
AccessibleContext.
[139]6.2 AccessibleContext
AccessibleContext is an abstract class that must be maintained by each
GUI object making up your program. It contains much of the
accessibility information. Table 3.1 shows the methods
AccessibleContext supports and their descriptions.
Method Description
addPropertyChangeListener(PropertyChangeListener) Adds a
PropertyChangeListener to the listener list.
firePropertyChange(String property, Object oldValue, Object newValue)
Supports reporting bound property changes.
getAccessibleAction() Gets the AccessibleAction associated with this
object that supports one or more actions.
getAccessibleChild(int) Returns the specified Accessible child of the
object.
getAccessibleChildrenCount() Returns the number of Accessible children
of the object.
getAccessibleComponent() Gets the AccessibleComponent associated with
this object.
getAccessibleDescription() Gets the AccessibleDescription property of
this object.
getAccessibleIndexInParent() Gets the 0-based index of this object in
its accessible parent.
getAccessibleName() Gets the AccessibleName property of this object.
getAccessibleParent() Gets the AccessibleParent of this object.
getAccessibleRole() Get the role of this object.
getAccessibleSelection() Gets the AccessibleSelection associated with
this object.
getAccessibleStateSet() Get the state set of this object.
getAccessibleText() Gets the AccessibleText associated with this
Component. Note: If this text should also include hypertext links,
this method should return an AccessibleHypertext object.
getAccessibleValue() Gets the AccessibleValue associated with this
object.
getLocale() Gets the locale of the component.
removePropertyChangeListener(PropertyChangeListener listener) Removes
a PropertyChangeListener from the listener list.
setAccessibleDescription(String description) Sets the accessible
description of this object.
setAccessibleName(String name) Sets the localized accessible name of
this object.
setAccessibleParent(Accessible parent) Sets the accessible Parent of
this object. Table 3.1 AccessibleContext Abstract Class Methods
Assistive technologies can easily use AccessibleContext. For example,
by querying AccessibleContext, an assistive technology program can
know about and announce changes in a text field.
Section 6.2 provides information to help you implement
AccessibleContext in your library. The following topics are covered:
* [140]6.2.1 Basic Accessible Information
+ [141]6.2.1.1 AccessibleName
+ [142]6.2.1.2 AccessibleDescription
+ [143]6.2.1.3 AccessibleValue
+ [144]6.2.1.4 Locale
+ [145]6.2.1.5 AccessibleSelection
+ [146]6.2.1.6 AccessibleComponent
+ [147]6.2.1.7 AccessibleText
* [148]6.2.2 Parent/Child Information
+ [149]6.2.2.1 getAccessibleChild(n)
+ [150]6.2.2.2 getAccessibleChildCount()
+ [151]6.2.2.3 getAccessibleParent()
+ [152]6.2.2.4 getAccessibleIndexInParent()
* [153]6.2.3 Role and State Information
+ [154]6.2.3.1 AccessibleRole
+ [155]6.2.3.2 AccessibleState
* [156]6.2.4 Property Change Notification
* [157]6.2.5 National Language Information
+ [158]6.2.5.1 AccessibleBundle
+ [159]6.2.5.2 AccessibleResourceBundle
* [160]6.2.6 AccessibleAction
* [161]6.2.7 Miscellaneous Information
+ [162]6.2.7.1 AccessibleHypertext
+ [163]6.2.7.2 AccessibleHyperlink
[164]6.2.1 Basic Accessible Information
This section describes:
* AccessibleName
* AccessibleDescription
* AccessibleValue
* Locale
* AccessibleSelection
* AccessibleComponent
* AccessibleText
[165]6.2.1.1 AccessibleName
AccessibleName is simply the name of the object.
Here are some general rules to follow for setting the AccessibleName:
* As a general default, when creating your accessible Component, the
getAccessibleName method should return the text that appears on
the screen for simple classes. Examples of these simple classes
are labels, push buttons, check boxes, menu items, simple tab pane
entries, and spin buttons. If someone else will reuse this
component, you should allow setAccessibleName to override the
default.
* For complex classes that contain a collection of components
(children), such as list boxes, tab panes, combo boxes, menus, and
so on, you can return null, unless the application developer
explicitly uses the setAccessibleName method. The application
developer might have an explicit function for your component and
would need to set the name. For example, the developer might
configure your combo box to contain the months of the year, in
which case, the developer would set the AccessibleName to months.
* When you change the AccessibleName, be sure to fire the
ACCESSIBLE_NAME_PROPERTY as described in [166]section 6.2.4
Property Change Notification
[167]6.2.1.2 AccessibleDescription
AccessibleDescription is a text description of an object's purpose.
For example, if you had a table in your application containing your
current month's categorized cash flow, you should provide a text
description using AccessibleDescription.
To write a class file that is accessible, follow these rules:
* As a default, if your GUI objects include the notion of tooltips
and you can access the tooltip text, return the tool tip if the
application has not set up an accessible description. Note: Swing
components do this for you.
* Allow an application developer, using your class file, to replace
your default AccessibleDescription using the
setAccessibleDescription method.
* When you change the AccessibleDescription, be sure to fire the
ACCESSIBLE_DESCRIPTION_PROPERTY as described in [168]section 6.2.4
Property Change Notification.
* Keep the description short.
* Set the description based on locale.
If you need to use an existing Accessible class file to build an
application, and the default accessible description does not
accurately describe the function of the Accessible object, set the
accessible description in that class file.
[169]6.2.1.3 AccessibleValue
Use AccessibleValue only for a specific set of object types, that
provide a range of values and a current setting. Otherwise, return
null for this value.
Scroll bars, sliders, and progress bars, where the current value needs
to be acquired, are examples of objects needing an AccessibleValue
setting.
AccessibleValue supports the methods in Table 5.0.
Method Description
getCurrentAccessibleValue() Gets the value of this object as a
java.lang.Number.
getMaximumAccessibleValue() Gets the maximum value of this object as a
java.lang.Number.
getMinimumAccessibleValue() Gets the minimum value of this object as a
java.lang.Number.
setCurrentAccessibleValue(Number) Sets the current value of this
object as a java.lang.Number. Table 5.0 AccessibleValue Interface
Methods
Important:
Whenever the current accessible value changes, you need to fire the
ACCESSIBLE_VALUE_CHANGE property change in the AccessibleContext. In
a progress bar, this happens when the progress bar increases its
current value. For more information about firing this property change,
see [170]section 6.2.4 Property Change Notification.
[171]6.2.1.4 Locale
This is the current locale for which your component was written. See
the JDK for a more detailed description. Low-vision assistive
technology uses this information to determine how to speak your
application. When you extend either the AWT Component class or
JComponent, to make your custom Component, you can return the Locale
in AccessibleContext using the getLocale method in java.awt.Component.
[172]6.2.1.5 AccessibleSelection
AccessibleSelection is a collection of the selected accessible
children for your object. AccessibleSelection maintains an internal
vector of selected items. The collection is referenced by an index
from 0 to the n-1 selection. The n-1 selection is the last selected
item and is where the user would have the current input focused. For
example, if your object is a list box, this would maintain the
collection of currently selected entries as proxied by your list box.
AccessibleSelection is an extremely important feature when supporting
the Accessibility API. It allows assisitve technology to tell the user
what is currently selected. AccessibleSelection would be applied to
lists, menus, the list in a combo box, selected minimized windows
inside a Desktop Manager window, and so on.
AccessibleSelection supports the methods listed in Table 6.0.
Method Description
addAccessibleSelection(int) Adds the selected item in the object to
the object's selection.
clearAccessibleSelection() Clears the selection in the object, so that
nothing in the object is selected.
getAccessibleSelection(int) Returns an Accessible object representing
the selected item in the object.
getAccessibleSelectionCount() Returns the number of items currently
selected.
isAccessibleChildSelected(int) Returns true if the current child of
this object is selected. Otherwise, returns False.
removeAccessibleSelection(int) Removes the selected item in the object
from the object's selection.
selectAllAccessibleSelection() Causes every selected item in the
object to be selected if the object supports multiple selections.
Table 6.0 AccessibleSelection Interface Methods
Important:
When changes occur in the AccessibleSelection, you need to fire the
ACCESSIBLE_SELECTION_PROPERTY property change event in the
AccessibleContext.
For non-AccessibleText components, you also need to fire an
[173]ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY property change event when
the current ACTIVE child changes. This allows an assistive technology
to process multiple selected items while keeping track of the current
active selected item. For more information about firing this property
change, see [174]section 6.2.4 Property Change Notification.
[175]6.2.1.6 AccessibleComponent
AccessibleComponent is the accessible JDK component associated with
this accessible object. AccessibleComponent defines a standard
interface for assistive technologies to directly interact with an
object's associated component. It provides a framework for modifying
and querying standard component settings as well as asking questions
about a component's children.
AccessibleComponent applies to objects that have an associated
component, like the base components for a given GUI framework. An
example is the JFC JComponent class.
AccessibleComponent supports the methods listed in Table 7.0.
Method Description
addFocusListener(FocusListener) Adds the specified focus listener to
receive focus events from this component.
contains(Point) Checks whether the specified point is within this
object's bounds (the point's x and y coordinates are defined to be
relative to the coordinate system of the object).
getAccessibleAt(Point) Returns the Accessible child, if one exists,
contained at the local coordinate Point.
getBackground() Gets the background color.
getBounds() Get the object's bounds as a Rectangle object.
getCursor() Gets the Mouse Cursor.
getFont() Gets the Font.
getFontMetrics(Font) Gets the FontMetrics.
getForeground() Gets the foreground color.
getLocation() Gets the object's location relative to the parent as a
point specifying the object's top-left corner in the screen's
coordinate space.
getLocationOnScreen() Returns the object's Point location on the
screen.
getSize() Returns the object's size as a Dimension object.
isEnabled() Determines if the object is enabled.
isFocusTraversable() Returns whether this object can accept focus or
not.
isShowing() Determines if the component is showing.
isVisible() Determines if the component is visible.
removeFocusListener(FocusListener) Removes the specified focus
listener so it no longer receives focus events from this component.
requestFocus() Requests focus for this object.
setBackground(Color) Sets the background color.
setBounds(Rectangle) Sets the object's bounds as a Rectangle object.
setCursor(Cursor) Sets the Mouse Cursor.
setEnabled(boolean) Sets the enabled state.
setFont(Font) Sets the Font.
setForeground(Color) Sets the foreground color.
setLocation(Point) Sets the object's location relative to the parent.
setSize(Dimension) Resizes the object so that it has width and height.
setVisible(boolean) Sets the visible state. Table 7.0
AccessibleComponent Interface Methods
When you are programming the AccessibleContext, you will find that you
can retrieve much of the AccessibleComponent information directly from
the actual associated JDK awt.Component and JFC base
javax.swing.JComponent class. In the case of JFC, the base JComponent
class has an internal abstract class called AccessibleJComponent.
AccessibleJComponent has many of the methods needed to support
AccessibleComponent because the information can be acquired directly
from JComponent.
The AccessibleComponent interface is taken from awt.Component, not
javax.swing.JComponent. Therefore, the code in AccessibleJComponent
could be trivially placed in a non-JFC component, which extends
awt.Component to help create a custom, non-JFC accessible component.
The code snippets in Figure 8.0 appear in JComponent.java
Class JComponent {
protected AccessibleContext accessibleContext = null;
/**
* Get the AccessibleContext associated with this
* JComponent
*
* @return the AccessibleContext of this JComponent
*/
public AccessibleContext getAccessibleContext() {
return accessibleContext;
}
public abstract class AccessibleJComponent extends
AccessibleContext
implements Serializable, AccessibleComponent {
/**
* Get the AccessibleComponent associated with
* this object if one exists. Otherwise return
* null.
**/
public AccessibleComponent
getAccessibleComponent() {
return this;
}
/**
* Get the Font of this object.
*
* @return the Font,if supported, for the object;
* otherwise, null
*/
public Font getFont() {
return JComponent.this.getFont();
}
/**
* Set the Font of this object.
*
* @param f the new Font for the object
*/
public void setFont(Font f) {
JComponent.this.setFont(f);
}
/**
* Set the enabled state of the object.
*
* @param b if true, enables this object;
* otherwise, disables it
*/
public void setEnabled(boolean b) {
boolean old = JComponent.this.isEnabled();
JComponent.this.setEnabled(b);
if (b != old) {
if (accessibleContext != null) {
if (b) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.ENABLED);
} else {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.ENABLED, null);
}
}
}
}
public String getAccessibleDescription() {
if (accessibleDescription != null) {
return accessibleDescription;
} else {
try {
String ttt = getToolTipText(null);
if (ttt != null) {
return ttt;
}
} catch (Exception e) {
}
}
return null;
}
.
.
.
}
}
Figure 8.0 Example Code found in JFC's JComponent for Supporting
AccessibleComponent Information
The sample code in Figure 9.0 demonstrates the structure for building
an accessible component when using the JFC JComponent as a base.
Because the internal JComponent class, AccessibleJComponent, extends
AccessibleContext, you automatically get the AccessibleComponent
methods.
class MyButton extends JComponent implements Accessible{
String ButtonText;
AccessibleContext GetAccessibleContext() {
If accessibleContext != null
AccessibleContext == new MyAccessibleComponent();
}
class MyAccessibleButton extends AccessibleJComponent() {
String AccessibleName();
.
.
.
getAccessibleName() {
if (AccessibileName == null)
return ButtonText;
else
return AccessibleName;
}
}
}
Figure 9.0 Sample Code Demonstrating the Use of JComponent to Support
Accessible Component
Although we have selected to show JComponent as the foundation for
building an accessible component, you can also use the JDK Component
class. Many of the methods such as getFont in AccessibleComponent can
be acquired from java.awt.Component.
Important:
When building applications using JFC, it is recommended that you start
from JComponent or another existing JFC component to build your new,
custom Accessible component. When building non-JFC applications you
should start by building off the JDK Component class or a descendant
of it.
[176]6.2.1.7 AccessibleText
AccessibleText is used for providing detailed access to complex and
editable text documents and text fields. Examples of this are text
edit fields, text areas, WYSIWYG web browser and word processing
client areas, and mail program client areas. These areas often involve
the use of a caret for entering text when they are in an editable
state. AccessibleContext should return null for AccessibleText in the
case of scroll bars, check boxes, and so on.
AccessibleText interface (Table 10) provides a mechanism for assistive
technologies to gain access to documents by defining a
character-indexed mechanism for traversing documents in your program.
The predecessors of the Accessibility API relied on an Off-Screen
model (text-database reconstruction) of the desktop to provide access
to program documents. This was unreliable and often the biggest causes
for delay in providing access to a new GUI-based windowing system. The
AccessibleText approach is truly state-of-the-art in access technology
and it is one that facilitates multi-modal access to applications by
mainstream users.
Method Description
getAfterIndex(int part, int index) Returns the String after a given
index based on the part defined in 6.2.1.7.3.
getAtIndex(int part, int index) Returns the String at a given index
based on the part defined in 6.2.1.7.3.
getBeforeIndex(int part, int index) Returns the String before a given
index based on the part defined in 6.2.1.7.3.
getCaretPosition() Returns the zero-based offset of the caret.
getCharacterAttribute(int index) Returns the AttributeSet for a given
character (at a given index).
getCharacterBounds(int index) Determines the bounding box of the
character at the given index into the string.
getCharCount() Returns the number of characters (valid indicies).
getIndexAtPoint(Point) Given a point in local coordinates, returns the
zero-based index of the character under that Point.
getSelectedText() Returns the portion of the text that is selected.
getSelectionEnd() Returns the end offset within the selected text.
getSelectionStart() Returns the start offset within the selected text.
Table 10.0 AccessibleText Interface Methods
[177]6.2.1.7.1 Text Attributes
To implement AccessibleText you will need to examine how you have
built your document model. Most document models are designed based on
how they handle paragraphs, runs of text with common properties, an
embedded graphic, and so on. The HTML web page is the epitome of a
complex document as it also allows the document to be interactive. In
fact, a web browser may have to handle an embedded Java applet. The
idea here is to convert your document to a text representation. To do
this, you need to know more about the attribute set associated with
each character and how the attribute set is used to embed complex
components and icons.
When an assistive technology wishes to get the set of attributes for a
given index, it will call the AccessibleText method
getCharacterAttribute(int index) for the given character index. This
returns an object of class AttributeSet that maintains a database of
key/value pairs as defined in Table 3.0 for the StyleConstants class.
To get the background color for a character index in your document it
would issue the following set of calls:
import javax.swing.text.StyleConstants;
import javax.swing.text.AttributeSet;
import javax.swing.accessibility.*;
Color getColor(Accessible yourComponent, int index) {
Color bg = null;
AccessibleContext ac = yourComponent.getAccessibleContext();
AccessibleText at = ac.getAccessibleText();
// Get the Attribute Set
AttributeSet aset = at.getCharacterAttribute(index);
// Get the background color
bg = (Color) aSet.getAttribute(StyleConstants.Background);
while (bg == null) {
//No background color here: Check the Parent
//Attribute Set
aSet = (AttributeSet) aSet.getAttribute(StyleConstants.ResolveAttribut
e);
if (aSet != null) {
bg = (Color) aSet.getAttribute(StyleConstants.Background);
if (bg != null)
break;
}
else
break;
}
/* When no background color exists in the */
/* AttributeSet Tree, get the the color */
/* from the accessible component */
if (bg == null) {
AccessibleComponent acx = ac.getAccessibleComponent();
bg = acx.getBackground();
}
return bg; // return the background color
}
Figure 11.0 Retrieving the Background Color from AccessibleText
Examining Figure 11.0 we can see how an assistive technology program
will search the attribute set tree looking for the background color
attribute. When it finds the information, it will stop the search.
Otherwise, it will get the information from the AccessibleComponent.
When storing runs of attributes in your attribute set, use
AttributeSet. To make life easy, the Sun folks have provided you with
a class called SimpleAttributeSet in the JFC. This supports the
descendant AttributeSet interface for adding attributes to it called
MutableAttributeSet. Like AttributeSet, MutableAttributeSet is a JFC
interface.
If you wanted to create an HTML document, where the default colors
were black on white. You would create your default attribute set as
follows:
SimpleAttributeSet DefaultAttributeSet;
DefaultAttibuteSet.add(StyleConstants.Foreground, Color.black);
DefaultAttibuteSet.add(StyleConstants.Background, Color.white);
//Give the run a name
LinkAttribute.Set.add(StyleConstants.NameAttribute,"");
If your browser which controlled the document drawing detected a
hypertext link in the input stream, where the hypertext foreground
color was to be blue and the text underlined, you would create an
AttributeSet run and add it as follows:
// Create an Attribute Set run with blue, underlined
// Foreground text
SimpleAttributeSet LinkAttributeSet = New SimpleAttributeSet();
LinkAttributeSet.add(StyleConstants.Foreground, Color.blue)
LinkAttributeSet.add(StyleConstants.Underline, new Boolean(true));
//Give the run a name
LinkAttribute.Set.add(StyleConstants.NameAttribute,"");
// Set the Resolving Parent, so the assistive technology can determine the back
ground color
LinkAttributeSet.setResolveParent(DefaultAttributeSet);
Now, you simply have to store this AttributeSet with the specified run
of text in your document, based on your document data model. When
assistive technology goes to index the text in your document to grab
the AttributeSet, you will be ready with the information. Furthermore,
you will have the attribute information available to draw the run
yourself.
[178]6.2.1.7.2 Embedding Objects
Your document may contain an "embedded" complex document or non-text
object that identifies a special component to be handled by your
application. For this, simply provide a blank character for the
object's index position, reference the Component which draws it in the
AttributeSet, just like attributes for font, foreground color, and so
on. The Component referenced in the attributes needs to implement the
Accessibility API. An example could be the inclusion of a JTable.
Another example may be a JLabel containing a bit map. This design
allows assistive technologies to scan or browse your document. If the
user wishes to focus on the embedded object he can focus and expand
his view of the document to that component or ignore it entirely.
// Create an Attribute Set run with blue, underlined
// Foreground text
SimpleAttributeSet TableAttributeSet = New SimpleAttributeSet();
TableAttributeSet.add(StyleConstants.ComponentAttribute, new JTable());
//Give the list of components a name
TableAttributeSet.add(StyleConstants.ComponentElementName, "Table of Contents")
;
//Give the run a name
TableAttribute.Set.add(StyleConstants.NameAttribute,"
");
//Set the Resolving Parent, so assistive technologies can determine the backgro
und color
LinkAttributeSet.setResolveParent(DefaultAttributeSet);
To embed icons, simply follow the same procedure for using a blank
character to represent the indexed character for the icon. In the
attribute, create a run, which sets the run AttributeSet information
as follows:
Attribute Value
StyleConstants.NameAttribute ""
StyleConstants.IconElementName URL String for the Icon
StyleConstants.IconAttribute (Icon)new ImageIcon(URL,
Description); Table 12: Sample Attributes for Embedding Icons in
Attribute Sets
Now that you know how to embed objects, the question is when to embed
objects. To answer this question, put yourself in a blind user's
shoes. This user wants to be able to read your document in a browsing
fashion. When he runs across a new paragraph he may want to know that
it is a new paragraph, but he does not want to deal with it like an
embedded document. Consider embedded documents as document parts you
may want to skip over in when casually browsing.
Examples of true embedded documents are tables, a Java applet used to
show a MPEG video and so on. If the user wants to expand his view on
this embedded object, he can ask his Java screen reading application
to expand the view on that Component. The Component could be a text
area in an HTML Form. In this case, the user could detect from the run
that a text area exists and can choose to expand his view on the text
area. The embedded object should have implemented Accessible and its
AccessibleContext should support AccessibleText.
[179]6.2.1.7.3 Referencing the Indexed Character String
As shown in [180]section 6.2.1.7 AccessibleText, access to text,
through the AccessibleText interface is based on a character index and
the part of text you want to retrieve around that index. At a given
character index, the caller requests the corresponding word,
character, or sentence based on the method and part definitions of
AccessibleText.CHARACTER, AccessibleText.WORD, or
AccessibleText.SENTENCE, respectively.
[181]6.2.1.7.4 Caret Position and SelectedText
The AccesibleText interface refers to offsets for these values (the
character index for these items in your AccessibleText document). The
definition of the Caret is obvious, but to avoid confusion,
SelectedText is the text the user has highlighted often for cutting,
pasting, and deleting.
Important:
If you are developing a new accessible text class (non-JFC), please
remember to keyboard-enable selecting text. This accomplished by the
user holding the shift key down at the caret position and moving the
arrow keys, pressing the PAGE-UP, END, HOME, or PAGE-DOWN in
succession.
A good way to verify your keyboard accessibility is to unplug your
mouse and try to navigate the text object yourself.
[182]6.2.1.7.5 Property Changes
The three property changes you must fire for AccessibleText are:
* ACCESSIBLE_TEXT_PROPERTY (text data changes)
* ACCESSIBLE_SELECTION_PROPERTY (highlighting text)
* ACCESSIBLE_CARET_PROPERTY (caret moves)
Your AccessibleText implementation should fire these changes from the
firePropertyChange method in your implementation of AccessibleContext.
Important:
Do not fire ACCESSIBLE_VISIBLE_DATA_PROPERTY for AccessibleText
Components. Use the ACCESSIBLE_TEXT_PROPERTY instead. Firing both will
result in sending unneeded property change events to assistive
technologies. For a detailed description of firing these property
changes see [183]section 6.2.4 Property Change Notification.
[184]6.2.2 Parent/Child Information
The way assistive technologies gather and organize information about
your program is by assembling the list of components making up your
application from the parent/child hierarchy. A simplistic example of
this is when an assistive technology program listens for a focus
change. When this occurs, the assistive technology program would go up
the parent tree, from the focused component, until it reaches the
window frame. It then recursively enumerates all the visible and
showing children making up the active program. The assistive
technology program now has a list of all the components making up your
application and it can organize them based on its representation of
the screen. At this point, the assistive technology communicates with
them individually through the Accessibility API. This is why it is
important that you provide parent/child information for each of your
objects.
Note: Many GUI components act as a proxy for their children. In this
case, their children are specialized objects responsible for their
rendering and all focus management and input is managed by the
proxying parent component. As a result, these children cannot be
enumerated using the standard JDK methods for enumerating children. To
facilitate assistive technology access to your program it is important
that you support the methods, listed in this section, for all GUI
objects and that all GUI objects implement the Accessibility API. An
example where a parent proxies for its children is the way a JFC JList
component treats its list entries. Each entry is treated as an
accessible child who is told to draw by the JList component.
This section describes the following methods:
* AccessibleChild
* AccessibleChildCount
* AccessibleParent
* AccessibleIndexInParent
Important:
Whenever an Accessible object adds or removes an AccessibleChild, it
must fire an ACCESSIBLE_CHILD_PROPERTY change to notify an assistive
technology when its Accessible children change. Furthermore, this
information should be reflected in the AccessibleChildCount.
[185]6.2.2.1 getAccessibleChild(n)
This function returns the nth immediate child that implements the
Accessibility API.
[186]6.2.2.2 getAccessibleChildCount()
getAccessibleChildCount returns the number of immediate children that
implement the Accessibility API. If you had a list box with ten
entries, you would have 10 accessible children.
[187]6.2.2.3 getAccessibleParent()
AccessibleParent returns the parent object that implements the
Accessibility API. If there is no Accessible parent this method should
return null.
[188]6.2.2.4 getAccessibleIndexInParent()
When implementing AccessibleContext, this method returns the index of
the AccessibleContext in its parent's Accessible child list.
An example is a list box. If your list box had 10 entries, the number
of accessible children would be 10. The nth child of the list box
would be the nth entry in the list box. When assistive technology
queries the nth entry in the list box, the result should support the
Accessibility API. When assistive technology asks for the
AccessibleParent of the entry from its AccessibleContext, it should
return the list box object.
[189]6.2.3 Role and State Information
Role and state information describes the unique features of an object.
By defining an object's role you describe the object's generic
function in the system independent of its class name. The object's
role enables assistive technology to decide how to present the object
and to tell the user what it is.
The state naturally describes the current state of the object. For
example, if the object is a check box it may be in the "checked" state
or if it is a text area it is important to know if it is in the
"editable" state.
This section describes the following:
* AccessibleRole
* AccessibleState
* AccessibleStateSet
[190]6.2.3.1 AccessibleRole
AccessibleRole is the basic role of an application component. The role
describes the generic function of the component; such as "push
button," "table," or "list."
In older windowing systems like Windows 3.XÒ or Presentation Manager,
assistive technology programs used to use the class name to provide
the role information about a GUI object. This was often unusable
because applications would subclass standard windowing components and
give them obscure class names. By providing standard role information
you can provide the user with familiar information about the object's
function within your program. For example, if you sub-classed an AWT
button class with a class called foobarpbutton, the role would still
be AccessibleRole.PUSH_BUTTON.
This class provides a set of strongly typed constants enumerating
common object roles. AccessibleRole is a descendant of
AccessibleBundle See [191]section 6.2.5.1 AccessibleBundle. Therefore,
it inherits the toDisplayString(Locale) method allowing you to obtain
the localized string based on a locale-independent key from a
predefined AccessibleBundle containing the keys defined in this class.
A public constructor for this class has been purposely omitted and
applications should use one of the constants from this class. If the
constants in this class are not sufficient to describe the role of an
object, a subclass should be generated from this class and it should
provide constants in a similar manner.
The generic enumerated roles are largely based on classes provided in
JFC's rich GUI component class library.
Table 13 contains a pre-defined set of AccessibleRoles and their brief
descriptions:
AccessibleRole Description
ALERT An object used to alert the user, such as a warning message.
AWT_COMPONENT An AWT component, but nothing else is known about it.
CHECK_BOX A check box. In the generic sense, this is a choice that can
be checked or unchecked and provides a separate indication of the
current state.
COLUMN_HEADER The header for a column of data.
COMBO_BOX A combination of a text field and drop-down list.
DESKTOP_ICON An iconified internal frame in a DESKTOP_PANE.
DESKTOP_PANE This is normally used as the parent of internal frames to
provide a pluggable desktop manager object to the internal frames or
iconified internal frames.
DIALOG A dialog box.
DIRECTORY_PANE A generic container providing directory information.
FILE_CHOOSER A dialog box used to choose a file.
FILLER An object that fills up space in a user interface.
FRAME A window frame.
GLASS_PANE A transparent window container which does not contain a
frame.
INTERNAL_FRAME A frame-like object that is clipped by a desktop pane
or parent pane window. A familiar example would be the program group
windows in the Windows 3.1tm Program Manager or an individual document
frame in a multi-document application such as a word processor.
LABEL A display object used to show a short text string, an image, or
both. A label does not react to input events.
LAYERED_PANE A specialized pane that allows its children to be drawn
in layers, providing a form of stacking order. For example, you may
have a stack of child Container windows where the layered pane would
determine which layer in the stack would be drawn in the appropriate
Z-order.
LIST An object containing a list of selectable items. This usually
describes a list box.
MENU An object, that when selected, displays a vertical pop-up list
of menu items.
MENU_BAR The top-level container of menu and menu items.
MENU_ITEM A Menu or Menu Bar entry.
OPTION_PANE A specialized pane whose primary use is inside a dialog.
PAGE_TAB A Tab in a Page Tab List.
PAGE_TAB_LIST A set of selectable notebook tabs. Each tab contains a
graphic and/or text name.
PANEL A rectangular area in an application which controls the layout
of its children.
PASSWORD_TEXT A text object used for passwords, or other places where
the text contents are not shown widely to the user.
POPUP_MENU A modal list of menus, which can be popped to the highest
Z-order of visibility.
PROGRESS_BAR An object which graphically depicts the progress of a
desired operation in the form of a bar scale. For example, it would be
used to the progress of an install program.
PUSH_BUTTON A simple push button.
RADIO_BUTTON An implementation of a radio button -- an item that can
be selected or deselected, and which displays its state to the user.
ROOT_PANE This is a top-level container pane for an application whose
definition is derived from the JFC root pane.
ROW_HEADER An object that defines a row label (like in a table or
spreadsheet).
SCROLL_BAR A horizontal or vertical scroll bar used to scroll an area
on the screen.
SCROLL_PANE A pane that allows horizontal or vertical scrolling of
its contents through the use of optional horizontal and vertical
scroll bars.
SEPARATOR An implementation of a Menu Separator.
SLIDER A control that lets the user select a value from a bounded
interval.
SPLIT_PANE A glass pane divided into two equal areas with a
separator.
SWING_COMPONENT A JFC component having no user-definable role.
TABLE A table of data consisting of row and column information.
TEXT A document or edit field containing only text.
TOGGLE_BUTTON A generic button which can be either locked on or off.
TOOL_BAR A bar of selectable button objects, each providing a unique
function.
TOOL_TIP Text description.
TREE An object displaying a visible tree representation such as a
file directory.
UNKNOWN An object having either no user-definable or provided
AccessibleRole.
VIEWPORT An object which maintains the state of a screen transfer
area from an off screen bitmap like the Xtm Windows System backing
store.
WINDOW An object that is responsible for receiving user input from the
native windowing system. This is usually a JDK window. Table 13:
Pre-Defined AccessibleRoles
Although it is possible to subclass AccessibleRole and extend it to
add new objects, it is preferable that you use one of the predefined
roles when supporting the AccessibleContext method getAccessibleRole
and augment the role though the accessible description. If you need
additional roles, you should submit your request to access@sun.com to
augment the standard AccessibleRole list. For example, your program
may use a thermometer object to display the temperature. An option
would be to use the PROGRESS_BAR accessible role and set the
AccessibleDescription to "Thermometer."
[192]6.2.3.2 AccessibleState
Use AccessibleState to describe a particular state of a component. The
actual state of the component is defined as an AccessibleStateSet,
which is a collection of an object's AccessibleStates.
The constants in this class present a strongly typed enumeration of
common object states. AccessibleState is a descendant of
AccessibleBundle. See [193]section 6.2.5.1 AccessibleBundle.
Therefore, it inherits the toDisplayString(Locale) method. This allows
you to obtain the localized string, based on a locale-independent key,
from a predefined AccessibleBundle containing the keys defined in this
class.
A public constructor for this class has been purposely omitted, and
applications should use one of the constants from this class. If the
constants in this class are not sufficient, create a subclass from
this class, and provide constants in a similar manner.
The generic enumerated states that this class provides are largely
based on classes provided in JFC's rich GUI component class library.
AccessibleState Description
ACTIVE Indicates whether an application is active. Example: Top-level
frames use ACTIVE to indicate that it or one of its children has
focus. The ACTIVE state is also set for Accessible descendents found
in objects, such as a list when a child is the current Active
descendent. See [194]ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY.
ARMED Indicates that the user input is currently directed to that
object and it is "armed for selection." Example: a highlighted menu
item or a pressed push button.
BUSY Indicates if the object is currently busy and it is not
responding to user input. Example: an application displays the
hourglass.
CHECKED Indicates whether an object is in the checked state. Example:
radio buttons and check boxes.
COLLAPSED Indicates this object is collapsed, such as when a tree
branch is collapsed.
EDITABLE Indicates whether a text or document area is in an editable
state.
ENABLED Indicates if an object is enabled. An object that normally
responds to user input and can be set to not respond to user input
(disabled state) would support this state. Example: a menu item - this
state would be removed if it was grayed out.
EXPANDABLE Indicates this object allows progressive disclosure of its
children.
EXPANDED Indicates this object is expanded.
FOCUSABLE Indicates whether the object is capable of receiving input
focus.
FOCUSED Indicates whether the current object has input focus.
HORIZONTAL Indicates whether the object is in a horizontal state.
Examples: scroll bars, sliders, progress bars, and scroll panes.
ICONIFIED Indicates whether the frame object is in an iconified or
minimized state.
MODAL A window's state such that when an application window is
"modal," the user cannot switch to another window within the
application until after the window is destroyed or set to non-modal.
Example: dialog boxes.
MULTI_LINE Indicates this (text) object can contain multiple lines of
text, such as a multi-line edit field.
MULTISELECTABLE Indicates whether the given container is in a state
supporting selection of more than one of its Accessible Children.
Example: a list box.
OPAQUE Indicates whether a component paints every pixel within its
rectangular region. A non-opaque component paints only some of its
pixels, allowing the pixels underneath it to "show through." A
component that does not fully paint its pixels therefore provides a
degree of transparency.
PRESSED Indicates whether the object is currently depressed. Example:
a push button.
RESIZABLE Indicates whether the object is resizable. Example: a frame
uses this.
SELECTABLE Indicates if the object is selectable. Example: a toggle
button.
SELECTED Indicates if the object is currently selected. Example: a
selected check box menu item.
SHOWING Equivalent to the isShowing state in the JDK component -
indicates if the object is showing on the screen. Example: a pop-up
menu. When it has not been popped up it is visible but not showing.
SINGLE_LINE Indicates this (text) object can contain only a single
line of text, such as single-line edit field.
TRANSIENT Indicates that this object is transient. This also notifies
an assistive technology to not add listeners to the object because it
will never generate events. Examples of transient objects are those
found in collective Swing components, such as lists, tables, and
trees. In these cases, Accessible children are created by a single
cell-renderer that creates transient accessible children for an
assistive technology based on the child index.
When you create an Accessible object in response to a requested
proxied "Accessible" child, and this child is only created to fulfill
the request, you should include AccessibleState.TRANSIENT in the
child's AccessibleStateSet. This tells the assistive technology to
monitor its proxying parent for changes to its children, rather than
the transient child. In the case of JFC, this is often done for cell
renderer objects.
VERTICAL Indicates whether the object is in a vertical state.
Examples: scroll bars, sliders, progress bars, and scroll panes.
VISIBLE Equivalent to the isVisible state in the JDK component -
indicates if the object will be visible when "shown" on the screen. An
object needs to be visible and showing to be displayed. Table 14:
Pre-Defined AccessibleStates
Note: Whenever a change in AccessibleState occurs in an object, you
need to fire an appropriate property change in AccessibleContext.
AccessibleStateSet: AccessibleStateSet maintains a collection of the
AccessibleState settings for a given Accessible object. It has methods
for you to add or remove AccessibleStates to its collection. An
assistive technology would query the current AccessibleStateSet to
determine the state of an object.
It is important that you maintain the set of state information for
each Accessible object. Examples of state information are "checked"
for a check box, or "vertical" for a scroll bar. See the previous
section for a more detailed description of the AccessibleState.
The AccessibleStateSet class supports the methods listed in Table 15.
Method Description
add(AccessibleState) Adds a new state to the current state set if it
is not already present.
addAll(AccessibleState[]) Adds an array of Accessible states to the
existing state set.
clear() Removes all the states from the current state set.
contains(AccessibleState) Determines if the AccessibleState passed is
in the state set.
remove(AccessibleState) Removes a state from the current state set.
toArray() Returns the current state set as an array of
AccessibleState.
toString() Returns a localized String representing the current state
set using the default locale. Table 15: AccessibleStateSet Methods
To modify the state set, check to see if the AccessibleStateSet
contains the AccessibleState. Then, add or remove the AccessibleState,
as needed.
Important:
Whenever you add or remove states to the AccessibleStateSet, you must
fire an ACCESSIBLE_STATE_PROPERTY change event in AccessibleContext,
as described in [195]section 6.2.4. Property Change Notification.
[196]6.2.4 Property Change Notification
The Java Bean APIs (Java's software component model) support a common
object-oriented feature called properties. Properties are specific
attributes of an object. The Java bean API has added the ability for
an object to notify registered listeners when one of its properties
change. The Accessibility API has incorporated this feature to enable
assistive technology to be notified when specific property data
changes. This enables assistive technology programs to passively
monitor your application. Property change notification is handled
through your implementation of AccessibleContext. Assistive technology
programs will register listeners with the AccessibleContext object you
have written to monitor accessibility specific information. These
familiar Java bean methods are used to manage property changes in the
AccessibleContext:
firePropertyChange(String propertyName, Object oldValue, Object
newValue):
Fires the specified property change (propertyName) with the old
and new values to registered listeners.
addPropertyChangeListener(PropertyChangeListener listener):
Adds an object supporting the PropertyChangeListener interface
described in the Java bean package.
removePropertyChangeListener(PropertyChangeListener listener):
Removes an object supporting the PropertyChangeListener
interface described in the Java bean package.
The following is a list of Accessibility properties you must support:
ACCESSIBLE_DESCRIPTION_PROPERTY:
When a change in the accessible description occurs, you must
fire this property change event to registered listeners. To
fire the this property change event, the following mechanism is
required, where oldDescription and newDescription are of class
String:
firePropertyChange(
AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY,
oldDescription,
newDescription);
ACCESSIBLE_NAME_PROPERTY:
When a change in the accessible name occurs, you must fire this
property change event to registered listeners, where oldName an
newName are of class String.
firePropertyChange(
AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
oldName,
newName);
ACCESSIBLE_SELECTION_PROPERTY:
When a change occurs to your AccessibleSelection collection
object, you need to fire this property change event to
registered listeners. Selection change event data, when
implemented, usually involves complex collection objects and,
as such, it is both inefficient and unnecessary for you to
figure old and new values when firing the property change. To
fire a selection property change, the following mechanism is
required where selectedText is a string:
firePropertyChange(
AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
null,
selectedText);
If the selection change involves a collection of selected
items, use the following mechanism:
firePropertyChange(
AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
new Boolean(false),
new Boolean(true));
Where a collection is involved, the assistive technology
acquires the selection information from the AccessibleSelection
information of the component that is generating the property
change event.
ACCESSIBLE_STATE_PROPERTY:
When a change occurs to your AccessibleStateSet collection
object, you need to fire this property change event to
registered listeners. AccessibleState changes are basically
State flag toggles. When firing this property value of the old
or new value will be null if the respective value is off or the
AccessibleState constant if the value is on. For example, if an
entry field was switched to the Editable state, the property
firing in the AccessibleContext should be implemented as
follows:
firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null,
AccessibleState.EDITABLE);
ACCESSIBLE_TEXT_PROPERTY:
When a change occurs to the data in your AccessibleText object,
you need to fire this property change event to registered
listeners. Whenever the object making up your document change
(text is replaced, added, or deleted, objects are embedded,
etc.) you would fire this property change. You would not do so
for attributes of the data. For example, changing the font
would not result in a property change event.
firePropertyChange(
AccessibleContext.ACCESSIBLE_TEXT_PROPERTY,
new Boolean(false),
new Boolean(true));
ACCESSIBLE_VALUE_PROPERTY:
When a change occurs to the current value in your
AccessibleValue object, you need to fire this property change
event to registered listeners. AccessibleValues are set for
objects that support a value and value range setting components
such as scroll bars, sliders, and progress bars.
firePropertyChange(
AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
new Integer(oldValue),
new Integer(newValue));
ACCESSIBLE_VISIBLE_DATA_PROPERTY:
When a change occurs to the data in the visible portion of your
object, you need to fire this property change event to
registered listeners. This applies to the text changing in your
checkbox, a change in your list box's data, and so on. This is
an extremely important property, because many assistive
technologies store the visible data information in their own
data structures, to give their own "look and feel" of your
program. For example, the Access Engine technology in IBM's SVK
sorts its information in row/column format.
firePropertyChange(
AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
new Boolean(false),
new Boolean(true));
This property change applies to all components except those
that implement AccessibleText.
ACCESSIBLE_CARET_PROPERTY:
When a caret change occurs in Accessible objects supporting
AccessibleText, this property should be fired when the caret
changes position. The position old and new values passed should
be an Integer object containing the old and new values for the
character index for the caret.
firePropertyChange(
AccessibleContext.ACCESSIBLE_CARET_PROPERTY,
new Integer(oldposition),
new Integer(newposition));
ACCESSIBLE_CHILD_PROPERTY:
When a child is added or removed from an Accessible object,
this Accessible object should fire property change. If an
Accessible object is being added, the old value is null and the
new value is the Accessible child. If an Accessible child is
being removed, the old value is the Accessible child and the
new value is null.
Adding:
firePropertyChange(
AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
null,
(Accessible) childadded);
Removing:
firePropertyChange(
AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
(Accessible) childremoved,
null);
ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY:
A constant used to determine when the active descendant of a
component has changed. The active descendant is used for
objects such as list, tree, tab pane, and table, which might
have transient children. When the active descendant has
changed, the old value of the property change event is the
Accessible representing the previous active child. The new
value is the Accessible representing the current active child.
firePropertyChange(
AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
(Accessible) previous active child,
(Accessible) current active child);
Important:
In objects like lists, trees, and so on, it is often possible to
select multiple items. In these cases, the items are often represented
as highlighted text. It is either the currently Active child or the
last one that had the user's focus that is considered the active
descendant. The AccessibleState of this descendant should have its
AccessibleStateSet include AccessibleState.ACTIVE. This is
represented, graphically, on many systems as the moving dotted box
around the list element you are currently operating on.
[197]6.2.5 National Language Information
This section describes the following two class files, which come with
the Accessibility API to allow it to support localized Role and State
information:
* AccessibleBundle
* AccessibleResourceBundle
Normally, you should not need to extend or modify these files. You
should use the standard Accessible Role and State definitions defined
in the Accessibility API. If however, you need to have additional
Roles or States, consider the following:
* An assistive technology will likely have not seen them before and
therefore they will not be readily accessible.
* You will need to create new files, which are descendants of
AccessibleRole, AccessibleState, AccessibleBundle, and
AccessibleResourceBundle to accommodate your new roles and states.
* If you do the latter, Sun does not guarantee the data in the
AccessibleResourceBundle class. This contains all the
key/localized string information for each AccessibleRole and
AccessibleState. This could break the accessibility of your
application in later releases of the Accessibility API.
We strongly recommend:
* Do not create your own AccessibleRole and AccessibleState
information for your application. Use those provided for by Sun.
* If you have a need to add additional Role and State information,
make a request to the Sun Accessibility group for incorporation in
a later release of the Sun Java Accessibility API.
[198]6.2.5.1 AccessibleBundle
As stated earlier, AccessibleRole and AccessibleState are descendants
of AccessibleBundle. AccessibleBundle supports the methods listed in
Table 16.
Method Description
toDisplayString() Returns the localized String describing the key
using the default locale.
toDisplayString(Locale) Obtains the key as a localized string. See the
JDK for a detailed description of Locale.
toDisplayString(String ResourceBundleName, Locale) Obtains the key as
a localized string, based on the fully-qualified resource bundle file
name and the Locale.
toString() Gets the localized string describing the key using the
default locale. Table 16: AccessibleBundle Methods
The source for this class is in the javax.accessibility package source
included in the JFC.
[199]6.2.5.2 AccessibleResourceBundle
This contains all the key/localized string information for each
AccessibleRole and AccessibleState.
The source for this class is in the javax.accessibility package source
included in the JFC.
[200]6.2.6 AccessibleAction
It is often difficult for people with disabilities to navigate an
application. For example, it is difficult to impossible for blind
computer users to use a mouse. It is also difficult for a sighted user
to determine the hot spots on an image map found on a web page.
Voice navigation systems, initially used by mobility impaired users,
need to convert voice commands to actions. The right way to implement
voice control of a GUI is not by simulating keyboard and mouse actions
because there is no description of the actions available, and the
simulation can be difficult.
For these reasons, the AccessibleAction object was created.
AccessibleAction contains a collection of description/action entries
to allow assistive technologies to select and perform a given object's
action(s).
Note: For objects that have no action, like a label or title bar,
AccessibleContext would return null for the AccessibleAction.
The AccessibleAction interface you would implement is described in
Table 17.
Method Description
doAccessibleAction(int) Performs the specified action on the object.
getAccessibleActionCount() Returns the number of accessible actions
available in this object. If there is more than one, the first one is
the "default" action.
getAccessibleActionDescription(int) Returns a description of the
specified action of the object. Table 17: AccessibleAction Methods
An example of AccessibleAction for a tree element might be:
* getAccesibleActionCount returns 1.
* getAccessibleAccessibleDescription[0] = "ToggleExpand".
* doAccessibleAction(0): expand or collapse the tree element based
on the state of the element.
Important:
If you have a component or component element that can be activated by
the mouse or keyboard, you must provide an AccessibleAction for it,
otherwise it is not accessible.
[201]6.2.7 Miscellaneous Information
The following are specialized interfaces that do not fit into one if
the categories above. This section describes:
* AccessibleHypertext
* AccessibleHyperlink
[202]6.2.7.1 AccessibleHypertext
Many applications implement hypertext-type interfaces to create richly
linked documents. Some of the most fundamental applications for text
are help systems. In a help system, a specific piece of text or an
image is visibly augmented to indicate that if you select that area,
you will access more information about that topic. This concept is
expanded to the Web, where images and text in web pages link you to
documents on either your machine or another machine.
AccessibleHypertext is a Java interface extension to AccessibleText
that enables you to provide a document interface that facilitates
access to hyperlinks. If you have an application component that
contains Hypertext, you must implement AccessibleHypertext on that
component. Because AccessibleHypertext extends AccessibleText, only
the added methods for AccessibleHypertext are described in Table 18.
Method Description
getLink(int) Returns the nth AccessibleHyperlink of this hypertext
document.
getLinkCount() Returns the number of links within this document.
getLinkIndex(int) Returns the index into an internally stored array of
AccessibleHyperlink objects based on the AccessibleText document
character index. If no link exists at this character index, the result
returned is -1. Table 18: AccessibleHypertext Methods
By providing the AccessibilityHypertext interface, you are enabling a
disabled user to:
* Quickly access the hypertext links for an entire document.
* Determine whether a given document index contains a hypertext
link.
* Select and activate any of the set of links at the specific
document index.
* Enable assistive technologies, such as technologies for mobility
impairments and the blind, to access a hypertext document without
using a mouse. One example is hands free navigation without a
mouse, for example, through a voice recognition interface.
The accessible hyperlink that this interface returns is described in
[203]section 6.2.7.2 AccessibleHyperlink.
[204]6.2.7.2 AccessibleHyperlink
An AccessibleHyperlink defines a link or collection of links. It is an
abstract Java class that extends AccessibleAction. Because it extends
AccessibleAction, it provides a mechanism for describing each link
element and how to activate the element. Like AccessibleAction, each
link is referenced through a zero-based index (0 through n-1). This is
particularly important for image maps found on web pages. On a web
page, an image map might contain clickable hot areas that act as
hyperlinks to other documents.
AccessibleHyperlink is described in Table 19.
Method Description
isValid() This indicates whether the link is still valid with respect
to the AccessibleHypertext it references. This method returns true if
the link is valid and false if it is not. A link is invalid (return
false) if the underlying text changed, such as when a link is
followed.
getAccessibleActionCount() Returns the number of accessible actions
available in this link. For HTML image maps, this equals the number of
links for a given image map. If there is more than one, the first is
not considered the "default" action. Typically, links have one
Accessible action.
doAccessibleAction(int) Performs the action specifed by index passed
for this link.
getAccessibleActionDescription(int) Returns a String description for
the indexed action. The description should be set to the anchoring
text. In the case of an HTML link like
IBM Special Needs Home Page, the value returned should be "IBM
Special Needs Home Page". If this were an image, for example, , the result returned would be the ALT text "a
picture of Rich".
getAccessibleActionObject(int) Gets an object that represents the link
action for the given link. Using the example from the previous method
for a text link, you would want to return new java.net.URL
(http://www.ibm.com/sns).
getAccessibleActionAchor() Returns an object that represents the link
anchor, as appropriate for that link. For example, from the image map
example in getAccessibleDescription, this would return
ImageIcon(phillricho.gif, "Phill and Rich's Picture").
getStartIndex() Gets the character index within the hypertext document
at which this link begins.
getStopIndex() Gets the character index within the hypertext document
at which this link ends. Table 19: AccessibleHyperlink Methods
[205]6.3 Hints, Tips, and Words of Wisdom
When determining how to implement code, it is always good to see how
someone else accomplished the task. The JFC comes complete with
source. Because the JFC has implemented the Accessibility API, in most
cases, this is an excellent place to start. Furthermore, the JFC also
includes the Accessibility API source. See [206]section 6.2.5.1
AccessibleBundle for some excellent examples.
JFC Component Type of Example
JList Example of a Proxying component for a list of Accessible
Children.
JTextComponent, JEditorPane Examples of AccessibleText and
AccessibleText implementation for presenting HTML text.
JLabel Simple implemenation of the Accessibility API.
JProgressBar Implementation of AccessibleValue.
JComponent AccessibleJComponent internal class implementation of the
AccessibleContext abstract class.
AbstractButton Implementation of AccessibleAction for activating a JFC
button. Table 20: Example Accessibility API Implementations
The next two sections are problem areas you are likely to run into
when trying to make application components accessible:
* Managing Children - Proxied Objects
* Peered Objects
[207][208][209][210][211]6.3.1 Managing Children
Proxied objects are lightweight objects whose placement, drawing
directives, and response to input are guided by a parent object. An
example is the JFC implementation of cell renderers for list box. In a
JFC list box, each list entry is created through the use of a single
ListCellRenderer. The JList component tells it where to draw, when to
"appear" selected, and so on. The JList component does not care what
the cell renderer draws in it as long as it does what it is told. The
cell render does not receive focus from the windowing system, even
though JList may ask it to appear focused. If you are familiar with X
Window System programming, you should recognize these lightweight
objects as similar to "gadgets."
The JFC JTabbedPane component presents a different parent/child
relationship that might best be described as a limited proxy. In the
case of notebook page tabs, you know you will be dealing with a
limited number of children. Here, the tabs are not actually
components, but merely visual page tab elements with a reference to
the component to be shown, based on the page tab selected. Because the
list of elements is small, and generally persistent, it is easier to
maintain a vector of accessible objects representing each page tab.
When assistive technology requests an accessible child, JTabbedPane
merely goes to the internal vector of accessible page tab objects and
returns the corresponding object.
Parents, who do not proxy for their children, need only worry about
keyboard navigation to the children and providing the list of
children.
Here are some basic rules to follow when managing children:
* Make sure the children implement Accessible.
* If the children are selectable, a proxying parent should:
+ Implement AccessibleSelection. This is not the case when the
parent does not proxy for the child.
+ The children must indicate the state AccessibleState.SELECTED
in their AccessibleStateSet when selected.
* Proxying parents managing states for their children should fire
Accessible Property change events for their children. This is very
important for proxying components that manage large lists of
children. Assistive technology developers would like to avoid
adding PropertyChangeListeners to each list entry.
* When managing focus for a child, make sure the children are
accessible via the keyboard.
* Make sure the parent reports the children (0 through n-1) in the
logical order they appear and are navigable via the keyboard.
* Make sure all property change events are fired. If you have a
child whose text changes, make sure to fire an
ACCESSIBLE_DATA_VISIBLE_PROPERTY property change unless the child
implements AccessibleText. AccessibleText should fire the
ACCESSIBLE_TEXT_PROPERTY.
[212]6.3.2 Peered Objects
Peered objects translate to GUI objects in the underlying operating
system. For example, most AWT components fall into this category; an
AWT button translates to a button on the underlying Windows operating
system. It will be very difficult, perhaps impossible, without help
from both the Java side and the underlying operating system to make
peered objects accessible on the Java side.
In most instances, the data does not reside on the Java side of the
wall. In the case of Windowstm or OS/2tm, it means that you need to
provide numerous methods to get the data back to the Java side of the
wall from the native DLL. This may be simple for small items like
labels and buttons, but for more complex items like file dialogs and
WYSIWIG documents, it is a difficult task.
The most expedient solution is to use JFC and not peered objects.
[213]6.3.3 Menus
Menus are usually the most specialized part of a GUI application due
to performance issues and constant access by the user. They are often
the most distinguishing features of a GUI environment. This means they
are usually treated as a special case item by assistive technologies.
If you decide to use a new menuing system, you probably will no longer
work with assistive technology.
Important:
Use JFC's menu components. Assistive technologies are familiar with
them.
[214]6.3.4 Text Components
Using JFC's JTextComponent is ideal, but implementing AccessibleText
on components like these is a minimum. This is especially important
for editable text areas.
[215]6.3.5 Keyboard Usability Issues
[216]Section 11.1.1 JFC Keyboard Binding contains keyboard assignments
for the Java Foundation Classes. You can use the bindings as a
foundation to keyboard enable your application. When you keyboard
enable your application, the following keyboard usability issues need
to be considered:
Keyboard Bindings
In Java, you never know what system your application might run on.
Therefore, you must consider how keyboard conflicts might affect the
usability of your keyboard implementation. Take the following steps to
prevent conflicts with the underlying operating environment:
* Make sure the keyboard bindings you select do not conflict with
system keyboard mappings of the underlying operating system. For
example, Ctrl+Alt+Del might cause you to reboot or offer a
shutdown option on some systems.
* Make sure the keyboard bindings you select do not interfere with
the reserved mobility access keyboard modifiers for your operating
system. See [217]section 11.1.3 Reserved Key Mappings for Mobility
Access Features.
Navigation Order
It is important that application developers maintain a logical
keyboard navigation order. The navigation order is defined as the
order with which you use the keyboard to navigate between components
and component elements in your graphical program. Navigation is
accomplished by tabbing between components or groups, and using the
arrow keys within a component group or component's elements.
Tabbing
The ability to tab between software components is a key feature in the
implementation of keyboard accessibility. A component is inclusive in
the tabbing order when added to a panel and its isFocusTraversable()
method returns true. A component can be removed from the tabbing order
by simply extending the component, overloading this method, and
returning false.
Excessive use of tabbing can reduce the usability of software for both
disabled and non-disabled users. As a developer, you need to determine
the point at which tabbing gets in the way and provide a keyboard
alternative. This is done through the use of keyboard Mnemonics and
Accelerators.
Use of Mnemonics and Accelerators
Class libraries, like the Java Foundation Classes, should provide for
keyboard mnemonics and accelerators in their design. In the case of
JFC keyboard mnemonics, all visible items on the screen that set a
mnemonic for a component can have the component activated via the
ALT+mnemonic.
It is important that all visible menu items in an application's
menubar be activated via the keyboard. In JFC, this is accomplished by
setting the mnemonics for those menu items. To set a mnemonic, pass a
Java virtual key as defined in java.awt.KeyEvent. For example, to set
the mnemonic to ALT+F, use:
JMenu myMenu = new JMenu();
myMenu.setMnemonic(java.awt.event.KeyEvent.VK_F);
Additionally, menu items can have accelerators set to activate the
action they perform via the keyboard. It is important that frequently
used actions, like those found in a tool bar, have menu items with
assigned with an accelerator. To assign the Alt+1 accelerator to a
menu item, use the Swing KeyStroke class to create the key stroke, and
pass it to the JMenuItem setAccelerator method as follows:
JMenuItem myItem = new JMenuItem();
myItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MAS
K));
For components that do not specifically have a setMnemonic, the JLabel
componet in JFC has a method called setDisplayedMnemonic. Use the
method to change the focus to the component it is labeling, as defined
in the setLabelFor method. Here is a code example:
JLabel mylabel = new JLabel("File Name"); //Create a JLabel
JTextField myfield = new JTextField("MyFilename"); //Create a JTextFie
ld
mylabel.setLabelFor(myfield); //Associate label w
ith text field
mylabel.setDisplayedMnemonic(java.awt.event.KeyEvent.VK_F); //Set ALT+F for the
text field
Tab Groupings
Buttons of common functionality, such as a set of radio buttons used
to set the location of a panel (top left, bottom left, and so on.),
should be grouped together so the first element of the visible group
can be tabbed to. The arrow keys can be used to navigate to each end
of the group.
Quick Access to Keyboard Navigation Documentation
A serious problem with many software applications is that
documentation for keyboard access features is non-existent.
Documenting the features in print format does not help blind users. To
correct this problem, documentation about accessibility features
should be available electronically in the application's accessible
help facility, and a user should be able to activate the help using
the keyboard, typically the F1 key. In the case of blind users, they
can use the same screen reader program to access the help facility
that they use to access the application. It also improves usability to
define a "Keys Help" section in your help facility.
Maintain Consistent Keyboard Navigation Definitions
For usability reasons, most software needs to have product features
that are consistent between releases. For example, Lotus maintained
the same keyboard accelerators when converting the 123 spreadsheet
product from DOS to Windows. The same is true for keyboard access.
Imagine the difficulty for blind users you swapped the cut and paste
keyboard keys.
When considering your keyboard interface definition, start by using
the Common User Access (CUA) guidelines. Veteran disabled computer
users grew up with versions of CUA on most graphical systems,
including OS/2, Windows, the X Windows system, and DOS. The appendix
has sample keyboard settings for other operating systems that shows
the influence of CUA keyboard navigation on modern day operating
systems.
[218]7.0 Java Development Tool Designers
Powerful tools for building Java applications, including
next-generation tools, such as IBM's Visual Age for Java, are featured
on the IBM Java Developers' tools website:
[219]http://www.ibm.com/java/tools/tools.html.
IBM Visual Age for Java 2.0 includes the Swing class files. Use the
class files and these guidelines to create accessible Java
applications.
Guidelines are under development for tool designers for a later
release of this document that will better facilitate and perhaps
automate some of the building of accessible Java applications.
[220]8.0 Testing for Accessibility
Today, there are several ways to test your application for
accessibility. The first method is to unplug your mouse and try to
navigate your application without a mouse. This approach will uncover
where you need to implement keyboard access and how to do it in a way
that is usable. [221]Section 6.3.5 Keyboard Usability Issues will help
you in your implementation.
The second way to test your application for accessibility is to use an
accessibility test tool. Currently, the Sun Microsystems Java
Accessibility Utilities contain a set of tools which you can use to
help test the accessibility of your application. For example, the
Explorer tool will display each component's accessibility information
(e.g. AccessbleName and AccessibleDescription). You can find the
utilities at [222]http://java.sun.com/products/jfc/#download-access.
The third way to test your application for accessibility is to test
your application with an assistive technology that presents your
application in the form needed for a specific disability. The IBM Self
Voicing Kit for Java (SVK) will be soon be available for download from
the [223]IBM alphaWorks site.
Follow the testing checklist when writing your Java application.
Accessibility Test Checklist
1. Fully test your application using only the keyboard. Ensure you
set the keyboard focus to a component when a window is activated.
2. Use the demo tools provided in the Java Accessibility Utilities
package, to ensure that all relevant information is available on
components.
+ Ensure that each relevant component has implemented
Accessible
+ Ensure that each accessibility field is filled in
appropriately
+ Ensure there is an accessible action for components you can
activate with mouse or keyboard
3. Use IBM's Self Voicing Kit (SVK) to test your application for
Accessibility
+ Use the F7 Key to launch the Accessibility Test Tool to
analyze each component for accessibility
o Ensure that each relevant component has implemented
Accessible
o Ensure that each accessibility field is filled in
appropriately
o Ensure there is an accessible action for components you
can activate with mouse or keyboard
o Ensure sure there the each component which performs a
user function can be accessed through the keyboard
o Ensure sure that component labels are set properly
+ Use the Speech Output and/or output window to make sure text
and components are spoken properly
o Ensure sure that text is echoed when you type characters
o Ensure sure that highlighted text is spoken
o Ensure sure that component labels are spoken
o Ensure sure icon descriptions are set and spoken by the
SVK
+ Use the F8 Key on each component to verify that the
Accessible Action works as you intended
+ Use the F6 Key make sure that all text and components are
read in the visible parts of your application
+ In the absence of a speech output mechanism use the SVK
output window to verify the text that should be spoken
[224]9.0 Online Information and Help
When developing documentation for your application in HTML, please
follow the Web accessibility guidelines found on the IBM Special Needs
Systems web site: [225]http://www.austin.ibm.com/sns/access.html.
The World Wide Web Consortium (W3C) publishes the official guidelines
at [226]http://www.w3.org/WAI.
[227]10.0 Future Discussions
Java is still new and the following areas of accessibility are planned
to be addressed in future issues:
* Multimedia framework - closed captioning
* AccessibleTable - advanced accessible table access
* JavaOStm - operating system accessibility features
* Guidelines for Java development tool designers
[228]11.0 Appendix
The appendix describes keyboard bindings, accessibility references and
trademarks.
[229]11.1 Keyboard Bindings
Keyboard bindings are partially implemented in JFC. There are some
components with a question mark next to them, which indicates the
binding might be modified. This section will change if and when the
components change. Thes keyboard bindings are also under review by IBM
Special Needs Systems and other industry experts, such as the Trace
Research and Development Center.
[230]11.1.1 JFC Keyboard Bindings for Windows95/NT Components
This seperate document contains a list of the [231]keyboard bindings
for JFC components on the Windows 95/NT platform.
[232]11.1.2 Difference Evaluation: JFC Keyboard Bindings for Windows95/NT and
CDE/Motif
This seperate document contains a list of the [233]differences between
the keyboard bindings for JFC components on the Windows 95/NT and the
CDE/Motif platform.
[234]11.1.3 Reserved Key Mappings for Mobility Access Features
These keys are reserved for assistive technologies that assist
mobility impaired users.
Keyboard Mappings Mobility Access Feature
5 consecutive clicks of Shift key On/Off for StickyKeys
Shift key held down for 8 seconds On/Off for SlowKeys and RepeatKeys
6 consecutive clicks of Control key On/Off for screen reader numeric
keypad
6 consecutive clicks of Alt key Future Access use Table 21: Reserved
Key Mappings for Mobility Access Features
[235][236][237][238][239]11.2 Accessibility References
"IBM Accessibility Guidelines"
IBM Special Needs Systems
[240]http://www.austin.ibm.com/sns/access.html
"Making the GUI Talk"
Richard S. Schwerdtfeger, IBM.
[241]ftp://ftp.software.ibm.com/sns/sr-os2/sr2doc/guitalk.txt
Off-Screen Model Technology and GUI Screen Readers
"Towards Accessible Human-Computer Interaction"
Eric Bergman, Earl Johnson, Sun Microsytems.
[242]http://www.sun.com/tech/access/updt.HCI.advance.html
"Accessibility Quick Reference Guide"
Sun Microsystems.
[243]http://www.sun.com/tech/access/access.quick.ref.html
"Java Development Kit"
Sun Microsystems. [244]http://java.sun.com/products/jdk/
"Java Foundation Class"
Sun Microsystems. [245]http://java.sun.com/products/jfc/
[246][247][248][249][250]11.3 Trademarks
IBMÒ, OS/2Ò, AIXÒ, AS/400Ò, Screen ReaderÒ, and Visual AgeÒ are
trademarks or registered trademarks of International Business Machines
Corporation in the United States and/or other countries.
Lotustm is a trademark of Lotus Development Corporation in the United
States and/or other countries.
Tivolitm is a trademark of Tivoli Systems Inc. in the United States
and/or other countries.
MicrosoftÒ, WindowsÒ, Windows95Ò, and WindowsNTÒ are registered
trademarks of Microsoft Corporation.
Sun Microsystemstm, Javatm, 100%Pure Javatm, JavaOStm, and Solaristm
are trademarks of Sun Microsystems Inc.
Other company, product, and service names may be trademarks or service
marks of others.
[251]11.4 Feedback
Please e-mail feedback to IBM Special Needs Systems at
[252]snsinfo@us.ibm.com.
[253]Valid HTML 4.0![254]Bobby approved!
Ó Copyright IBMÒ Corporation 1998
- End of Document -