-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
P4
-
Affects Version/s: 21, 25, 27
-
Component/s: client-libs
-
os_x
On Mac if you have a JComponent that presents itself using AccessibleRole.HYPERLINK: VoiceOver identifies that component as a "text element".
Here is a sample program:
```
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class VoiceOverHyperlinkRole {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame();
f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS));
f.getContentPane().add(createText(
"INSTRUCTIONS (Mac-only):\n" +
"1. Open VoiceOver\n" +
"2. Move the VoiceOver cursor over the link.\n" +
"3. Observe how VoiceOver identifies the link.\n\n" +
"Expected behavior: VoiceOver should identify it as a \"link\". " +
"It should not say \"text element\", \"text\" or \"hyperlink\".\n\n" +
"If you select the link using \"Accessibility Inspector\": it " +
"should identify its role as AXLink."
));
f.getContentPane().add(new JSeparator());
f.getContentPane().add(createText("This button uses `AccessibleRole.HYPERLINK:`"));
f.getContentPane().add(createLink(AccessibleRole.HYPERLINK));
// for debugging / experimentation:
boolean tryOtherRoles = false;
if (tryOtherRoles) {
f.getContentPane().add(createText("This button uses `new AccessibleRole(\"Link\") {}`:"));
f.getContentPane().add(createLink(new AccessibleRole("Link") {
}));
f.getContentPane().add(createText("This button uses `new AccessibleRole(\"link\") {}`:"));
f.getContentPane().add(createLink(new AccessibleRole("link") {
}));
f.getContentPane().add(createText("This button uses `new AccessibleRole(\"AXLink\") {}`:"));
f.getContentPane().add(createLink(new AccessibleRole("AXLink") {
}));
}
f.pack();
f.setVisible(true);
}
});
}
private static JTextArea createText(String text) {
JTextArea textArea = new JTextArea(text);
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setBorder(new EmptyBorder(20, 10, 3, 10));
return textArea;
}
private static JButton createLink(AccessibleRole role) {
String text = "<html><u>https://bugs.openjdk.org/</u></html>";
JButton button = new JButton(text) {
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJButton() {
@Override
public AccessibleRole getAccessibleRole() {
return role;
}
};
}
return accessibleContext;
}
};
button.setContentAreaFilled(false);
button.setBorderPainted(false);
return button;
}
}
```
Here is a sample program:
```
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class VoiceOverHyperlinkRole {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame();
f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS));
f.getContentPane().add(createText(
"INSTRUCTIONS (Mac-only):\n" +
"1. Open VoiceOver\n" +
"2. Move the VoiceOver cursor over the link.\n" +
"3. Observe how VoiceOver identifies the link.\n\n" +
"Expected behavior: VoiceOver should identify it as a \"link\". " +
"It should not say \"text element\", \"text\" or \"hyperlink\".\n\n" +
"If you select the link using \"Accessibility Inspector\": it " +
"should identify its role as AXLink."
));
f.getContentPane().add(new JSeparator());
f.getContentPane().add(createText("This button uses `AccessibleRole.HYPERLINK:`"));
f.getContentPane().add(createLink(AccessibleRole.HYPERLINK));
// for debugging / experimentation:
boolean tryOtherRoles = false;
if (tryOtherRoles) {
f.getContentPane().add(createText("This button uses `new AccessibleRole(\"Link\") {}`:"));
f.getContentPane().add(createLink(new AccessibleRole("Link") {
}));
f.getContentPane().add(createText("This button uses `new AccessibleRole(\"link\") {}`:"));
f.getContentPane().add(createLink(new AccessibleRole("link") {
}));
f.getContentPane().add(createText("This button uses `new AccessibleRole(\"AXLink\") {}`:"));
f.getContentPane().add(createLink(new AccessibleRole("AXLink") {
}));
}
f.pack();
f.setVisible(true);
}
});
}
private static JTextArea createText(String text) {
JTextArea textArea = new JTextArea(text);
textArea.setOpaque(false);
textArea.setEditable(false);
textArea.setBorder(new EmptyBorder(20, 10, 3, 10));
return textArea;
}
private static JButton createLink(AccessibleRole role) {
String text = "<html><u>https://bugs.openjdk.org/</u></html>";
JButton button = new JButton(text) {
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJButton() {
@Override
public AccessibleRole getAccessibleRole() {
return role;
}
};
}
return accessibleContext;
}
};
button.setContentAreaFilled(false);
button.setBorderPainted(false);
return button;
}
}
```
- links to
-
Review(master)
openjdk/jdk/29686