在鼠标悬停时检索JEditorPane中超链接的title-attribute

时间:2014-11-02 22:23:53

标签: java swing tooltip mouselistener jeditorpane

我想将工具提示添加到(不可编辑的)JEditorPane中的超链接。我在网上找到了一些提示,但没有一个对我有用。这是我目前的做法:

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) {
        //
    }
});

我的编辑器窗格的初始化:

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

编辑器窗格的内容如下:

<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>

从调试开始,我看到当我将鼠标移到编辑器窗格上时,pos总是会发生变化,但是,字符元素e始终是null

所以我的问题是:

  1. 初始化编辑器窗格时,是否需要将编辑器工具包和文档类型设置为HTML?
  2. 如何在编辑器窗格上移动鼠标时获取正确的元素并访问title属性以将其设置为工具提示?

3 个答案:

答案 0 :(得分:4)

您似乎正在处理错误的元素,HTML.Attribute.TITLE既不是锚标记也不是锚标记的属性...

相反,您需要从文档HTML.Tag.A中提取Element属性,然后需要从中提取HTML.Attribute.HREF ...

您可以覆盖由MouseListener调用的组件getToolTipText方法,而不是使用ToolTipManager,并允许您自定义返回的值,例如...... < / p>

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;
    }

};

使用此功能需要您使用ToolTipManager手动注册组件,因为setToolTipText通常会这样做...

ToolTipManager.sharedInstance().registerComponent(editorPane);

nb:如果您想显示alt值,则应使用HTML.Attribute.TITLE代替HTML.Attribute.HREF

答案 1 :(得分:3)

也许您可以使用HyperlinkListener

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public final class HyperlinkTooltipTest {
  private static final String HTML_TEXT = "<html><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>";

  private JComponent makeUI() {
    JEditorPane jEditorPaneIsFollower = new JEditorPane();
    jEditorPaneIsFollower.setEditable(false);
    jEditorPaneIsFollower.setContentType("text/html");
    jEditorPaneIsFollower.setDocument(new HTMLDocument());
    jEditorPaneIsFollower.setEditorKit(new HTMLEditorKit());
    jEditorPaneIsFollower.setText(HTML_TEXT);
    ToolTipManager.sharedInstance().registerComponent(jEditorPaneIsFollower);

    jEditorPaneIsFollower.addHyperlinkListener(new HyperlinkListener() {
      private String tooltip;
      @Override public void hyperlinkUpdate(HyperlinkEvent e) {
        JEditorPane editor = (JEditorPane) e.getSource();
        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
          System.out.println(e);
        } else if (e.getEventType() == HyperlinkEvent.EventType.ENTERED) {
          tooltip = editor.getToolTipText();
          Element elem = e.getSourceElement();
          if (elem != null) {
            AttributeSet attr = elem.getAttributes();
            AttributeSet a = (AttributeSet) attr.getAttribute(HTML.Tag.A);
            if (a != null) {
              editor.setToolTipText((String) a.getAttribute(HTML.Attribute.TITLE));
            }
          }
        } else if (e.getEventType() == HyperlinkEvent.EventType.EXITED) {
          editor.setToolTipText(tooltip);
        }
      }
    });
    return new JScrollPane(jEditorPaneIsFollower);
  }
  public static void main(String... args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new HyperlinkTooltipTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

答案 2 :(得分:0)

CustomEditorPane:

@Override
public String getToolTipText(MouseEvent _event) {
    int pos_ = viewToModel(_event.getPoint());
    if (pos_ < 0) {
        //If not found, then return null
        return null;
    }
    HTMLDocument hdoc_ = (HTMLDocument) getDocument();
    Element e_ = hdoc_.getCharacterElement(pos_);
    AttributeSet a_ = e_.getAttributes();

    Enumeration<?> enumm_ = a_.getAttributeNames();
    while (enumm_.hasMoreElements()) {
        Object o_ = enumm_.nextElement();
        if (!o_.toString().equalsIgnoreCase("a")) {
            //skip html tags that are not anchors
            continue;
        }
        Object value_ = a_.getAttribute(o_);
        //Test if the anchor has an attribute "title"
        if (!(value_ instanceof SimpleAttributeSet)) {
            continue;
        }
        SimpleAttributeSet attSet_ = (SimpleAttributeSet)value_;
        Enumeration<?> at_ = attSet_.getAttributeNames();
        while (at_.hasMoreElements()) {
            Object att_ = at_.nextElement();
            if (att_.toString().equalsIgnoreCase("title")) {
                //return the value of the title of the anchor
                return attSet_.getAttribute(att_).toString();
            }
            //skip other attributes of this anchor
        }
    }
    //The visited tag is not an anchor or the visited anchor has no attribute named title
    return null;
}