GUI 中组件组之间的关系通常很杂乱。让 AT 阅读器明了这些关系,可以使它增强组件组的表示,从而将比较复杂的信息传递给用户。在 Swing 中,我们使用 AccessibleContext() 方法的 AccessibleRelationSet getAccessibleRelationSet() 方法来定义关系。
AccessibleRelationSet 包含一组 AccessibleRelation 。每个 AccessibleRelation 描述两个 Accessible 对象(源和目标)之间的关系。目前,这些关系是如下所示定义的:
CONTROLLED_BY 将给定目标标识为给定组件的控制器。
CONTROLLER_FOR 表明给定组件控制给定目标。
LABELLED_BY 表明给定组件是由给定目标标记的。
LABEL_FOR 表明给定组件是给定目标的标签。
MEMBER_OF 表明给定组件是给定目标组的成员。
AccessibilityDemo1 中的可访问性工具箱提供了几种实用程序方法,它们可以帮助您定义可访问关系。单选按钮之间的“只有一个被选中”关系是一种很常见的关系。在 Swing 中,我们使用 javax.swing.ButtonGroup 来实现这种关系。清单 9 显示了可访问性工具箱用于在按钮组中定义单选按钮的实用程序方法。您会注意到,既有定义单个单选按钮的方法,也有定义单选按钮集(或组)的方法。
清单 9. 定义组中按钮的方法
2 String name, String action, int vKey, boolean selected) {
3 JRadioButton b = new JRadioButton();
4 b.setSelected(selected);
5 return (JRadioButton)AccessibleUtils.setAccessibleValues(
6 resourceBundle, (Accessible)b,
7 new AccessibleUtils.AccessibleValues(
8 idGen.nextId("radioButton"),
9 name,
10 AccessibleUtils.formatText(resourceBundle, "{0} Button", name),
11 "=tt",
12 AccessibleUtils.formatText(resourceBundle,
13 "Press to {0}", action), vKey));
14 }
15 JPanel setupRadioButtonSet(String title, JRadioButton[] bs) {
16 return setupRadioButtonSet(title, Arrays.asList(bs));
17 }
18 JPanel setupRadioButtonSet(String title, Collection bs) {
19 JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10));
20 AccessibleUtils.setAccessibleValues(resourceBundle, (Accessible)p,
21 new AccessibleUtils.AccessibleValues(
22 idGen.nextId("panel"),
23 null,
24 "languages",
25 "=tt",
26 "Select the desired language"));
27 AccessibleUtils.setMemberRelationship(p, bs);
28 p.setBorder(new TitledBorder(title));
29 addAll(p, bs);
30 ButtonGroup bg = new ButtonGroup();
31 addAll(bg, bs);
32 return p;
33 }
34 void addAll(ButtonGroup g, Collection l) {
35 for ( Iterator i = l.iterator(); i.hasNext(); ) {
36 g.add((AbstractButton)i.next());
37 }
38 }
39
您可以使用上述助手方法定义如 图 1所示的语言选择单选按钮集,如清单 10 所示:
清单 10. 定义语言选择单选按钮(来自图 1)
2 :
3 ArrayList buttons = new ArrayList();
4 StringTokenizer st2 = new StringTokenizer(
5 "English!French!Spanish!German!Italian!Japanese!Chinese!" +
6 "Korean!Arabic!Hebrew!Russian", "!");
7 for ( int i = 0; st2.hasMoreTokens(); i++ ) {
8 String name = nextToken(st2);
9 buttons.add(name, setupRadioButton(name,
10 AccessibleUtils.formatText(rb, "select {0}", name),
11 (int)name.charAt(0), i == 0));
12 }
13 JPanel formBox2 = setupRadioButtonSet("Languages", buttons);
14 :
15 }
16
使用与设置按钮相同的方法将单选按钮设置成可访问的。但是,与按钮不同的是,经常将单选按钮添加到 ButtonGroup 和 AccessibleRelationSet 中。清单 11 中详细说明了用来辅助完成这项任务的 AccessibileUtils() 方法:
清单 11. AccessibileUtils 方法
2 return setMemberRelationship(group, new Accessible[] {member});
3 }
4 Accessible setMemberRelationship(Accessible group, Accessible[] members) {
5 return setMemberRelationship(group, Arrays.asList(members));
6 }
7 Accessible setMemberRelationship(Accessible group, Collection members) {
8 for ( Iterator i = members.iterator(); i.hasNext(); ) {
9 Accessible a = (Accessible)i.next();
10 AccessibleContext ac = a.getAccessibleContext();
11 if ( ac == null ) {
12 throw new NullPointerException(
13 "AccessibleContext cannot be null on an Accessible object"
14 + formatClassToken(a));
15 }
16 AccessibleRelationSet ars = ac.getAccessibleRelationSet();
17 AccessibleRelation ar =
18 new AccessibleRelation(AccessibleRelation.MEMBER_OF, group);
19 ars.add(ar);
20 }
21 return group;
22 }
23