Java 在鼠标悬停时检索JEditorPane中超链接的标题属性

Java 在鼠标悬停时检索JEditorPane中超链接的标题属性,java,swing,tooltip,mouselistener,jeditorpane,Java,Swing,Tooltip,Mouselistener,Jeditorpane,我想将工具提示添加到(不可编辑)JEditorPane中的超链接。我在网上找到了一些提示,但没有一个对我有用。这是我目前的做法: jEditorPaneIsFollower.addMouseMotionListener(new java.awt.event.MouseMotionListener() { @Override public void mouseMoved(java.awt.event.MouseEvent evt) { int pos = jEdit

我想将工具提示添加到(不可编辑)
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());
编辑器窗格的内容如下所示:


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

因此,我的问题是:

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

  • 也许您可以使用超链接监听器:

    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);
      }
    }
    
    import java.awt.*;
    导入javax.swing.*;
    导入javax.swing.event.*;
    导入javax.swing.text.*;
    导入javax.swing.text.html.*;
    公共最终类HyperlinkTooltipTest{
    私有静态最终字符串HTML_TEXT=“”
    + ""
    + ""
    +“Ü;bergeordnet:”
    + ""
    + ""
    + ""
    + ""
    + "";
    私有JComponent makeUI(){
    JEditorPane jEditorPaneIsFollower=新的JEditorPane();
    jEditorPaneIsFollower.setEditable(false);
    setContentType(“text/html”);
    setDocument(新的HTMLDocument());
    jEditorPaneIsFollower.setEditorKit(新的HTMLEditorKit());
    jEditorPaneIsFollower.setText(HTML_文本);
    ToolTimManager.sharedInstance().registerComponent(jEditorPaneIsFollower);
    jEditorPaneIsFollower.addHyperlinkListener(新的HyperlinkListener(){
    私有字符串工具提示;
    @重写公共无效hyperlinkUpdate(HyperlinkEvent e){
    JEditorPane编辑器=(JEditorPane)e.getSource();
    如果(e.getEventType()==HyperlinkEvent.EventType.ACTIVATED){
    系统输出打印ln(e);
    }else if(e.getEventType()==HyperlinkEvent.EventType.ENTERED){
    tooltip=editor.getToolTiptText();
    Element elem=e.getSourceElement();
    if(elem!=null){
    AttributeSet attr=elem.getAttributes();
    AttributeSet a=(AttributeSet)attr.getAttribute(HTML.Tag.a);
    如果(a!=null){
    setToolTipText((字符串)a.getAttribute(HTML.Attribute.TITLE));
    }
    }
    }else if(e.getEventType()==HyperlinkEvent.EventType.EXITED){
    编辑器.setToolTipText(工具提示);
    }
    }
    });
    返回新的JScrollPane(jEditorPaneIsFollower);
    }
    公共静态void main(字符串…参数){
    invokeLater(新的Runnable(){
    @重写公共无效运行(){
    createAndShowGUI();
    }
    });
    }
    公共静态void createAndShowGUI(){
    JFrame f=新的JFrame();
    f、 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f、 getContentPane().add(新的HyperlinkTooliptest().makeUI());
    f、 设置大小(320240);
    f、 setLocationRelativeTo(空);
    f、 setVisible(真);
    }
    }
    
    也许您可以使用
    超链接监听器

    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);
      }
    }
    
    import java.awt.*;
    导入javax.swing.*;
    导入javax.swing.event.*;
    导入javax.swing.text.*;
    导入javax.swing.text.html.*;
    公共最终类HyperlinkTooltipTest{
    私有静态最终字符串HTML_TEXT=“”
    + ""
    + ""
    +“Ü;bergeordnet:”
    + ""
    + ""
    + ""
    + ""
    + "";
    私有JComponent makeUI(){
    JEditorPane jEditorPaneIsFollower=新的JEditorPane();
    jEditorPaneIsFollower.setEditable(false);
    setContentType(“text/html”);
    setDocument(新的HTMLDocument());
    jEditorPaneIsFollower.setEditorKit(新的HTMLEditorKit());
    jEditorPaneIsFollower.setText(HTML_文本);
    ToolTimManager.sharedInstance().registerComponent(jEditorPaneIsFollower);
    jEditorPaneIsFollower.addHyperlinkListener(新的HyperlinkListener(){
    私有字符串工具提示;
    @重写公共无效hyperlinkUpdate(HyperlinkEvent e){
    JEditorPane编辑器=(JEditorPane)e.getSource();
    如果(e.getEventType()==HyperlinkEvent.EventType.ACTIVATED){
    系统输出打印ln(e);
    }else if(e.getEventType()==HyperlinkEvent.EventType.ENTERED){
    tooltip=editor.getToolTiptText();
    Element elem=e.getSourceElement();
    if(elem!=null){
    AttributeSet attr=elem.getAttributes();
    AttributeSet a=(AttributeSet)attr.getAttribute(HTML.Tag.a);
    如果(a!=null){
    setToolTipText((字符串)a.getAttribute(HTML.Attribute.TITLE));
    }
    }
    }else if(e.getEventType()==HyperlinkEvent.EventType.EXITED){
    编辑器.setToolTipText(工具提示);
    }
    }
    });
    返回新的JScrollPane(jEditorPaneIsFollower);
    }
    公共静态void main(字符串…参数){
    invokeLater(新的Runnable(){
    @重写公共无效运行(){
    createAndShowGUI();
    }
    });
    }
    公共静态void createAndShowGUI(){
    JFrame f=新的JFrame();
    f、 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f、 getContentPane().add(新的HyperlinkTooliptest().makeUI());
    f、 设置大小(320240);
    f、 setLocationRelativeTo(空);
    f、 setVisible(真);
    }
    }
    
    您似乎在处理错误的元素,
    HTML.Attribute.TITLE
    既不是锚定标记,也不是锚定标记的属性

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

    您可以替代使用
    MouseListener
    ,替代由
    ToolTipManager
    调用的组件
    getToolTipText
    方法,该方法允许您自定义值
    ToolTipManager.sharedInstance().registerComponent(editorPane);
    
    @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;
    }