VoiceOver Identifies Hyperlink as Text

XMLWordPrintable

    • 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/&lt;/u&gt;&lt;/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;
          }
      }

      ```

            Assignee:
            Jeremy Wood
            Reporter:
            Jeremy Wood
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: