一些 Swing 组件不直接支持助记符。正如我先前讨论的,这些 Swing 通过允许 JLabel 来标记组件以弥补这一不足。可访问性工具箱提供了助手方法来辅助对组件作标记。清单 12 展示了作用于 JTextField 组件的助手方法:
清单 12. 对组件作标记的助手方法
1 JTextField setupLabelledField(
2 JPanel lp, JPanel fp, String name, int vKey) {
3 JLabel l = new JLabel("", JLabel.RIGHT);
4 AccessibleUtils.setAccessibleValues(resourceBundle, (Accessible)l,
5 new AccessibleUtils.AccessibleValues(
6 idGen.nextId("label"),
7 name,
8 name + " label",
9 "=tt",
10 AccessibleUtils.formatText(resourceBundle,
11 "Identifies the {0} field", name),
12 vKey));
13 lp.add(l);
14 JTextField tf = new JTextField("", 40);
15 AccessibleUtils.setAccessibleValues(resourceBundle, (Accessible)tf,
16 new AccessibleUtils.AccessibleValues(
17 idGen.nextId("textField"),
18 null,
19 name + " entry field",
20 "=tt",
21 AccessibleUtils.formatText(resourceBundle,
22 "Enter the value for {0}", name)));
23 fp.add(tf);
24 AccessibleUtils.setLabelRelationship(l, tf);
25 return tf;
26 }
27
2 JPanel lp, JPanel fp, String name, int vKey) {
3 JLabel l = new JLabel("", JLabel.RIGHT);
4 AccessibleUtils.setAccessibleValues(resourceBundle, (Accessible)l,
5 new AccessibleUtils.AccessibleValues(
6 idGen.nextId("label"),
7 name,
8 name + " label",
9 "=tt",
10 AccessibleUtils.formatText(resourceBundle,
11 "Identifies the {0} field", name),
12 vKey));
13 lp.add(l);
14 JTextField tf = new JTextField("", 40);
15 AccessibleUtils.setAccessibleValues(resourceBundle, (Accessible)tf,
16 new AccessibleUtils.AccessibleValues(
17 idGen.nextId("textField"),
18 null,
19 name + " entry field",
20 "=tt",
21 AccessibleUtils.formatText(resourceBundle,
22 "Enter the value for {0}", name)));
23 fp.add(tf);
24 AccessibleUtils.setLabelRelationship(l, tf);
25 return tf;
26 }
27
尽管并未显示,但是请注意也应该用 AccessibleUtils.formatText 处理 name + "label" 和 name + "entry field" 子句,以充分地支持国际化转换。
现在就在清单 13 中查阅方法的细节:
清单 13. setLabelRelationship 助手方法的细节
1 Accessible setLabelRelationship(Accessible label, Accessible target) {
2 if ( label instanceof JLabel ) {
3 ((JLabel)label).setLabelFor((Component)target);
4 /* *** done by setLabelFor ***
5 AccessibleContext ac1 = label.getAccessibleContext();
6 if ( ac1 == null ) {
7 throw new NullPointerException(
8 "AccessibleContext cannot be null on an Accessible object"
9 + formatClassToken(label));
10 }
11 AccessibleRelationSet ars1 = ac1.getAccessibleRelationSet();
12 AccessibleRelation ar1 = new AccessibleRelation(
13 AccessibleRelation.LABEL_FOR, target);
14 ars1.add(ar1);
15 */
16 AccessibleContext ac2 = target.getAccessibleContext();
17 if ( ac2 == null ) {
18 throw new NullPointerException(
19 "AccessibleContext cannot be null on an Accessible object"
20 + formatClassToken(target));
21 }
22 AccessibleRelationSet ars2 = ac2.getAccessibleRelationSet();
23 AccessibleRelation ar2 = new AccessibleRelation(
24 AccessibleRelation.LABELLED_BY, label);
25 ars2.add(ar2);
26 }
27 return label;
28 }
29
2 if ( label instanceof JLabel ) {
3 ((JLabel)label).setLabelFor((Component)target);
4 /* *** done by setLabelFor ***
5 AccessibleContext ac1 = label.getAccessibleContext();
6 if ( ac1 == null ) {
7 throw new NullPointerException(
8 "AccessibleContext cannot be null on an Accessible object"
9 + formatClassToken(label));
10 }
11 AccessibleRelationSet ars1 = ac1.getAccessibleRelationSet();
12 AccessibleRelation ar1 = new AccessibleRelation(
13 AccessibleRelation.LABEL_FOR, target);
14 ars1.add(ar1);
15 */
16 AccessibleContext ac2 = target.getAccessibleContext();
17 if ( ac2 == null ) {
18 throw new NullPointerException(
19 "AccessibleContext cannot be null on an Accessible object"
20 + formatClassToken(target));
21 }
22 AccessibleRelationSet ars2 = ac2.getAccessibleRelationSet();
23 AccessibleRelation ar2 = new AccessibleRelation(
24 AccessibleRelation.LABELLED_BY, label);
25 ars2.add(ar2);
26 }
27 return label;
28 }
29