Sun Java Solaris Communities My SDN Account Join SDN
 
Article

What's New with Accessibility

 
 

Articles Index


Image of Sun in WindowThis article describes some recent accessibility enhancements in Version 1.3 of the Java 2 Platform, Standard Edition. It also presents coding examples that show you how to use these enhancements. "Accessibility" here means making the graphical components of a program's user interface available to screen readers, "hands-free" pointing devices, and other assistive technologies that are used by people with disabilities. So if you're a developer interested in making the user interface of your program accessible to people with disabilities, read on.

On July 26, 2000, the Americans with Disabilities Act (ADA) celebrated its tenth anniversary. The act prohibits discrimination and ensures equal opportunity for persons with disabilities in employment, state and local government services, public accommodations, commercial facilities, and transportation. The ADA act has had a significant impact not only on people with disabilities, but also on the general public who benefit from the creativity and skill of people with disabilities. As Attorney General, Janet Reno notes "Over the past decade so much has changed. It is no longer unusual to see people with disabilities dining out in restaurants, working in the office, participating in town hall meetings, shopping at the malls, watching a movie or cheering at a stadium. That's because the ADA is making the dream of access a reality."

The Role of Java Technology

Java technology has played an important role in facilitating the promise of the ADA as it applies to computing and computer usage. Together with tools such as screen readers and hands-free pointing devices, Java technology is helping make computing and computer usage a reality for people with disabilities. Consider, for example, a sight-impaired programmer who uses a screen reader to describe the components of a program's graphical user interface. Or think of a quadriplegic who depends on a hands-free pointing device to update a spreadsheet. These tools, also called assistive technologies, need access to the characteristics of the displayed content. In other words, the screen reader needs to know that a component is a button rather than a text field; the pointing device needs to distinguish each column of the spreadsheet. And that's where Java technology comes in. Through the Java Accessibility API, application developers can easily make the characteristics of a program's user interface available to assistive technologies. The Java Accessibility API is defined in the javax.accessibility package.

In addition, Java Accessibility Utilities help assistive technologies monitor component-related events. They also help assistive technologies get additional information about the GUI, such as the current position of the mouse, or the window that currently has focus.

Recently some important accessibility enhancements have been made in Version 1.3 of Java 2 Platform, Standard Edition (J2SE). These include additions to the Java Accessibility API and the Java Accessibility Utilities. Also, there are two new accessibility-related tools: the Java Access Bridge for the Microsoft Windows Operating System, and the Java Accessibility Helper. The Java Access Bridge Version 1.0 has been released; and the Java Accessibility Helper is available as part of the Early Access Release Program.

Let's take a look at these enhancements. But first, let's briefly examine the basics of using the Java Accessibility API and Java Accessibility Utilities.

Using the Java Accessibility API

The Accessibility API comprises a set of interfaces and classes. The main interface is the Accessible interface; all components that support accessibility must implement this interface. The Accessible interface defines one method, getAccessibleContext. When called on an accessible component, getAccessibleContext returns an AccessibleContext object. This object contains a basic set of accessibility information about the component, such as the component's accessible name, description, role, parent, and children, as well as the component's state, for example, if the component is a window, AccessibleContext indicates whether the window is active.

Support for the Accessibility API is built into Java Foundation Classes (JFC) Swing . Most Swing components, such as JButton and JTextArea, implement the Accessible interface. (In J2SE version 1.3, accessibility support has been extended to the Abstract Windowing Toolkit, but more about that later.)

Here's how you use the Accessibility API. Suppose you have a simple application that displays a button.

Simple Button


import java.awt.*;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class SimpleButton extends JPanel {
    
  public SimpleButton() {
     JButton aButton = new JButton("Button");
     add(aButton);
  }

  public static void main(String[] args) {
      JFrame frame = new JFrame("SimpleButton");
      frame.getContentPane().add(new SimpleButton(), 
                             BorderLayout.CENTER);
      frame.pack();
      frame.setVisible(true);
    }
}

You can use the setAccessibleName and setAccessibleDescription methods of AccessibleContext to set an accessible name and description for the button.
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.accessibility.*;

public class AccessSimpleButton extends JPanel {
    
    public AccessSimpleButton() {
        JButton aButton = new JButton("Button");
       aButton.getAccessibleContext().         
                setAccessibleName("Button");    
        String desc = "This is a simple button";
        aButton.getAccessibleContext().         
                setAccessibleDescription(desc); 
        add(aButton);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame(
                                 "AccessSimpleButton");
        frame.getContentPane().
                          add(new AccessSimpleButton(), 
                                  BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}

In reality, it's not usually necessary to manually set an accessible name as shown in the previous example. That's because default accessible names exist for Swing components. For example, the default accessible name for the JButton class is the JButton label.

Back to Top

Note, you would only want to set an accessible description if the accessible name of an object doesn't do a good job of describing the object. However, if you do need to provide an accessible description for a Swing component, you can also provide it by assigning the component a tool tip. For example, you can give the button in the previous example an accessible description as follows:

aButton.setToolTipText("This is a simple button");

To retrieve the accessible name and description, use the getAccessibleName and getAccessibleDescription methods of AccessibleContext. For example:
   String buttonname = 
                aButton.getAccessibleContext().
                           getAccessibleName();
   String buttondesc = 
                aButton.getAccessibleContext().
                    getAccessibleDescription(); 

AccessibleContext has methods to set or get the following basic accessible information about a component:
  • Name (setAccessibleName, getAccessibleName)
  • Description (setAccessibleDescription, getAccessibleDescription)
  • Role (get AccessibleRole)
  • Parent (setAccessibleParent, getAccessibleParent, getAccessibleIndexInParent)
  • Children (getAccessibleChild, getAccessibleChildrenCount)
  • State (getAccessibleStateSet)
  • Relationship with other components (getAccessibleRelationSet)

In addition to methods for setting and getting basic accessibility information, AccessibleContext has methods for retrieving information about components that have special types of characteristics. For example, a component that displays text can make the text accessible to an assistive technology by implementing the AccessibleText interface; the getAccessibleText method of AccessibleContext returns the accessible text for a component that implements the AccessibleText interface. An assistive technology could then use AccessibleText interface methods to perform actions on the text, such as retrieve selected text. The following table lists the AccessibleContext methods that retrieve special accessibility information. These methods return objects that implement various accessibility-related interfaces. The interfaces are also listed in the table, along with a brief description of how an assistive technology could use the interfaces:

Method Interface Usage
getAccessibleAction AccessibleAction Specify actions for the component to perform.
getAccessibleComponent AccessibleComponent Get the graphical representation of a component.
getAccessibleSelection AccessibleSelection Determine currently selected children of the component.
getAccessibleText AccessibleText Get accessible text for the component.
getAccessibleValue AccessibleValue Get the numerical value for the component.

Using the Java Accessibility Utilities

Like the Accessibility API, the Java Accessibility Utilities comprise a set of interfaces and classes. One class, EventQueueMonitor, provides core functions needed by assistive technologies. For example, the isGUIInitialized method in EventQueueMonitor checks whether the GUI subsystem is initialized (an assistive technology needs to know this before it attempts to display a GUI). EventQueueMonitor implements the GUIInitializedListener interface.

Back to Top

Here's an example that uses EvenQueueMonitor. The example code is extracted from a sample assistive technology, named "Ferret," that is packaged with the Java Accessibility Utilities. Ferret, like the other sample assistive technologies, is designed to show you how the Java Accessibility Utilities can be used in a program. Among other things it can do, Ferret is able to follow the mouse pointer as it moves across a user interface. When the mouse pointer points at a component in the interface, Ferret gets the accessible information for the component. This task is also important for assistive technologies such as hands-free pointing devices.

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.accessibility.*;
import com.sun.java.accessibility.util.*;

...

public class Ferret implements MouseMotionListener, 
        FocusListener, CaretListener, KeyListener, 
        ActionListener, MenuListener,
        GUIInitializedListener {   
...

// Create the GUI
    //
    public Ferret() {
    if (EventQueueMonitor.isGUIInitialized()) {     
           createGUI();
    } else {
       EventQueueMonitor.addGUIInitializedListener( 
                                                 this); 
        }
    }
...

    // Update (and speak) what's under the mouse
    //   
    public void updateAccessibleAtMouse() {
        Point currentMousePos = EventQueueMonitor.
                              getCurrentMousePosition();
        Accessible a = null;
        if (activeMenu != null) {
            JPopupMenu pm = activeMenu.getPopupMenu();
            Point menuLoc = pm.getLocationOnScreen();
            Point menuPoint = new Point(
                 currentMousePos.x - menuLoc.x, 
                 currentMousePos.y - menuLoc.y);
                Component c = pm.getComponentAt(
                                  menuPoint);
                if (c instanceof Accessible) {
                    a = (Accessible) c;
                } 
        }
        if (a == null) {
            a = EventQueueMonitor.getAccessibleAt
                                  (currentMousePos);
        }
        if (a != null) {
        AccessibleContext ac = a.getAccessibleContext();
            Point containerPoint = null;
              if (ac != null) {
              AccessibleComponent acmp = 
                            ac.getAccessibleComponent();
              if (acmp != null) {
              Point containerLoc = 
                             acmp.getLocationOnScreen();
              if (containerLoc != null) {
                  containerPoint = 
                  new Point(
                     currentMousePos.x - containerLoc.x,
                     currentMousePos.y - containerLoc.y);
                 } 
              }
              apiPanel.updateInfo(ac, containerPoint);

...

    // Start the whole shebang going 
    //   
    static public void main(String args[]) {
...  

        new Ferret();
    }

Ferret uses the EventQueueMonitor getCurrentMousePosition method to determine the current mouse position, and getAccessibleAt method to get the Accessible object at that position. After it gets the object, Ferret gets the AccessibleContext for the object, and gets the accessible information from the AccessibleContext. The calls to AccessibleContext methods such as getAccessibleName are in the apiPanel.updateInfo method. apiPanel is an instance of AccessibilityAPIPanel, which is supplied in the Accessibility Utility package along with the sample assistive technologies. Here's the code in apiPanel.updateInfo that retrieves the accessible information from the AccessibleContext object:
mouseInformation = new java.awt.List(lines);

mouseInformation.add("interface AccessibleContext:");
            mouseInformation.add("    Name:  " + 
                             ac.getAccessibleName());
            mouseInformation.add("    Desc:  " + 
                      ac.getAccessibleDescription());
            mouseInformation.add("    Role:  " + 
                             ac.getAccessibleRole());
            mouseInformation.add("    State(s): " + 
                         ac.getAccessibleStateSet());
try {
            mouseInformation.add("    Locale: " + 
                                     ac.getLocale());
...
	    
            Accessible parent = ac.
                              getAccessibleParent();
            if (parent != null) {
                AccessibleContext ap = parent.
                             getAccessibleContext();
...		
		
            }

            mouseInformation.add("    # Children: " + 
                     ac.getAccessibleChildrenCount());

            if (parent != null) {
                AccessibleContext ap = parent.
                              getAccessibleContext();
                Accessible sibling = 
                              ap.getAccessibleChild(
                  ac.getAccessibleIndexInParent()+1);
                  if (sibling != null) {
                    AccessibleContext as = sibling.
                    getAccessibleContext();
                    mouseInformation.add(
                     "    Next Sibling's Name: " + 
                             as.getAccessibleName());
                  }
...		
            }
            

Notice that Ferret also calls getAccessibleComponent on the AccessibleContext. This returns an object that implements the AccessibleComponent interface. This allows Ferret to retrieve information such as the object's background color and font. Again, Ferret uses apiPanel to get this information; here's the applicable code:
           //
           // AccessibleComponent
           //
            AccessibleComponent acp = 
                           ac.getAccessibleComponent();
            if (acp != null) {
                mouseInformation.add(
                     "interface AccessibleComponent:");
                mouseInformation.add(
                     "    Background Color: "  
                                + acp.getBackground());
                mouseInformation.add(
                     "    Foreground Color: " + 
                                  acp.getForeground());
                mouseInformation.add(
                     "    Cursor: " + acp.getCursor());
                Font font = acp.getFont();
                mouseInformation.add(
                                  "    Font: " + font);
                if (font != null) {
                    mouseInformation.add(
                     "    Font Metrics: " + 
                             acp.getFontMetrics(font));
                }
                mouseInformation.add(
                    "    Enabled: " + acp.isEnabled());
                mouseInformation.add(
                    "    Visible: " + acp.isVisible());
                mouseInformation.add(
                    "    Showing: " + acp.isShowing());
                if (acp.isShowing()) {
                    mouseInformation.add(
                    "    Location on Screen: " + 
                            acp.getLocationOnScreen());
                }
                mouseInformation.add(
                     "    Bounds: " + acp.getBounds());
                mouseInformation.add(
                     "    Size: " + acp.getSize());
                mouseInformation.add(
                     "    Focus Traversable: " + 
                             acp.isFocusTraversable());
                }

 

Suppose you run Ferret with the AccessibleSimpleButton program. Suppose too that you point your mouse at the Button in the Accessible SimpleButtonProgram GUI. Here's what Ferret displays:

Ferret

Notice the Settings menu. You can set it to:

Setting Displays accessible information about
Track Mouse The component at the current mouse position
Track Focus The component with current focus
Track Caret The text field at the current caret position

In addition to the GUIInitializedListener interface, the Accessibility Utilities package includes a TopLevelWindowListener interface that is used by EventQueueMonitor to determine if a top-level window is opened or closed.

The Accessibility Utilities package also includes various classes for registering listeners and tracking events on accessible objects. For example, the AccessibilityEventMonitor class implements a PropertyChange listener on all Accessible objects in the Java Virtual Machine1.

New Accessibility Features in J2SE v 1.3

J2SE version 1.3 adds a number of new Accessibility features. There are additions to the Java Accessibility API, and new support for Accessibility in AWT. There are also enhancements to the Java Accessibility Utilities. This means that more types of information can be made available to assistive technologies, and accessible information can be made available for more types of interface components.

Back to Top

Additions to the Java Accessibility API

The following interfaces and classes are new for J2SE v1.3:

  • AccessibleIcon. This interface has methods for setting and getting accessibility information about icons.
  • AccessibleRelation. This class describes the relationship between an accessible object and other objects.
  • AccessibleRelationSet. This class describes a set of relationships for a component.
  • AccessibleTable. This interface has methods for setting and retrieving accessibility information about a table.
  • AccessibleTableModelChange. This interface has methods to identify changes made to a table model.

AccessibleIcon

The AccessibleIcon interface extends accessibility to icons. In particular, it gives you a way to specify an accessible description for an icon. It also allows you to retrieve the description as well as information about the icon's height and width.

Here's an application that displays the button and icon (to run the application so that it displays the icon, you'll need to download the image. Right-click chicklet.gif and select Sava As.):

Simple Icon Button

And here's an application that displays the button and icon:

import java.awt.*;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.ImageIcon;

public class SimpleIconButton extends JPanel {
    
    public SimpleIconButton() {
        ImageIcon buttonIcon = new ImageIcon(
                                      "chicklet.gif");
        JButton iButton = new JButton(
                                "Button", buttonIcon);
        add(iButton);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("SimpleIconButton");
        frame.getContentPane().add(
          new SimpleIconButton(), BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}

Here's how to set and get the accessible information about the icon:
import javax.accessibility.*;
...

        AccessibleContext ac = 
                       iButton.getAccessibleContext();
        AccessibleIcon ai[] = 
                       ac.getAccessibleIcon();
        // Specify an accessible description 
        // for the icon
        ai[0].setAccessibleIconDescription(
                                  "A chicklet image");
        // Retrieve the accessible icon 
        // description
        ai[0].getAccessibleIconDescription();
        // Retrieve the accessible icon width
        ai[0].getAccessibleIconWidth();
        // retrieve the accessible icon 
        // height
        ai[0].getAccessibleIconHeight();        
 

A new method in getAcessibleContext, called getAccessibleIcon, returns an array of type AccessibleIcon. Each element of the array represents an accessible icon that is associated with the object of interest. In this case, the button has one accessible icon, the chicklet icon.

Although setAccessibleIconDescription is a method for specifying an accessible description for an icon, you can also provide an accessible description by specifying a description in the icon's constructor, for example:

   ImageIcon buttonIcon = new ImageIcon(
         "chicklet.gif", "A chicklet image");

AccessibleRelation and AccessibleRelationSet

AccessibleRelation and AccessibleRelationSet are classes that contain information about object relationships. AccessibleRelation contains information about a specific relationship between objects. AccessibleRelationSet contains information about a set of relationships pertinent to an object. Here's an example:

Suppose your have a column of buttons, headed by a label:

Access Simple Button Rel

Here's an application that displays the label and buttons, and specifies accessible relationships for these components.

import java.awt.*;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.BorderFactory;
import javax.accessibility.*;

public class AccessSimpleButtonRel extends JPanel {
 
    public Component componentBuilder() {
        // Create label
        JLabel myLabel = new JLabel(
                                "A column of buttons");
        
        // Create buttons
        JButton aButton = new JButton("Button A");
        aButton.getAccessibleContext().
                    setAccessibleName("Button A");
        
        JButton bButton = new JButton("Button B");
        bButton.getAccessibleContext().
                    setAccessibleName("Button B");
               
        JButton cButton = new JButton("Button C");
        cButton.getAccessibleContext().
                    setAccessibleName("Button C");
                
       // Set up relationships            
        AccessibleRelationSet labelRelationSet = 
                myLabel.getAccessibleContext().
                       getAccessibleRelationSet();
        labelRelationSet.add(
          new AccessibleRelation(
          AccessibleRelation.LABEL_FOR, aButton));
        labelRelationSet.add(
          new AccessibleRelation(
          AccessibleRelation.LABEL_FOR, bButton));   
        labelRelationSet.add(
          new AccessibleRelation(
          AccessibleRelation.LABEL_FOR, cButton));       
		
        AccessibleRelationSet abuttonRelationSet = 
                aButton.getAccessibleContext().
                       getAccessibleRelationSet();
                abuttonRelationSet.add(
                       new AccessibleRelation(
          AccessibleRelation.LABELED_BY, myLabel));
		
        AccessibleRelationSet bbuttonRelationSet = 
                bButton.getAccessibleContext().
                        getAccessibleRelationSet();
                abuttonRelationSet.add(
                       new AccessibleRelation(
          AccessibleRelation.LABELED_BY, myLabel));
		
         AccessibleRelationSet cbuttonRelationSet = 
               cButton.getAccessibleContext().
                        getAccessibleRelationSet();
               abuttonRelationSet.add(
                        new AccessibleRelation(
          AccessibleRelation.LABELED_BY, myLabel));  			

        JPanel myPane = new JPanel();
        myPane.setBorder(BorderFactory.
                createEmptyBorder(10, 20, 10, 20));
        myPane.setLayout(new GridLayout(0, 1));
        myPane.add(myLabel);
        myPane.add(aButton);
        myPane.add(bButton);
        myPane.add(cButton);
        return myPane;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame(
                           "Button Relationships");
        AccessSimpleButtonRel buttonrel = 
                       new AccessSimpleButtonRel();
        Component mycomponents = buttonrel.
                                componentBuilder();
        frame.getContentPane().add(
                mycomponents, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}

labelRelationshipSet is an AccessibleRelationshipSet for the label. It is created by the getAccessibleRelationSet method of the label's AccessibleContext:
   AccessibleRelationSet labelRelationSet = 
             myLabel.getAccessibleContext().
                    getAccessibleRelationSet();
 
An Add method is used to add AccessibleRelations to labelRelationSet. Each AccessibleRelation specifies a specific relationship between the label and another object. For example, the following statement creates an AccessibleRelation specifying that myLabel is a label for aButton, and adds it to labelRelationSet:
 labelRelationSet.add(new AccessibleRelation(
         AccessibleRelation.LABEL_FOR, aButton));
  
You can also use the JLabel.setLabelFor() method as a handy shortcut to set the LABEL_FOR relationship between a label and the object that it's labeling.

Notice that AccessibleRelations are also established to indicate that myLabel is also the label for buttons bButton and cButton. These AccessibleRelations are added to labelRelationSet. In other words, labelRelationSet specifies the relationship between the label and all three buttons.

Notice too that an AccessibleRelationSet and AccessibleRelation are also established for each button, indicating that the button is labeled by myLabel. For example, these statements create an AccessibleRelationSet and AccessibleRelation for aButton:

 AccessibleRelationSet abuttonRelationSet = 
   aButton.getAccessibleContext().
                     getAccessibleRelationSet();
   abuttonRelationSet.add(new AccessibleRelation(
 AccessibleRelation.LABELED_BY, myLabel));

Other types of object-to-object relationships can be specified. In particular, an AccessibleRelation can specify that an object controls another object or is controlled by another object. Or it can specify that an object is a member of a group of objects.

Back to Top

AccessibleTable

The AccessibleTable interface extends accessibility information to tables. For example, it provides methods for setting and retrieving an accessible caption for a table, and for getting the number of rows and columns in a table. The Swing class JTable.AccessibleJTable implements the AccessibleTable interface.

Here's an example. Suppose you have a table like this:

Simple Table

Here's an application that displays the table:

import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.*;

public class SimpleTable extends JFrame {
    
  public SimpleTable() {
      super("Personnel");

      Object[][] data = {
          {"Thomas", "Albanese", "Engineer", 
                 "Development", new Integer(10)},
          {"Laura", "Bates", "Administrator", 
                     "Benefits", new Integer(4)},
          {"Susan", "Carson", "Director", 
                   "Marketing", new Integer(12)},
          {"William", "Delancy", "Instructor", 
                     "Support", new Integer (6)}
      };

      String[] columnNames = {"First Name", 
                              "Last Name",
                              "Job Title",
                              "Department",
                              "Service (yrs)"};
                                
      JTable perstab = new JTable(data, columnNames);
      perstab.setPreferredScrollableViewportSize(
                             new Dimension(500, 65));
      JScrollPane scrollPane = new JScrollPane(
                                            perstab);
      getContentPane().add(scrollPane, 
                                BorderLayout.CENTER);
        
  }

  public static void main(String[] args) {
      SimpleTable frame = new SimpleTable();
      frame.pack();
      frame.setVisible(true);
  }
}

Here's how to retrieve accessible information about the number of columns and rows in the table:
  AccessibleContext ac = perstab.
                          getAccessibleContext();
  AccessibleTable atab = ac.getAccessibleTable();
  atab.getAccessibleColumnCount();
  atab.getAccessibleRowCount();

The getAccessibleTable method in the AccessibleContext returns an object of type AccessibleTable. This object contains a variety of methods for setting and retrieving accessible information about the table. This includes the getAccessibleColumnCount and getAccessibleRowCount methods illustrated above. Some other methods include (there are others):
Method Usage
getAccessibleCaption Get the accessible table caption
getAccessibleColumnDescriptionGet the accessible table column description
getAcessibleColumnHeader Get the accessible column header
getAcessibleRowDescriptionGet the accessible table row description
getAccessibleSummary Get the accessible table summary description
isAccessibleColumnSelectDetermine if a specified column is selected
isAcessibleRowSelected Determine if a specified row is selected
setAccessibleCaption Set the accessible table caption
setAccessibleColumnDescriptionSet the accessible table column description
setAcessibleColumnHeader Set the accessible column header
setAcessibleRowDescriptionSet the accessible table row description
setAccessibleSummary Set the accessible table summary description

AccessibleTableModelChange

This interface has methods to identify changes made to a table model. It includes methods that you can use to determine what type of change was made (insert, update, or delete). Methods are also available to get the first column or row, and last column or row that was changed. The interface is implemented by the Swing class JTable.AccessibleJTable.AccessibleJTableModelChange. For example, here's how to determine the type of change made to the table model for the table in the SimpleTable program:

import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent;
...
 
public class SimpleTable extends JFrame {
    
  public SimpleTable() {
  ...
     
   AccessibleContext ac = perstab.
                   getAccessibleContext();
    ...                                
      
  // Define PropertyChangeListener

   PropertyChangeListener propertyChangeListener = 
       new PropertyChangeListener() {
        public void propertyChange(
                  PropertyChangeEvent e) {
        System.err.println(
        "property changed: "+e.propertyName+
        	"; old value="+e.oldValue+";
	 		     new value="+ newValue);
		}
      };
                
         // Attach Listeners

         ac.addPropertyChangeListener(
         propertyChangeListener);
                    
    }
    ...

Support for Accessibility in AWT

Accessibility has been extended to AWT in a number of ways.

  • Applets can now be made accessible.
  • Accessibility support is now part of AWT Component and AWT Container.
  • A new Robot class has been added to AWT. This class can be used by assistive technologies to track mouse movements.

Applets can now be made accessible: Accessibility support has been extended to applets.

In particular, the class java.applet.Applet now implements the Accessible interface. Let's look at an an example. Here's a program that starts an accessible applet:

Access Applet


import java.awt.Frame;
import java.applet.Applet;
import java.awt.Button;
import javax.accessibility.*;

public class AccessApplet extends Applet {
   public static void main (String args[]) {
      Framer f = new Framer("Accessible Applet");
      f.setSize(300, 100);
      f.show ();
  }
}    

class Framer extends Frame {
    public Framer(String title) {
        super(title);
        AccessApplet applet = new AccessApplet();
        applet.start();
        add (applet, "Center");
         String descapplet = 
                      "This is a simple applet";    
        applet.getAccessibleContext().                    
          setAccessibleDescription(descapplet);   
        applet.add(aButton);
    }
    
}


Accessibility support is now part of AWT Component and AWT Container: This means that accessibility is not only built into Swing components, but into any AWT component that extends java.awt.Component and java.awt.Container. This includes AWT components such as Button and Canvas, and lightweight AWT components. For example, you can add an accessible name and description to the AWT button component in the previous AccessApplet program as follows:

import java.awt.Frame;
import java.applet.Applet;
import java.awt.Button;
import javax.accessibility.*;

public class AccessApplet extends Applet {
    ...

class Framer extends Frame {
    public Framer(String title) {
        ...
       
        Button aButton = new Button("Button"); 
        aButton.getAccessibleContext().
                  setAccessibleName("Button");
        String desca = 
                    "This is a simple button";
        aButton.getAccessibleContext().
              setAccessibleDescription(desca);
        applet.add(aButton);
    }
    
}


A new Robot class has been added to AWT: The Robot class, java.awt.Robot, is used for automating GUI actions such as entering keystrokes or moving the mouse. This is a handy feature for automating things like GUI test programs or demonstrations. However it's also an accessibility enhancement because assistive technologies can use the Robot class to manage and track keystrokes and mouse movements. A good example of an application that uses java.awt.Robot is presented in the Tech Tip Automating GUI Programs with java.awt.Robot.

Enhancements to the Java Accessibility Utilities

The Java Accessibility Utilities have been updated to support the following new Accessibility interfaces and classes:

  • AccessibleIcon
  • AccessibleRelation
  • AccessibleRelationSet
  • AccessibleTable

This means that an Accessibility Utility such as Ferret can now display accessible information as supported by these classes and interfaces. For example, through the AccessibleIcon interface, Ferret can display accessible information about an icon, such as its description, width, and height.

New Accessibility Tools

There are two new accessibility-related tools: the Java Access Bridge for the Microsoft Windows Operating System, and the Java Accessibility Helper.

Java Access Bridge

The Java Access Bridge makes it possible for a Windows-based assistive technology to access information provided by a Java application through the Accessibility API. This allows software such as screen readers running in a Windows environment to get at accessible information for a GUI component such as a Swing button.

The Access Bridge spans both the Windows and Java environments. Part of it is a Java class. The other part is a set of Windows Dynamic Link Libraries (DLLs). When a Windows-based assistive technology runs, it interacts with the DLL portion of the Access Bridge. The Bridge's class then communicates with the Accessibility API and Java Accessibility Utilities through the Java Virtual Machine. (In order to use the Java Access Bridge, you need to have the Java Accessibility Utilities installed.)

Java Accessibility Helper

The Java Accessibility Helper is a tool that examines an AWT or Swing-based application for accessibility, and reports any problems it finds. Let's run Accessibility Helper against the SimpleButton application. Recall that this is a simple application that displays a Swing button.

Accessibility Helper is capable of running various tests against an application. In its Test Set Option panel, you specify the type of test you want to run:

Access Helper

Selecting the API Tests option tells Accessibility Helper to test the application's GUI components for accessibility support. Here's the in-progress display of an API Tests run against the SimpleButton application:

Access Helper

Notice how Accessible Helper detected that the JButton component has an accessible name (because a name was specified when the JButton was instantiated). But the JButton component has an accessible description that is null (because no description was specified). The report produced by this run will highlight as a potential problem the fact that the accessible description is null.

Selecting Automatic UI Manipulation interacts with the GUI components. It automatically traverses the components in the GUI, for example, by moving the mouse pointer. In doing this, Accessibility Helper checks that the GUI is designed for accessibility. For example, it verifies that buttons in an application can be accessed from the keyboard.

Additional Reading

Sun Microsystems' Accessibility Program

Accessibility Enhancements in Java 2 SDK, Standard Edition, version 1.3

Java 2 Platform SE v1.3 Package javax.accessibility

Java 2 Platform SE v1.3 Package com.sun.java.accessibility.util

Automating GUI Programs with java.awt.Robot

The JFC Swing Tutorial: How to Support Assistive Technologies

Project Swing (Java Foundation Classes) Software

U.S. Department of Justice Americans with Disabilities Act Home Page

Back to Top

Coffecup Logo

About the Author

Ed Ort is a staff member of the Java Developer Connection. He has written extensively about relational database technology and programming languages.

Have a question about programming? Use Java Online Support.

_______
1 As used in this document, the terms "Java virtual machine" or "JVM" mean a virtual machine for the Java platform.