Search code examples
javaswingtooltipmouselistenerjeditorpane

Retrieve title-attribute of hyperlink in JEditorPane on mouse hover


I want to add tooltips to hyperlinks in a (non-editable) JEditorPane. I found some hints on the web, but none of them worked for me. This is my current approach:

jEditorPaneIsFollower.addMouseMotionListener(new java.awt.event.MouseMotionListener() {
    @Override
    public void mouseMoved(java.awt.event.MouseEvent evt) {
        int pos = jEditorPaneIsFollower.viewToModel(evt.getPoint());
        if (pos >= 0) {
            HTMLDocument hdoc = (HTMLDocument)jEditorPaneIsFollower.getDocument();
            javax.swing.text.Element e = hdoc.getCharacterElement(pos);
            AttributeSet a = e.getAttributes();
            String href = (String) a.getAttribute(javax.swing.text.html.HTML.Attribute.TITLE);
            if (href != null) {
                jEditorPaneIsFollower.setToolTipText(href);
            } else {
                jEditorPaneIsFollower.setToolTipText(null);
            }
        }
        else {
            jEditorPaneIsFollower.setToolTipText(null);
        }
    }
    @Override
    public void mouseDragged(java.awt.event.MouseEvent e) {
        //
    }
});

The initialization of my editor pane:

jEditorPaneIsFollower.setEditable(false);
jEditorPaneIsFollower.setContentType("text/html");
jEditorPaneIsFollower.setDocument(new HTMLDocument());
jEditorPaneIsFollower.setEditorKit(new HTMLEditorKit());

The content of the editor pane is following:

<html>
  <head>
  </head>
  <body>
    <table>
      <tr>
        <td width="1%" valign="top">
          &#220;bergeordnet:
        </td>
        <td valign="top">
          <a href="#cr_288" alt="DRGs als Prozesssteuerung" title="DRGs als Prozesssteuerung">288</a> 
        </td>
      </tr>
    </table>
  </body>
</html>

From debugging, I see that pos always changes when I move the mouse over the editor pane, however, the character element e is always null.

So my questions are:

  1. Do I need to set editor kit and document type to HTML when initializing the editor pane?
  2. How can I fetch the right element and access the title attribute to set it as tooltip when moving the mouse over the editor pane?

Solution

  • You seem to be dealing with the wrong elements, HTML.Attribute.TITLE is neither a anchor tag or property of an anchor tag...

    Instead, you need to extract the HTML.Tag.A attribute from the document Element, you then need to extract the HTML.Attribute.HREF from it...

    Instead of using a MouseListener, you could override the components getToolTipText method which is called by the ToolTipManager and would allow you to customise the value returned, for example...

    JEditorPane editorPane = new JEditorPane() {
    
        @Override
        public String getToolTipText(MouseEvent evt) {
            String text = null;
            int pos = viewToModel(evt.getPoint());
            if (pos >= 0) {
                HTMLDocument hdoc = (HTMLDocument) getDocument();
                javax.swing.text.Element e = hdoc.getCharacterElement(pos);
                AttributeSet a = e.getAttributes();
    
                SimpleAttributeSet value = (SimpleAttributeSet) a.getAttribute(HTML.Tag.A);
                if (value != null) {
                    String href = (String) value.getAttribute(HTML.Attribute.HREF);
                    if (href != null) {
                        text = href;
                    }
                }
            }
            return text;
        }
    
    };
    

    Using this would require you to manually register the component with the ToolTipManager, as setToolTipText does this normally...

    ToolTipManager.sharedInstance().registerComponent(editorPane);
    

    nb: If you want to display the alt value, you should use HTML.Attribute.TITLE instead of HTML.Attribute.HREF