Initially created by: Jan Benway October 12, 2001
Last modified by: Jan Benway October 15, 2001
Dealing with Unfocusable Components - by Design
This document describes how to make "standalone text" accessible to
screenreaders and usable by all other users.
The Problem
The problem is that in many dialog boxes, important text is stored in JLabel components
or disabled JTextAreas. Screen readers cannot read text that is not in focusable
components.
JLabels are not focusable unless they are connected (using labelFor) with another
component (such as a JComboBox).
Disabled JTextAreas are not focusable. The developer can make a JTextArea focusable by
making it non-editable but enabled. This is problematic, though, because sighted users can
accidentally put the keyboard focus on these areas. This causes a usability problem. There
is seldom any reason for sighted users to put the focus there. Also, the JDK doesn't
provide any visual feedback when the focus is there. Making the problem worse, users
cannot use Tab to move the focus away from the component. Control-Tab is needed.
The Solution
There are two solutions to this problem. Which solution should be used in which dialog
box depends on how the components are being used.
Uneditable text tends to fall into two categories: Text that is displaying uneditable
parameters or status, and text that gives instructions. Which solution you use depends on
which type of text you have.
Uneditable Parameters and Status
Dialog boxes often display dynamic information as background information or status for
the user. If this information is displayed in JLabel components or other unfocusable
components, screenreaders will not have access to it.
Here is an example:

In the dialog box above, most of the information is read-only, but the read-only
information is labeled. So, the read-only information should be put into uneditable
JTextFields. The labels for these JTextFields should be set with labelFor and mnemonics
should be assigned.
This has been done in the Class wizard:

Here, the screenreader users (or any user) can focus the value for "Name" by
using the N mnemonic, or by tabbing to the component. The same things for the value for
"Package" and for "Class Declaration".
If there is no JLabel labeling the unfocusable information
In some cases, dynamic information is contained in a JLabel that has no static label.
For example, see this dialog box:

In this case, the text "You are already logged in" has no static label.
Consider whether a logical label could be added so that a mnemonic could be assigned. In
this case, perhaps a label with the text "Login Status:" would be appropriate.
In some cases, such information could be treated the same way as instructional text and
be added to the accessible description of the dialog box. Consider what makes sense in
your case.
Guidelines:
1. Put dynamic read-only information into uneditable JTextFields.
2. Use the default appearance of these JTextFields (gray background, visible border)
3. Assign the labelFor and mnemonic appropriately for the static JLabel
associated with the JTextField.
4. Automatically select the text in the JTextField when that component gains focus.
This is not the default behavior -- the developer must explicitly implement it. This is
required by the Java Look and Feel Design Guidelines.
5. Do not make the JTextField disabled, only uneditable. Making the component disabled
makes it unfocusable, and also difficult to read. Making the component uneditable keeps it
focusable and it has the added benefit of allowing users to copy the text out of these
components, which can be useful in some cases (for instance, it is useful if a long path
name is displayed).
6. Assign the initial focus to some editable component, if there is one. If the first
component in a dialog box is a non-editable textfield (as in both examples shown above),
set the initial focus elsewhere -- on the first component a user is like to use. Leave the
non-editable text fields in the tab order.
7. Whenever the value of a parameter changes, a VISIBLE_PROPERTY_CHANGE event should be
generated to cue the assistive technology to read it again.
How to Implement These Guidelines
initComponents();
jLabel1.setDisplayedMnemonic('L');
jTextField1.selectAll(); //use this but next part with Listener is
recomended
jTextField1.addFocusListener(new java.awt.event.FocusListener() {
public void focusGained(java.awt.event.FocusEvent e) {
jTextField1.selectAll();
}
public void focusLost(java.awt.event.FocusEvent e) {
}
});
If you have many JTextField in dialog, you could use this syntax:
initComponents();
jTextField1.selectAll();
jTextField2.selectAll();
jTextField1.selectAll();
jTextField1.addFocusListener(new CheckSelectAll());
jTextField2.addFocusListener(new CheckSelectAll());
jTextField3.addFocusListener(new CheckSelectAll());
.
.
.
class CheckSelectAll implements java.awt.event.FocusListener { // Inner
class
public void focusGained(java.awt.event.FocusEvent e) {
((javax.swing.JTextField)e.getComponent()).selectAll();
}
public void focusLost(java.awt.event.FocusEvent
e) {
}
}
Open Issue
There is no visible feedback when a uneditable textfield has focus and is why we are
selecting the entire text (JTextField.selectAll();)of an uneditable area..
This is a JDK problem: 4512626
Instructional Information
Many dialog boxes, and especially wizard pages have information that describes the
dialog box as a whole.
For example, the New Class Wizard contains this page:

This page has two JLabels that are not focusable: The page title and the instruction
text. The text of both of these should be added to the AccessibleDescription
of the page. This way, the user with a screenreader can issue an instruction
to hear a description of the dialog box. The steps text is added to the accessible
description automatically by the WizardDescriptor, so each developer needn't
handle this. The instruction text does need to be handled by the wizard developer.
This accessibleContext should be set for the JPanel. It is forwarded to the
WizardDescriptor in openide.
If the information applies to only part of the dialog box
In some cases, instructional text doesn't describe the dialog box as a whole, but only
on component or set of components.
For example, in this dialog box, there is a label that describes the "Add
recursively" checkbox:

In this case, the instructional text should be added as the labelFor for
the checkbox. If this instructional text is a JLabel then use setLabelFor to
link the text to the component it is describing; AccessibleDescription will
be set by default. If the instructional text is a JTextArea then set the AccessibleDescription.
In some cases, instructional text describes a group of components. For example:

In this case, place the group of components on their own JPanel. Then, assign the
instruction text as the labelFor for the JPanel.
Guidelines
1. Assign text that describes the whole dialog box as the accessible description of
that dialog box. DialogDescriptor, NotifyDescriptor and WizardDescriptor will use
AccessibleContext (Name,Description) assigned to obtained JPanel.
2. Assign text that describes smaller sections of the dialog box as labelFor
(which will set the AccessibleDscription) the component it describes. If it
describes a group of components, place those components on a sub-panel and assign the text
to that sub-panel.
3. The text of the AccessibleDescription should be placed in the
I18N bundle file. If text is written especially for accessible names and descriptions,
use the NetBeans naming convention to prefix the bundle: Use the prefix ACS_.
If it is necessary to make a distinction between accessibleName and accessibleDescription
use ACSN_ and ACSD_.
4. If the instruction text is in a JTextArea, make the JTextArea disabled and
non-editable. Make sure to set the appropriate properties of the JTextArea. Then, add the
text to the AccessibleDescription as with the JLabel example.
jTextArea.setWrapStyleWord (true);
jTextArea.setLineWrap (true);
jTextArea.setEnabled (false);
jTextArea.setEditable (false);
jTextArea.setOpaque (false);
jTextArea.setFont (javax.swing.UIManager.getFont ("Label.font"));
jTextArea.setDisabledTextColor (javax.swing.UIManager.getColor
("Label.foreground"));
5. The steps pane on wizards can be left unfocusable by developers implementing
wizards. All text available there will also be available as the page title for
each page. OpenIDE assigns the text in the following and preceding steps as
the AccessibleDescription for the Next and Back buttons, respectively.
Developers implementing individual wizards do not need to worry about it.
How to Implement These Guidelines
<code here>
<Need concrete example of how to assign this in NetBeans. Need example for: Regular
dialog, property editor, and wizard page>
Open Issue
The NetBeans team has not been able to get JAWS to read these accessible descriptions
on entire dialog boxes (only individual components). Further testing is needed.