2014-11-02 76 views
1

我想將工具提示添加到(不可編輯)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屬性以將其設置爲工具提示?

回答

4

你似乎在處理錯誤的元素,HTML.Attribute.TITLE既不是一個錨標記,錨標籤的屬性...

相反,您需要從文檔Element中提取HTML.Tag.A屬性,然後您需要從中提取HTML.Attribute.HREF ...

而不是使用一個MouseListener的,你可以覆蓋組件getToolTipText方法,它是由ToolTipManager調用,將允許您自定義的返回值,例如...

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

注意:如果你想顯示alt值,你應該使用HTML.Attribute.TITLE代替HTML.Attribute.HREF

+0

非常感謝,作品完美! – Daniel 2014-11-03 09:26:22

+0

很高興幫助... – MadProgrammer 2014-11-03 10:02:06

2

也許你可以使用一個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); 
    } 
} 
+0

這完美的作品,也是如此。兩種解決方案都被接受 – Daniel 2014-11-03 09:29:44

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