Sunday, October 18, 2009

25.7 Interfacing with Accessibility




I l@ve RuBoard










25.7 Interfacing with Accessibility



The following code shows how to create a
simple assistive technology that can monitor events on the system
event queue and interface with accessible components. The example
consists of one class, AssistiveExample. This
class creates a small window containing two labels and five
checkboxes, which are repeatedly updated when the mouse comes to rest
over an accessible component for longer than half a second.



Note that while using 1.2 or higher accessibility, we have to check
to see if the GUI is ready for us to start firing
accessibility-related commands. We do this by checking the
EventQueueMonitor.isGUIInitialized( ) method. This
method returns a boolean indicating whether the
GUI will accept accessibility commands. If it does, then
we're fine. If it doesn't, then we
must register ourselves to be notified when the GUI becomes
available. This uses the GUIInitializedListener
interface, which we explained earlier.



To use the AssistiveExample class, simply create a
new AssistiveExample object from an existing
application. The constructor creates a frame and makes it visible.
For an example, check the source of the BigExample
class in the online code files for this chapter.



Finally, note that we have a single button in our assistive example
that performs the first action reported by the accessible context.
You can use the Tab key to bring this button into focus while
pointing with the mouse, then press the space bar to fire the action.



// AssistiveExample.java
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.accessibility.*;
import com.sun.java.accessibility.util.*;

public class AssistiveExample extends JPanel
implements MouseMotionListener, ActionListener, GUIInitializedListener {

Timer timer;
static JFrame frame;

JLabel nameLabel = new JLabel( );
JLabel descriptionLabel = new JLabel( );
JLabel tableLabel = new JLabel( );

JCheckBox selectionCheckBox = new JCheckBox("Selection", false);
JCheckBox textCheckBox = new JCheckBox("Text", false);
JCheckBox valueCheckBox = new JCheckBox("Value", false);
JCheckBox componentCheckBox = new JCheckBox("Component", false);
JCheckBox actionCheckBox = new JCheckBox("Action", false);
JCheckBox hypertextCheckBox = new JCheckBox("Hypertext", false);
JCheckBox iconCheckBox = new JCheckBox("Icon", false);
JCheckBox tableCheckBox = new JCheckBox("Table", false);
JCheckBox editableTextCheckBox = new JCheckBox("EditableText", false);
JLabel classLabel = new JLabel( );
JLabel parentLabel = new JLabel( );
JLabel relationLabel = new JLabel( );
JButton performAction = new JButton("Perform Action");

public AssistiveExample( ) {
frame = new JFrame("Assistive Example");
// Insert the appropriate labels and checkboxes.
setLayout(new GridLayout(0,1)); // Just make as many rows as we need.

add(nameLabel);
add(descriptionLabel);
add(tableLabel);
add(new JSeparator( ));
add(actionCheckBox);
add(componentCheckBox);
add(editableTextCheckBox);
add(hypertextCheckBox);
add(iconCheckBox);
add(selectionCheckBox);
add(tableCheckBox);
add(textCheckBox);
add(valueCheckBox);
add(classLabel);
add(parentLabel);
add(relationLabel);
add(performAction);

setBorder(new TitledBorder("Accessible Component"));

performAction.addActionListener(this);

frame.getContentPane( ).add(this, BorderLayout.CENTER);
frame.setBounds(100,100,500,600);
frame.setVisible(true);

// Check to see if the GUI subsystem is initialized correctly. (This is needed in
// JDK 1.2 and higher.) If it isn't ready, then we have to wait.
if (EventQueueMonitor.isGUIInitialized( )) {
createGUI( );
} else {
EventQueueMonitor.addGUIInitializedListener(this);
}

performAction.grabFocus( );
}

public void guiInitialized( ) {
createGUI( );
}

public void createGUI( ) {
// We want to track the mouse motions, so notify the Swing event monitor of this.
SwingEventMonitor.addMouseMotionListener(this);

// Start a Timer object to measure how long the mouse stays over a particular
// area.
timer = new Timer(500, this);
}

public void mouseMoved(MouseEvent e) {
// If the mouse moves, restart the timer.
timer.restart( );
}
public void mouseDragged(MouseEvent e) {
// If the mouse is dragged, restart the timer.
timer.restart( );
}

public void actionPerformed(ActionEvent e) {
// Find the component currently under the mouse.
Point currentPosition = EventQueueMonitor.getCurrentMousePosition( );
Accessible comp = EventQueueMonitor.getAccessibleAt(currentPosition);

// If the user pressed the button, and the component has an accessible action,
// then execute it.
if (e.getActionCommand( ) == "Perform Action") {
AccessibleContext context = comp.getAccessibleContext( );
AccessibleAction action = context.getAccessibleAction( );

if (action != null)
action.doAccessibleAction(0);
else
System.out.println("No accessible action present!");
return;
}

// Otherwise, the timer has fired. Stop it and update the window.
timer.stop( );
updateWindow(comp);
}

private void updateWindow(Accessible component) {
if (component == null) { return; }

// Reset the checkboxes.
actionCheckBox.setSelected(false);
selectionCheckBox.setSelected(false);
textCheckBox.setSelected(false);
componentCheckBox.setSelected(false);
valueCheckBox.setSelected(false);
hypertextCheckBox.setSelected(false);
iconCheckBox.setSelected(false);
tableCheckBox.setSelected(false);
editableTextCheckBox.setSelected(false);

// Get the accessibile context of the component in question.
AccessibleContext context = component.getAccessibleContext( );
AccessibleRelationSet ars = context.getAccessibleRelationSet( );

nameLabel.setText("Name: " + context.getAccessibleName( ));
descriptionLabel.setText("Desc: " + context.getAccessibleDescription( ));
relationLabel.setText("Relation: " + ars);

// Check the context for each of the accessibility types.
if (context.getAccessibleAction( ) != null)
actionCheckBox.setSelected(true);
if (context.getAccessibleSelection( ) != null)
selectionCheckBox.setSelected(true);
if (context.getAccessibleText( ) != null) {
textCheckBox.setSelected(true);
if (context.getAccessibleText( ) instanceof AccessibleHypertext)
hypertextCheckBox.setSelected(true);
}
if (context.getAccessibleComponent( ) != null) {
componentCheckBox.setSelected(true);
classLabel.setText("Class: " + context.getAccessibleComponent( ));
parentLabel.setText("Parent: " + context.getAccessibleParent( ));
}
if (context.getAccessibleValue( ) != null)
valueCheckBox.setSelected(true);
if (context.getAccessibleIcon( ) != null)
iconCheckBox.setSelected(true);
if ((context.getAccessibleTable( ) != null) ||
(context.getAccessibleParent( ) instanceof JTable)) {
tableCheckBox.setSelected(true);
tableLabel.setText("Table Desc: " +
context.getAccessibleParent( ).getAccessibleContext( )
.getAccessibleDescription( ));
}
else {
tableLabel.setText("");
}
if (context.getAccessibleEditableText( ) != null)
editableTextCheckBox.setSelected(true);
repaint( );
}
}


Figure 25-2 shows the result. We've
connected our assistive technology to a demo application called
BigExample. (The only functioning component is the
Exit menu item.) Because Swing components support accessibility, we
didn't need to do much work beyond creating and
adding the components to the application. Figure 25-3 shows our assistive technology attached to the
accessible AWT button we developed earlier, proving that we can
communicate with it.




Figure 25-2. The assistive example in Mac OS X with a table




Figure 25-3. The assistive example on a Windows system with our customized AWT button





25.7.1 The Java Accessibility Helper



Developers serious about adding accessible support to their
applications should consider taking advantage of the

Java Accessibility
Helper from Sun. This GUI tool allows developers to test applications
from the assistive technology point of view. A test suite can be
developed for an application through an easy-to-use interface. This
free tool is currently available in its 0.6 release as part of the
Java Developer
Connection's Early Access program.
You'll need to be a member to download the helper
(which comes with some great step-by-step documentation), but you
really should be a member of the JDC if you aren't
already! (For details, check out
http://developer.java.sun.com/developer/.)












    I l@ve RuBoard



    No comments:

    Post a Comment