Accessibility Support for the Java PlatformMarch 1998This paper provides an overview of Sun Microsystems efforts to build disability access into the Java platform. It also delves into significant detail about various aspects of the Java Accessibility effort. It is assumed that the reader is familiar with object oriented programming in general, and the Java programming language and application environment in particular. Without such a background, the reader should nonetheless find the high level discussion of Sun's Java Accessibility work worthwhile. Contents:
IntroductionThere are four areas in which Sun is currently building support for Accessibility into the Java platform: the Java Accessibility API, the Java Accessibility Utilities, the Java Accessibility Bridge, and the Pluggable Look and Feel of the Java Foundation Classes. This work comes out of an in-depth review of accessibility requirements for the Java platform as specified in an evaluation and report commissioned by Sun in March, 1996, a 3 day meeting hosted by Sun in February, 1997, the expertise and background knowledge of the members of the Sun Accessibility team, and the ongoing feedback from assistive technology vendors and the larger disability community. This support is scheduled to be available in final form in 1998 in two separate versions. The first version will support the current release of the Java Development Kit (JDK1.1), and the second version will support the next release of the Java Development Kit (JDK1.2). Early Access releases of Sun's support in most, if not all, of these areas, are already available publicly on the Internet, and Sun will continue to release interim versions for public review and feedback until the final release in 1998. The following four sections give a brief overview of the four areas of support for Java Accessibility that Sun is currently developing. They are each described in detail in the body of this paper. The Java Accessibility APIThe Java Accessibility API defines a contract between the individual user interface components that make up a Java application and an assistive technology that is providing access to that Java application. If a Java application fully supports the Java Accessibility API, then it should be compatible with, and friendly toward, assistive technologies such as screen readers, screen magnifiers, etc. With a Java application that fully supports the Java Accessibility API, no off screen model would be necessary because the API provides all of the information normally contained in an off screen model. The Java Accessibility UtilitiesIn order to provide access to Java applications, an assistive technology requires more than the Java Accessibility API: it also requires support in locating the objects that implement the API as well as support for being loaded into the Java Virtual Machine, tracking events, etc. The Java Accessibility Utilities provide this assistance. The Java Accessibility BridgeJava applications run on a wide variety of host operating systems, many of which already have assistive technologies available for them (e.g. Macintosh, OS/2, Microsoft Windows). In order for these existing assistive technologies to provide access to Java applications, they need a bridge between themselves in their native environment(s), and the Java Accessibility support that is available from within the Java Virtual Machine (or Java VM). This bridge, by virtue of the fact that it has one end in the Java VM and the other on the native platform, will be slightly different for each platform it bridges to. Sun is currently developing a bridge for the Win32 platform. In cooperation with assistive technology vendors and the various platform vendors, Sun intends to make similar bridges available for other platforms over time. The Pluggable Look and Feel of the Java Foundation ClassesThe Java Foundation Classes (or JFC) are a collection of technologies that represent a new foundation upon which to build Java applications. The JFC will be part of the core of the JDK, starting with JDK1.2. The Java Accessibility API is one of the technologies of the JFC. Another is the "Swing" set of user interface components, which is built using a Pluggable Look and Feel architecture. This architecture separates the implementation of the user interface components from their presentation. On a component-by-component basis, the presentation is programmatically determined, and can be chosen by the user. Instead of a visual presentation, a user could instead choose an audio presentation, or a tactile (e.g. Braille) presentation, or a combination of the two. With this support, a user wouldn't need a separate assistive technology product interpreting the visual presentation of the program on the screen, but would instead have direct access to that program because it would interact with the user in his/her desired modality. The remaining sections of this document describe each of these features in more detail. The Java Accessibility APIThe Java Accessibility API is being delivered by Sun in two forms. In the first form, the Java Accessibility API is shipped with the 1.1 release of the Java Foundation Classes. The API is in the package, com.sun.java.accessibility, and is ready to run as a downloadable package on the browsers and Java Virtual Machines that are being currently deployed (for example, in the new Netscape browser), which fully support JDK1.1. In the second form, the Java Accessibility API will be delivered as a core part of the platform in the package java.awt.accessibility. As a result, every Java Virtual Machine that supports JDK1.2 will have the Java Accessibility API package already installed. The Java Accessibility API package consists of 8 Java programming language interfaces and 6 Java programming language classes. These are described below. A detailed examination of the Java Accessibility API is in Appendix A of this paper. Interface AccessibleInterface Accessible is the main interface of the Java Accessibility API. All components that support the Java Accessibility API must implement this interface. It contains a single method, Class AccessibleContextAccessibleContext represents the minimum information all accessible objects return and is obtained by calling the
In the future, additional interfaces (e.g., AccessibleTable and AccessibleLayout) may be added, and the abstract class AccessibleContext will be updated accordingly. Class AccessibleRoleThis class encapsulates the Accessible object's role in the user interface and is obtained by calling the In addition, the AccessibleRole constants provide a method called Class AccessibleStateThis class encapsulates a particular state of the Accessible object. Accessible states include things like "Armed", "Busy", "Checked", "Focused", etc. These roles are identified by the constants in this class such as The constants in this class present a strongly typed enumeration of common object roles. A public constructor for this class has been purposely omitted and applications should use one of the constants from this class. Although this class pre-defines a large list of standard roles, it is extensible so additional, programmer-defined roles can be added in the future without needing to modify the base class. Like AccessibleRole, the AccessibleState constants provide a method called Class AccessibleStateSetThis AccessibleStateSet class encapsulates a collection of states of the Accessible object and is obtained by calling the Class AccessibleBundleThis AccessibleBundle class is used to maintain a strongly typed enumeration. It is the super class of both the AccessibleRole and AccessibleState classes. Programmers normally do not interact with this class directly, but will instead use the AccessibleRole and AccessibleState classes. Class AccessibleResourceBundleThis AccessibleResourceBundle class contains the localized strings for the AccessibleRole and AccessibleState classes. Like AccessibleBundle, programmers normally do not interact with this class directly, but will instead use the AccessibleRole and AccessibleState classes. Interface AccessibleActionThe AccessibleAction interface should be supported by any object that can perform one or more actions. This interface provides the standard mechanism for an assistive technology to determine what those actions are as well as tell the object to perform those actions. Any object that can be manipulated should support this interface. Applications can determine if an object supports the AccessibleAction interface by first obtaining its AccessibleContext (see Accessible) and then calling the Interface AccessibleComponentThe AccessibleComponent interface should be supported by any object that is rendered on the screen. This interface provides the standard mechanism for an assistive technology to determine and set the graphical representation of an object. Applications can determine if an object supports the AccessibleComponent interface by first obtaining its AccessibleContext (see Accessible) and then calling the Interface AccessibleSelectionThis AccessibleSelection interface provides the standard mechanism for an assistive technology to determine what the current selected children are, as well as modify the selection set. Any object that has children that can be selected should support this the AccessibleSelection interface. Applications can determine if an object supports the AccessibleSelection interface by first obtaining its AccessibleContext (see Accessible) and then calling the Interface AccessibleTextInterface AccessibleText is the contract for making rich, editable text Accessible. Not all text displayed on the screen is rich and editable (e.g. text contained in buttons, labels, menus, etc., which users aren't expected to manipulate). However, objects containing editable text must implement interface AccessibleText if they are to interoperate with assistive technologies. This interface provides support for going between pixel coordinates and the text at a given pixel coordinate, for retrieving the letter, word, and sentence at, before, or after a given position in the text. This interface provides support for retrieving the attributes of the character at a given position in the text (font, font size, style, etc.), as well as getting the selected text (if any), the length of the text, and the location of the text caret. Applications can determine if an object supports the AccessibleText interface by first obtaining its AccessibleContext (see Accessible) and then calling the Interface AccessibleValueThe AccessibleValue interface should be supported by any object that supports a numerical value (e.g., a scroll bar). This interface provides the standard mechanism for an assistive technology to determine and set the numerical value as well as get the minimum and maximum values. Applications can determine if an object supports the AccessibleValue interface by first obtaining its AccessibleContext (see Accessible) and then calling the Interface AccessibleTableThe AccessibleTable interface is currently up for review and should only be used for experimental purposes. It is meant to be supported by an object that presents a table to the user. Interested parties should review this interface and send comments to access@sun.com. Based upon feedback from reviewers, we may add a method to AccessibleContext (e.g., Interface AccessibleLayoutThe AccessibleLayout interface is currently up for review and should only be used for experimental purposes. It is meant to be supported by an object that provides a spatial layout of its children on the screen. Interested parties should review this interface and send comments to access@sun.com. Based upon feedback from reviewers, we may add a method to AccessibleContext (e.g., An alternative consideration for the AccessibleLayout interface is to not make it part of the AccessibleContext class, but instead use it to develop a separate utility class that navigates through objects on the screen. Because an implementation of such an object is subject to interpretation (any given vendor might disagree with the logic for determining what objects are "above" and "below" others, for instance), Sun designed this object to be replaceable: the assistive technology may simply substitute for the Sun default any object that implements the interface. We're interested in the feedback you may have on these two approaches and will gladly read any mail you send to access@sun.com. The Java Accessibility UtilitiesThe Java Accessibility Utilities are delivered by Sun as a separately downloadable package for use by assistive technology vendors in their products which provide access to Java applications running in a Java Virtual Machine. This package provides the necessary support for assistive technologies to locate and query user interface objects inside a Java application running in a Java Virtual Machine. It also provides support for installing "event listeners" into these objects. These event listeners allow objects to learn about specific evens occurring in other objects using the peer-to-peer approach defined by the delegation event model introduced in JDK1.1. Finally, this package provides specific support for loading assistive technologies into a Java Virtual Machine based on JDK1.1. We expect this functionality won't be needed in future releases of the JDK, as that support will be in those releases. This package is still in active development, and is not as fully defined as the Java Accessibility API. This package is made up of the following major pieces: Key information about the Java Application(s)This package contains methods for retrieving key information about the Java application(s) running in the Java Virtual Machine. This support provides a list of the top-level windows of all of the Java applications, an event listener architecture to be informed when top level windows appear (and disappear), and means for locating the window that has the input focus, locating the mouse position, and inserting events into the system event queue. In order to provide this support immediately for the JDK1.1 environments, Sun took advantage of an implementation detail in the Sun reference implementation of the JDK. In the Sun implementation, the system-wide EventQueue can be replaced with an alternate one. The Java Accessibility Utilities provide an alternate system EventQueue in the class EventQueueMonitor that implements the functionality described previously. Sun expects to have the functionality provided in EventQueueMonitor in the next release of the Java Development Kit (JDK1.2), so this support will only be needed here for use in JDK1.1 environments. Unfortunately, because the ability to replace the system EventQueue was not part of the JDK1.1 specification released in February, 1997, Sun cannot require that JDK1.1 environments from other vendors support a replaceable system EventQueue. However, Sun is working with these companies to help them include the support for assistive technologies provided by the EventQueueMonitor class prior to their adoption of the next release of the JDK. Automatic Loading of Assistive TechnologiesIn order for an assistive technology to work with a Java application, it needs to be loaded into the same Java Virtual Machine as the Java application it is providing access to. This is done by extending the class libraries to look for a special configuration line in the awt.properties file specifying a list of assistive technology classes to load. This support is in the class EventQueueMonitor, which is a replacement for the system event queue. As stated above, the EventQueueMonitor implementation is dependent upon specific details of the Sun reference implementation of the JDK1.1 Java Virtual Machine, and not on the formal specification. Because of this, automatic loading of assistive technologies may not work in all JDK1.1 environments. The automatic loading of assistive technologies is part of the JDK1.2 specification, however, so this support will be in all Java Virtual Machines that support JDK1.2. Event SupportThe Java Accessibility Utilities include two classes for monitoring events in the Java Virtual Machine. The first class, AWTEventMonitor, provides a way to monitor all AWT events in all AWT components running in the Java Virtual Machine. This class essentially provides system-wide monitoring of AWT events, registering an individual listener for each AWT event type on each AWT component that supports that type of listener. Thus, an assistive technology can register a "Focused listener" with AWTEventMonitor, which will in turn register a "Focused listener" with each and every AWT component in each and every Java program in the Java Virtual Machine. Those individual listeners will funnel the events they hear about to the assistive technology that registered the listener with AWTEventMonitor in the first place. Thus, whenever a component gains or loses focus (e.g. the user hits the TAB key), the assistive technology will be notified. The second class, SwingEventMonitor, extends AWTEventMonitor to provide additional support for monitoring the Swing events supported by the Swing components. Since SwingEventMonitor extends AWTEventMonitor, there is no need to use both classes if you are using SwingEventMonitor in your assistive technology. A list of all of the events supported by the Java Accessibility Utilities is in Appendix B of this paper. AWT TranslatorsWith the release of the Java Foundation Classes (JFC), many developers who were using the AWT to build the user interfaces of their Java applications will switch to the new Swing classes in the JFC. Many will also update their existing AWT programs to Swing. Still, a significant number of Java applications will remain using some AWT components for displaying their user interfaces. The Java Accessibility Utilities contain a set of classes which implement the Java Accessibility API on behalf of AWT components - in effect translating for them! These translators work in concert with the support for finding Accessible components in the first place, which is part of the EventQueueMonitor method getAccessibleAt. If the object at that location isn't an actual instance of an Accessible, the getAccessibleAt method looks for a Translator that will implement the Accessible interface on behalf of that component. Like much of the rest of the Java Accessibility support, the translator architecture is completely extensible. Any programmer can create a translator. As long as the user's environment is configured properly, the Java Accessibility utility classes will automatically find the new translator and engage it. This means that both mainstream developers and assistive technology vendors can create and distribute new Accessible Translators, making formerly inaccessible user interface components accessible in the process. Sample Source CodeIn addition to the utility classes and translator architecture, the Java Accessibility Utilities includes several example assistive technology programs. The example programs include programs that monitor AWT and Swing events, a program that fully exercises the Java Accessibility API for the component underneath the mouse, and a program that traverses the component hierarchy, displaying the entire hierarchy in tree view. The Java Accessibility Bridge to Native CodeIn order for existing assistive technologies available on host systems (e.g. Microsoft Windows, Macintosh, OS/2) to provide access to Java applications, they need some way to communicate with the Java Accessibility support in those Java applications. The Java Accessibility Bridge supports that communication. This bridge is a class which contains "native methods." Part of the code for the class is actually supplied by a DLL on the host system - Solaris, OS/2, Microsoft Windows, Macintosh, etc. The assistive technology running on the host (e.g., a Macintosh screen reader) communicates with the Macintosh native DLL portion of the bridge class, which in turn communicates with the Java Virtual Machine, and from there to the Java Accessibility utility support and the Java Accessibility API on the individual user interface objects of the Java application it is providing access to. A diagram of how all of these components work together is shown below.
For example, in order for a screen reader for Microsoft Windows to provide access to Java applications running on that system, that screen reader would make calls to the Java Accessibility Bridge for Microsoft Windows. If/when a the user launched a Java application, the bridge would inform the screen reader of this fact. Then the screen reader would query the bridge about the Java application and the bridge would in turn forward those queries on to the Java Accessibility Utilities that were loaded into the Java Virtual Machine, and in many cases on to the individual user interface object that implemented the Java Accessibility API. When those answers came back to the bridge, the bridge would forward them on to the screen reader for Microsoft Windows, which would then use the answers to tell the user what was going on in the Java application. The Pluggable Look and FeelThe three areas Sun is working in on Java Accessibility discussed previously are all focused on three different facets of the problem of providing interoperability between assistive technologies and Java applications. While this work is absolutely critical -- virtually all users with disabilities today use specialized access software and hardware operating between them and mainstream software/hardware -- it doesn't provide fundamentally different access from what came before. Even though use of the Java Accessibility API eliminates the need for an off screen model, a screen reader using the Java Accessibility API would still be a screen reader: it would still be reading with speech and/or Braille the visual presentation of a program. The Java Foundation Classes' "Swing" user interface building blocks are designed around a Pluggable Look and Feel architecture that allows us for the first time to get away from interpreting the visual manifestations, and instead "plug in" a non-visual manifestation. This architecture separates the expression of the user interface from the underlying structure and data on a component-by-component basis. This is accomplished by separating the user interface of the component from the "model" of the component (the structure which encapsulates the state and information that the user interface portion presents to the user). Prior to the Pluggable Look and Feel, the non-mainstream user had two options: specialized software closely tailored to their non-mainstream modality (e.g. a talking web browser), or a specialized access application (e.g. a screen reader) which interpreted and re-presented the visual presentation of mainstream applications. With the Java Foundation Classes and Swing, we now have a third option: direct presentation in non-mainstream modalities of mainstream applications. How the Swing classes provide a Pluggable Look and FeelFor each component in Swing, there are actually (at least) five Java programming language objects that are needed to make that Swing component pluggable. These are: the component itself (e.g., a button); the Java programming language interface that defines the user interface (e.g., the button's UI); a default implementation of that user interface (e.g., the Basic Button); a Java programming language interface that defines the model of the component (e.g., the Button model); and finally, a default implementation of that model (e.g., the Swing Button model). For most uses of a given Swing component (e.g., a Button), the programmer doesn't need to know or care about any Swing object other than the first of the five listed above. The programmer simply creates a new instance of the first object of the five, and writes code to interact with it. The others are created automatically based upon the settings on the user's machine. By default, the choice of which user interface and model to use is made in the user's preferences files, where an entire "factory" of user-interfaces and models is specified by the user. What Swing providesIn order to make it easy to migrate from the user interface classes in the AWT to the new Swing user interface classes, Swing provides a parallel set of user interface classes to those in AWT. Each Swing class that has a parallel in the AWT bears a name that is identical to the AWT name, except that the letter "J" is prepended to it. Otherwise, each parallel user interface object contains a superset of the public methods and variables of the corresponding AWT class. There are roughly 55 user interface building blocks in Swing, including the common items such as buttons, check boxes, radio buttons, combo boxes, menus, and labels, as well more sophisticated items such as tooltips, tabbed panes, tree views, table views, editable text fields, HTML editors, a Color Chooser, a Money Chooser, etc. Each of these Swing user interface classes fully supports the Pluggable Look and Feel architecture. Providing Direct Accessibility in SwingIn order to get direct access to a Swing program via a non-mainstream modality (e.g., audio, Braille, etc.), the user would need a factory containing a set of user interface classes installed on their system for each of the Swing classes listed above. Then the user would need to specify that this replacement set be used in the appropriate properties file. Finally, the user would need to run Swing programs that didn't explicitly bar the use of alternate user interface factories. In setting this up, the user has three options: complete replacement of a mainstream user interface with their alternate one(s); having the mainstream interface and the alternate interface(s) working simultaneously (e.g., visual and audio) through the use of the special multiplexing user interface factory supplied by Sun; or finally, by choosing on a component-by-component basis which user interface class to use. The Road AheadWork remaining in the four areas of current Java Accessibility focusBetween now and the next release of the Java Development Kit (JDK1.2), expected in 1998, the Java Accessibility team will be finishing work in the four areas we are currently focusing on. Below is a brief overview of what remains in those areas:
Areas to focus on in the futureWhile the four areas in Java Accessibility that Sun is focusing on now are the key core areas, there are other parts of the Java platform that need to be addressed from an Accessibility point of view. That focus isn't possible until there is a defined Java Accessibility API, support for assistive technologies to get at that API, and a Pluggable Look and Feel architecture. But once those pieces are released, it will be time to focus on these other areas. They are as follows:
Appendix A: The Java Accessibility API in detailThe Java Accessibility API package consists of 8 interfaces and 6 classes. These are described below. Please refer to the JavaDoc documentation for more detail on these interfaces. Interface AccessibleInterface Accessible is the main interface of the Java Accessibility API. All components that support the Java Accessibility API must implement this interface. It contains a single method, Interface AccessibleContextAccessibleContext represents the minimum information all accessible objects return and is obtained by calling the
Class AccessibleRoleThe AccessibleRole class extends the class AccessibleEnumeration, which contains the actual methods for retrieving the role text, comparing one role to another, etc. The work is done in the protected constructor, which creates an AccessibleRole with the given String. All of the constants below are the pre-defined AccessibleRoles.
AccessibleStateThe AccessibleState class also extends the class AccessibleEnumeration, which contains the actual methods for retrieving the state text, comparing one state to another, etc. The work is done in the protected constructor, which creates an AccessibleState with the given String. All of the constants below are the pre-defined AccessibleStates.
Class AccessibleStateSetThe AccessibleStateSet class is meant to be a read only class for assistive technologies. As a result, the only methods an assistive technology should use from the AccessibleStateSet are the methods for querying the contents of the state set. The remaining methods are meant to be used by component developers, and provide convenient methods that allow a component developer to populate a state set when the
Class AccessibleBundleThe AccessibleBundle class contains the core functionality in both AccessibleRole and AccessibleState (both extend it). It is an abstract class that cannot be used directly.
Class AccessibleResourceBundleThe AccessibleResourceBundle class contains extends the class java.util.ListResourceBundle to provide localized strings for the AccessibleRole and AccessibleState classes. It is not meant to be used directly. Interface AccessibleActionThese Interface AccessibleAction methods return the number and descriptions of actions that a given object supports, and programmatically support executing those actions. These methods can only be used on a non-null object returned by the int getAccessibleActionCount(); String getAccessibleActionDescription(int i); boolean doAccessibleAction(int i); Interface AccessibleComponentThese Interface AccessibleComponent methods come from the AWT Component object - the object from which most objects that are part of a user interface derive. These aren't all of the methods in AWT Component, but they are the ones that have Accessibility implications, and Sun feels that every Accessible object should implement them. There's also an additional method, Color getBackground(); void setBackground(Color c); Color getForeground(); void setForeground(Color c); Cursor getCursor(); void setCursor(Cursor c); Font getFont(); void setFont(Font f); FontMetrics getFontMetrics(Font f); boolean isEnabled(); void setEnabled(boolean b); boolean isVisible(); void setVisible(boolean b); boolean isShowing(); boolean contains(Point p); Point getLocationOnScreen(); Point getLocation(); void setLocation(Point p); Rectangle getBounds(); void setBounds(Rectangle r); Dimension getSize(); void setSize(Dimension d); boolean isFocusTraversable(); void requestFocus(); void addFocusListener(FocusListener l); void removeFocusListener(FocusListener l); Accessible getAccessibleAt(Point p); Interface AccessibleSelectionThese Interface AccessibleSelection methods provide support for querying the selection(s) of an Accessible object, and adding/removing items from the selection on that object. These methods can only be used on a non-null object returned by the int getAccessibleSelectionCount(); Accessible getAccessibleSelection(int i); boolean isAccessibleChildSelected(int i); void addAccessibleSelection(int i); void removeAccessibleSelection(int i); void clearAccessibleSelection(); void selectAllAccessibleSelection(); Interface AccessibleTextThe following methods and constants specify Interface
AccessibleText, broken down into groups of similar functionality. These methods can only be used on a non-null object returned by the
Interface AccessibleValueThese Interface AccessibleValue methods return information about the current numerical value and also allows the current value to be set. These methods can only be used on a non-null object returned by the Number getCurrentAccessibleValue(); boolean setCurrentAccessibleValue(Number n); Number getMinimumAccessibleValue(); Number getMaximumAccessibleValue(); Appendix B: Events in the Java Accessibility UtilitiesBoth the AWT and Swing packages define a set of standard events for use in communicating changes in user interfaces build with these packages. The Java Accessibility Utilities provide system-wide access to these events (which are normally only available on an object-by-object basis). These support is provided by the two classes AWTEventMonitor and SwingEventMonitor in the Java Accessibility Utilities package. Below is the list of AWT events the AWTEventMonitor class provides access to:
The SwingEventMonitor class extends the AWTEventMonitor class. As a result, it provides access to all the events AWTEventMonitor does. As a result, if you use the SwingEventMonitor class, you do not need to use the AWTEventMonitor class. In addition, it provides access to the following Swing events:
In addition, the Swing components are also JavaBeans, so the SwingEventMonitor class also supports the following JavaBeans events:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||