[an error occurred while processing this directive]

Page One
Page Two
The Databank
What Is Swing?
Special Report
IDE Roundup
Swing and the Web
Swing Text
Tech Topics
Friends
Tips and Tricks
The PLAF Papers
Call 911
The Archive
JFC Home
Download Swing
Swing API Docs
Download JDK
JDK Docs
Java Tutorial
 
The Swing Connection Special Report

Accessibility and the Swing Set
How Swing Can Help You Create Accessible Apps

By Mark Andrews

Duke in wheelchairOne important feature of the Java Foundation Classes (JFC) is their support for accessibility -- that is, support for hardware and software designed for people with disabilities, such as blindness or limited sight, deafness or limited hearing, or dexterity-related disabilities such as the inability to operate a mouse.

Support for accessibility is a very important feature of Swing. In fact, the Swing set is the only JavaTM-language component set that can be used to write accessible user interfaces, whether for web, for desktop, or for people with disabilities.

This article explains what accessibility is, shows how accessibility is implemented in the JFC (Java Foundation Classes), and describes how easy it is to build accessible applications using Swing components.

The major topics covered in this article are:


Why Bother with Accessibility?

Approximately 40 million Americans have some type of disability. And the World Health Organization says that approximately 20 per cent of the earth's population has some disability. That's approximately 800 million people.

Consequently, when you create an application, it's important to consider whether -- and how -- a person with a disability might use it. Some potential users of your program may not be able to use their hands or eyes -- that means they cannot use a mouse, type on a keyboard, see a screen, or read a printed user's guide.

Over the years, disabled users and access technology vendors (ATVs) have invented ingenious workarounds for such problems. Voice-input mechanisms have been designed to replace the mouse. Special switches such as mouth sticks have been created to replace the keyboard. Text-to-speech devices have been created to read aloud information that's displayed on the screen.

And inaccessible hardware is only one part of the problem. Many kinds of software --operating systems as well as application programs -- often contain unintentional roadblocks to people who have disabilities. For example, programs that require mouse input can't be used by people who are blind or who cannot use their hands. Other programs require certain kinds of manual dexterity that many users do not have. (To illustrate try pressing Ctrl+Alt+Del -- a key combination often required to reboot a system -- using just one hand).

If all that isn't enough to make you sit up and take notice, there are a number of other good reasons for building accessibility into your applications. Here are three:

  • Accessibility is a requirement in all current federal contracts as required by section 508 of the Federal Rehabilitation Act. In the commercial sector, the Americans with Disabilities Act (ADA) calls for similar considerations. Consequently, incorporating accessibility technology into an application can enhance its marketability. For more details on this topic, see the next subsection, "Accessibility-Related Laws and Regulations."

  • Accessibility can be beneficial to people who do not have disabilities, as well as to those who do. Text-to-speech mechanisms, for instance, can be useful in many different kinds of applications, as can touch-screen programs such as those used in kiosks. Because of its support for accessibility, JFC makes it easy to create these kinds of applications, as well as many others that are not specifically designed for users with disabilities.
     
  • It's easy to incorporate accessibility into applications that make use of JFC because the Java Foundation Classes implement accessibility methods in Swing's user interface components. Application developers can take advantage of this easy way to incorporate accessibility into their designs. To learn more about how Swing supports accessibility, see the "Swing and Accessibility" section.

Accessibility-Related Laws and Regulations

Paying attention to accessibility concerns can help software developers meet federal regulations that deal with disability-related issues. The United States has a number of disability-related laws and federal regulations that give students, state and federal employees, consumers, and their representatives considerable leverage in influencing future purchasing in a diverse set of public and private markets.

Section 504 of the Federal Rehabilitation Act -- passed in 1973 -- covers education contracts that use federal funds. It states that products purchased for education using federal dollars must be usable by all students.

Section 508 of the Federal Rehabilitation Act is similar to Section 504 but applies to all government contracts. It requires support for accessibility in specific technology and information products. It was passed because purchases of inaccessible office automation technologies were forcing federal and state employees with disabilities out of their jobs, exposing the government to potential antidiscrimination lawsuits.

The Americans with Disabilities Act (ADA), passed in 1992, applies to private companies. It requires commercial companies to provide "reasonable" accommodation for disabled employees in order to prevent discrimination.

The Telecommunications Act, which became law in 1996, covers any system that communicates across a wire to other systems. Definitions and requirements associated with telecommunications accessibility under this law haven't yet been drawn up, but it is likely that when they are, federally funded purchases will fall under Section 508-like requirements. When that happens, technologies such as ATMs and public information kiosks will fall under ADA-like requirements.


Accessibility and JavaTM Technology

There are four mechanisms that Sun has developed to build support for accessibility into the JavaTM programming language:

The following sections give a brief overview of these four areas of accessibility support.


The Java Accessibility API

The Java Accessibility API -- like the Swing component set -- is part of the Java Foundation Classes (JFC). It is defined in the javax.accessibility package.

More specifically, the Java Accessibility API defines a contract between the user-interface components used in an application and an assistive technology that provides access to that Java application. If an application fully supports the Java Accessibility API, it can be compatible with, and friendly toward, screen readers, screen magnifiers, and other kinds of assistive technologies. With a Java application that fully supports the Java Accessibility API, no offscreen model is necessary, because the Accessibility API provides all of the information normally contained in an offscreen model.

Screen Readers

A screen reader is a piece of software that "reads" the contents of a screen to someone who cannot see it. Most screen readers do this using a speech synthesizer. But today, more and more screen readers also send their output to Braille output devices.

Screen Magnifiers

A screen magnifier is a piece of software that redraws the screen magnified. Simple screen magnifiers (or screen magnifiers in their most basic modes) turn one pixel into multiple pixels -- four, nine, sixteen, or more. The screen then becomes a magnifying lens, and the user pushes the lens around the virtually magnified screen "underneath" it. More sophisticated features include split screens, where only part of the screen is magnified; inverse video (with intelligent color mappings); overlaid cross-hairs for the mouse pointer; and multiple magnified regions.

I/O Devices and the Accessibility API

JFC supports many different kinds of assistive technologies and special I/O devices using an application programming interface called the Accessibility API. Assistive tchnologies use the Accessibility API to get information about Swing applications. Some of those assistive technologies in turn communicate privately with a variety of devices, including speech mechanisms, Braille displays and terminals, and other kinds of special I/O devices.

Interfaces and Classes

The Accessibility API package is made up of eight interfaces and six classes. The main interface in the Java Accessibility API package is the Accessible interface, which must be implemented by every component that supports accessibility. The main class in the Java Accessibility API is the AccessibleContext class, which provides the minimum essential information that all accessible objects must be able to return.

The Accessible Interface

The Accessible interface is an interface that you must apply to a class file to let an ATV program know that you have implemented the Accessibility API. The following code fragment shows the syntax for implementing the Accessible interface:

import com.sun.java.awt;
import com.sun.java.accessibility;

class MyButton implements Accessible extends Component{

     AccessibleContext getAccessibleContext() {
        ...
     }
}

The getAccessibleContext() Method

The Accessible interface contains just one method, named getAccessibleContext(). This is the syntax for calling getAccessibleContext():

   public AccessibleContext getAccessibleContext();

To instantiate an object of the AccessibleContext class, an application calls the getAccessibleContext() method on an object that implements the Accessible interface. When getAccessibleContext()is called, it returns an object of a class known as the AccessibleContext class. This returned object contains a set of fields that describe the accessibility features of the component being inqured about. These fields contain the component's name, characteristics, role, and state, as well as information about the parent and children of the object. JavaBeansTM property-change support is also included to allow assisitive technologies to learn when the values of the accessible properties change.

The information returned by getAccessibleContext() is a basic set of data for defining an accessible object. The getAccessibleContext() is called automatically whenever a program asks for an accessible user-interface object. Note that an accessible object is never created unless it are asked for. Consequently, there is almost no overhead cost to supporting accessibility. Why not? Because an accessible object is never created until it is actually needed by an assistive technology.

The Accessible Interface and Other Interfaces

Along with the Accessible interface, the Java Accessibility API supplies seven other interfaces that can provide an application with more specific accessibility information about accessible components. Each of these seven interfaces works much like the Accessible interface, but each provides a more focused set of data.

For example, the AccessibleAction interface is designed to be implemented by objects that perform actions. AccessibleAction provides a standard mechanism to determine what actions an accessible object must be able to perform, as well as to direct the object to perform those actions. An application can determine whether an object supports the AccessibleAction interface by first calling getAccessibleContext() to obtain the object's AccessibleContext and then calling the AccessibleContext class´s getAccessibleAction() method. If getAccessibleAction() does not return a null, the object being inquired about supports the AccessibleAction interface.

To obtain other kinds of information about accessible objects, you can use other interfaces defined in the Java Accessibility API. Table 1 lists and briefly describes all eight of the interfaces that the Accessibility API provides.

Table 1
Accessibility API Interfaces

Interface

Remarks

Accessible

The main interface in the Java Accessibility API. All components that support the Java Accessibility API must implement this interface. It defines a single method -- getAccessibleContext() -- which returns an instance of the  AccessibleContext class (next item).

AccessibleAction

Provides a mechanism for determining what actions an object can perform. To find out whether an object supports the AccessibleAction  interface, obtain the object´s AccessibleContext and use it to call getAccessibleAction(). If the return value is not null, the object supports this interface.

AccessibleComponent

Provides a mechanism for determining and setting the graphical representation of an object. To find out whether an object supports the AccessibleComponent interface, obtain the object´s AccessibleContext and use it to call getAccessibleComponent(). If the return value is not null, the object supports this interface.

AccessibleSelection

Provides a mechanism for determining what the current selected children are and for modifying the selection set. To find out whether an object supports the AccessibleSelection interface, obtain the object´s AccessibleContext and use it to call getAccessibleSelection(). If the return value is not null, the object supports this interface.

AccessibleText

Provides support for retrieving the attributes of the character at a given position in the text (font, font size, style, etc.), as well as for retrieving the selected text (if any), the length of the text, and the location of the text caret. To find out whether an object supports the AccessibleText interface, obtain the object´s AccessibleContext and use it to call getAccessibleText(). If the return value is not null, the object supports this interface.

AccessibleHypertext

Provides a mechanism for accessing text using its content, attributes, and spatial location. Also provides a mechanism for manipulating hyperlinks. To find out whether an object supports the AccessibleHypertext interface, obtain the object´s AccessibleContext and use it to call getAccessibleHyperext(). If the return value is not null, the object supports this interface.

AccessibleHyperlink

An object that is a hyperlink should support the AccessibleHyperlink interface.  To obtain an object that implements this interface, call the getLink() method on an AccessibleHypertext object.

AccessibleValue

Any object that supports a numerical value (for instance, a scroll bar) should support this interface. It  provides a  mechanism for getting and setting numerical values.  To find out whether an object supports the AccessibleValue interface, use the object´s AccessibleContext to call the getAccessibleValue() method of AccessibleContext. If the return value is not null, the object supports this interface.

 

What the getAccessibleContext() Method Returns

The AccessibleContext information returned by getAccessibleContext() can vary, depending on the role of the GUI class being used. Some methods defined by AccessibleContext can return null values if the methods do not apply in the specific context being used. For example, there is no reason to implement an AccessibleText interface on a scroll bar, so getAccessibleText() (one of the methods listed in Table 2) returns a null when a scroll bar is the object for which a context is being sought.

Table 2 lists the methods supported by AccessibleContext and describes each method.

Table 2
AccessibleContext methods

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. Call this method on all accessible components you want to use in your application.
getAccessibleIndexInParent() Gets the 0-based index of this object in its accessible parent.
getAccessibleName() Gets the AccessibleName property of an object. This property is simply the name of the object.
getAccessibleParent() Gets the AccessibleParent of this object.
getAccessibleRole() Gets the role of this object.
getAccessibleSelection() Gets the AccessibleSelection associated with this object.
getAccessibleStateSet() Gets the state set of this object.
getAccessibleText() Gets the AccessibleText associated with this component. Note: If the retrieved text contains 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. (An object's AccessibleName is simply the name of the object.)
setAccessibleParent(Accessible parent) Sets the accessible parent of this object.


Other Classes

Along with the AccessibleContext class, the Java Accessibility API provides six other classes that encapsulate various kinds of information about accessible objects. Each of these classes is supplied with methods that an application can call to obtain information about accessible objects.

Table 3 lists and briefly describes the seven classes defined in the Java Accessibility API.

Table 3
Classes in the Java Accessibility API

Class

Remarks

AccessibleBundle This class is used to maintain a strongly typed enumeration. It is the superclass of both the AccessibleRole and AccessibleState classes. The toDisplayString() method allows you to obtain the localized string for a locale-independent key from a predefined ResourceBundle for the keys defined in this class.

AccessibleContext

Contains the minimum amount of information that every accessible object should be able to return. Also contains methods for obtaining accessibility information about a component. If the component supports one or more of the interfaces listed in Table 1, methods provided by the AccessibleContext class return an object that implements that interface.

AccessibleRole

This class encapsulates an accessible object's "role" in a user interface. An accessible roles identifies a component's generic function, such as a "pushbutton," "table," or "list." These roles are identified by the constants. To obtain a constant that represents a desired role, call getAccessibleRole() method on an AccessibleContext. 

AccessibleState

This class identifies a particular state of the accessible object. (such as "Armed," "Busy," "Checked,"or "Focused.") The state of a component is defined as an AccessibleStateSet, which is a composed set of AccessibleStates. To obtain a constant that represents a desired role, call the getAccessibleState() method on an AccessibleContext.  

AccessibleStateSet

This class encapsulates a collection of states of an Aacessible object. The state set of a component is a set of AccessibleState objects that describe the current overall state of the object, such as whether it is enabled, whether it has focus, etc. To find out whether such a state is set, call the getAccessibleStateSet() method on an AccessibleContext.

AccessibleHyperlink

Encapsulation of a link or set of links (for example, a client-side image map) in a Hypertext document.

AccessibleResourceBundle

Contains localized strings for the AccessibleRole and AccessibleState classes. This class is provided for internal use by the Java Accessibility API. It is not meant to be used by assistive technologies or applications. Developers normally use the AccessibleRole and AccessibleState classes instead.

 

The Java Accessibility Utilities

In order to provide access to applications written in the Java programming language, an assistive technology requires more than the Java Accessibility API; it also requires a mechanism for locating the objects that implement the API, as well as support for being loaded into the Java Virtual Machine, tracking events, and so on. For developers of accessible applications in the Java programming language, the Java Accessibility Utilities provide this assistance.


NOTE: In JDK 1.2, support for loading assistive technologies into the Java VM is built in; it's only in Sun's JDK 1.1 VM that the Accessibility Utilities perform this task.


Sun provides the Java Accessibility Utilities in a downloadable package that is separate from the Java Accessibility API. This package provides support that assistive technologies need to locate and query user-interface objects inside an application running in a Java Virtual Machine. The Java Accessibility Utilities package also provides support for installing event listeners into user-interface objects. These event listeners are designed to make assistive technologies aware of events occurring in other objects.

The event model used by the Java Accessibility Utilities is the same one that´s used by components in the Swing set -- that is, the delegation event model introduced in JDK1.1. (For more information on how the delegation event model works, see the chapter on handling events in the Java Tutorial.)

Utility Interfaces and Classes

The Java Accessibility Utilities are downloadable as a separate package from the Java Software JFC Web site. This package contains two interfaces and nine classes. The two interfaces are:

  • The GUIInitializedListener interface, which is used by the EventQueueMonitor class to notify an interested party when the GUI subsystem has been initialized.
     
  • The TopLevelWindowListener interface, which is used by the EventQueueMonitor class to notify an interested party when a top-level window is created or destroyed in the Java Virtual Machine.

Table 4 lists and describes the nine classes provided in the Java Accessibility Utilities package. For more details, see the Java Accessibility Utilities API.

Table 4
Classes in the Java Accessible Utilities package

Class

Description

AccessibilityEventMonitor

Implements a PropertyChange listener on every UI object that implements the Accessibility interface in the Java Virtual Machine.

AccessibilityListenerList

Almost exactly like the Swing EventListener class.

AWTEventMonitor

Implements a suite of listeners that are conditionally installed on every AWT component instance in the Java Virtual Machine.

EventID

Contains integer constants that map to event support in AWT and Swing.

EventQueueMonitor

An EventQueue subclass that provides key core functionality for assistive technologies (and other system-level technologies that need some of the same things that assistive technology needs).

GUIInitializedMulticaster

Used to maintain a list of GUIInitializedListener classes.

SwingEventMonitor

Extends AWTEventMonitor by adding a suite of listeners conditionally installed on every Swing component instance in the Java Virtual Machine.

TopLevelWindowMulticaster

Used to maintain a list of TopLevelWindowListener classes.

Translator

The Translator class provides a translation to interface the Accessible interface with objects that do not implement it.



The Java Accessibility Bridge

Some host systems, such as Microsoft Windows, provide accessibility features that are not implemented in the same way as those provided by the Java Accessibility Utilities and the Java Accessibility API. For such existing accessibility technologies to function properly in a Java programming language environment, they need some way to communicate with the Java Accessibility API. For this reason, Sun is developing a special tool -- called the Java Accessibility Bridge to Native Code -- that can make existing accessibility technologies used in Windows applications compatible with the accessibility features offered in the Java Accessibility API and the Java Accessibility Utilities.

The following diagram shows how all these components might work together when development of the Java Accessibility Bridge is complete. You can keep up with the latest news on the Java Accessibility Bridge by checking a special Accessibility Bridge Internet page that´s part of the Java Acessibility Web site.

Java Accessibility Bridge Diagram

Accessibility and Swing's PLAF Design

One important feature of JFC is its pluggable look-and-feel architecture (for details, see the "Getting Started with Swing" article in this issue.) In a nutshell, JFC´s PL&F design separates the implementation of each user-interface component (the component´s model part) from its visual presentation (its view-controller part). Because the presentation of each Swing component is programmatically determined, it can be programmed to be user-selectable.

Because Swing's PLAF architecture is so versatile, the view part of a Swing component doesn't even have to be something that you can see. Although Swing components are usually thought of as being visible widgets, there is nothing in the Swing API that requires a Swing component to be implemented as an image displayed on a screen. Instead of presenting a Swing component visually, the writer of a Swing program can choose to present the view-controller part of the component in the form of an audio announcement or a tactile (Braille) presentation -- or even as some combination of the two.

Because Swing´s model/view-controller design supports such varied options, the creator of a Swing application does not need to turn to a separate "assistive technology" product to supplement the program's  visual presentation on a screen with alternate kinds of presentations. Why not? Because Swing itself provides all that a programmer needs to create whatever kind of presentation is appropriate. Swing components have all the functionality they need to interact with the user in whatever modality the user chooses.

The Multiplexed UI

One very important feature that helps Swing support accessibility is a mechanism called the multiplexed user interface, or multiplexed UI. The multiplexed UI -- an extension of Swing's pluggable look-and-feel architecture -- allows developers and access technology vendors to add multiple alternative user interfaces to the JFC component library when a Java Virtual Machine (JVM) starts.  The multiplexed UI also makes it possible for applications to offer multi-modal access features (such as hands-free voice access to applications) with very little extra development effort. And many kinds of capabilities that can be added to applications using the multiplexed UI are useful to people without disabilities, and well as to people with disabilities. (To learn more about Swing's multiplexed user interfaces, see the article titled "The Multiplexing Look and Feel" in The Swing Connection archive.)


Building Accessible Apps with Swing

The Java Foundation Class (JFC) library, which implements Swing's components, supports accessibility by implementing both basic keyboard accessibility and the Java Accessibility API. Consequently, to build basic support for accessiblity into a JFC program, you can practically use the Swing set right out of the box. There are only a few extra things you need to do to build basic support for accessibility into a Swing application.

Here are some things you should pay attention to when you want to design an accessible application using Swing components (for more details, see the IBM Web page titled "IBM Guidelines for Writing Accessible Applications Using 100% Pure Java"):

  • Provide descriptive component text: Call setAccessibleDescription() to set the accessible descriptions on all accessible components you want to use in your application (see Table 2). (In the Java Accessibility API, AccessibleDescription is a text description of an object's purpose. For example, if the object is a Web page link containing an image, set this to the Universal Resource Locator (URL) string of the target.)

    NOTE: Some JFC components use tool tips to provide this information, even if you don't explictly set the AccessibleDescription of an object. So if your program usse tool-tip text, your task might already be complete.

  • Provide descriptive text for icons and other graphics: For JLabels and JButton classes that contain only images, call setAccessibleName() to set the object's AccessibleName property (see Table 2). (In the Java Accessibility API, the accessible name of an object is simply the object's name.)

    When you want to use an icon in a Swing program that supports accessibity, call JFC's setIcon() method to create a JFC ImageIcon. Then you can use the ImageIcon class's setDescription() method to provide text descriptions of your icons to blind or sight-impaired users. Swing uses ImageIcon objects to place images in many different kinds of components, ranging from JFC buttons to labels. You should also use ImageIcons when you need to insert images into a JTextComponent object or into or JFC components subclassed from JTextComponent.

  • Always set the focus: Make sure that some component in your application has the input focus at all times. If no component has the focus, a screen-reader program can't tell a blind or sight-impaired user what's going on. Most Swing components implement focus-setting mechanisms to support keyboard navigation, so when when you keyboard-enable your Swing application, the Swing API should take care of all focus-setting requirements. But before you ship your app, check to make sure this was done.

  • Set mnemonics on components: Mnemonics are keyboard equivalents for component activation. Whenever you have a component that supports a setMnemonic() method, set the mnemonic to a unique key sequence to activate the object. In a Swing application, it is important that you always set the mnemonic for your app's first JMenuBar entry to allow a disabled user to get there using the keyboard.

  • Set keyboard accelerators in menus: JMenuItem components provide a setAccelerator() method to let you set a keyboard accelerator key. This key lets the user activate a menu item without having to go through the menu. When possible, it is a good (though not mandatory) practice to provide keyboard accelerators.

  • Implement keyboard activation of child JFrames or JInternalFrames: If you build a Java application or applet that manages child frames, provide a keyboard equivalent to let the user cycle the focus to each child frame, or to let the user access these frames from a main menu.

  • Label components properly: When you use Swing's JLabel class to provide a label for a component, call JLabel's setLabelFor() method to associate the component with its label. If both the displayedMnemonic and labelFor properties of a Swing component are set, the component's label calls the requestFocus() method of the component specified by the labelFor property when the appropriate mnemonic is activated.

  • Group objects inside named panels: When objects appear in groups, it's important to group those components logically and to assign each group of components a name. This practice makes it easier for users with disabilities to navigage your application. One way to group a set of components is to add the group to a JPanel and then set the JPanel's AccessibleName property. You can save yourself some trouble by using a JPanel with a JFC TitledBorder. Then you won't have to set the accessible name because the JFC will do that for you.

  • Pay attention to multithreading: Use multithreading to make sure that your program supports the simultaneous execution of multiple assistive technologies. For example, if your client application is dependent on a server action, design your app in such a way that it lets other threads run at the same time, even while it waits for the server to respond.
These simple tips are all you need to make sure that your app meets all the essential accessibility programming requirements. If you like, of course, you can do more. But if you do only what's outlined above, JFC will take care of the rest!


The Easy Path to Accessibity

In conclusion, to build an accessible application with the least amount of effort, do the following:

  • Build your application using JFC and Swing.

  • If the rich class library in the JFC does not have a component that meets your needs, create your hybrid component from the JFC JComponent class and implement the Accessibility API on your component. The JFC comes with source code, and the Accessibility API provides many examples that you can base your implementation on.

  • If Steps 1 and 2 don't meet your needs, implement the Accessibility API on your class library or component.

  • Use an accessibility tool to test your application for accessibility. The Java Accessibility Utilities contain a set of tools that you can use to help test the accessibility of your application. You can download the Java Accessibility Utilities from the Java Software Web site.
[an error occurred while processing this directive]