重载JLabel显示超级链接

                最近在一个Swing项目中,需要用到超级链接(文字或图片超链),直接使用JLabel中HTML显示功能无法实现,因为JLabel可以显示超级链接,但是无法相应超级链接上的鼠标动作。以前用过JEditorPane和JTextPane,十分庞大,在这个项目中不适合。在网上google了一下,找到一个大牛的文章:http://blog.palantirtech.com/2007/07/13/stupid-fast-hyperlinks-for-swing/ 。很不错,实现了在JLabel上显示超级链接,不过,非常简单,只能显示一个超级链接,而且不能显示图片链接。同时,他的实现使得原来JLabel可以通过html中的<br>标签来实现文字换行的功能也随之失效(已经完全不支持html文本显示了)。因此我重新写了一个HyperLinkLabel。也不是很完善,但是已经够用了,不但JLabel 之setIcon()正常使用,而且,可以不用HTML来实现文本换行显示,可以显示任意文字、文字链接、图片链接、图片、文字字体等;以及所有这些元素的任意混合、可以超级链接点击响应等
一共写了四个类,一个是Jabel的继承;一个是BasicLabelUI的继承(关键类);还有两个是用来存储传给label对象的文字解析出来的各种元素,如链接、图片等。

  1. HyperlinkLabel.java
  2. package com.palantir.ui;
  3. import java.awt.BorderLayout;
  4. import java.awt.Color;
  5. import java.awt.Cursor;
  6. import java.awt.Image;
  7. import java.awt.Rectangle;
  8. import java.awt.Toolkit;
  9. import java.awt.event.ActionEvent;
  10. import java.awt.event.ActionListener;
  11. import java.awt.event.MouseEvent;
  12. import java.awt.event.MouseListener;
  13. import java.awt.event.MouseMotionListener;
  14. import java.util.ArrayList;
  15. import javax.swing.ImageIcon;
  16. import javax.swing.JFrame;
  17. import javax.swing.JLabel;
  18. import javax.swing.JPanel;
  19. import javax.swing.SwingConstants;
  20. import javax.swing.Timer;
  21. public class HyperlinkLabel extends JLabel implements MouseListener, MouseMotionListener{
  22.     public static final Color DEFAULT_LINK_COLOR = Color.BLUE;
  23.     public static final String LINK_CLICKED = "HyperlinkLabel.LinkClicked";
  24.     private String actionCommand = LINK_CLICKED;
  25.     private Color linkColor=DEFAULT_LINK_COLOR; 
  26.     private boolean isPaintingLink = false;
  27.     public String label=null;
  28.     private ArrayList<Paragraph> paragraphs=null;
  29.     private HyperLink selectedlink=null;
  30.     public HyperlinkLabel(){
  31.         addMouseListener(this);
  32.         addMouseMotionListener(this);
  33.         setUI(HyperlinkLabelUI.instance);
  34.     }
  35.     private void init(){
  36.       isPaintingLink = false;
  37.       label=null;
  38.       if(paragraphs!=null)
  39.           paragraphs.clear();
  40.       paragraphs=null;
  41.       selectedlink=null;
  42.     }
  43.     public void setLinkColor(final Color linkColor) {
  44.         final Color plinkColor = this.linkColor;
  45.         this.linkColor = linkColor;
  46.         firePropertyChange( "link-color", plinkColor, linkColor );
  47.         
  48.         repaint();
  49.     }
  50.     
  51.     public Color getLinkColor() {
  52.         return linkColor;
  53.     }
  54.     @Override
  55.     public void setText(String label){
  56.         init();
  57.         this.label=label;
  58.     }
  59.     @Override
  60.     public String getText(){
  61.         return this.label;
  62.     }
  63.     public ArrayList<Paragraph> getParagraph(){
  64.         return this.paragraphs;
  65.     }
  66.     public void setParagraph(ArrayList<Paragraph> paragraphs){
  67.         this.paragraphs=paragraphs;
  68.     }
  69.     public HyperLink getSelectedLink(){
  70.         return selectedlink;
  71.     }
  72.     public void rePaintLink(){
  73.         if(selectedlink==null)
  74.             return;
  75.         
  76.     }
  77.     /**
  78.      * Let HyperlinkLabelUI assign the text position so mouse over can be
  79.      * computed properly. 
  80.      * @param x
  81.      * @param y
  82.      * @param width ignored (set to 0) as it isn't referenced in isOnLink
  83.      * @param height
  84.      */
  85.     
  86.     private HyperLink isOnLink(MouseEvent mev){
  87.         if(paragraphs==null)
  88.             return null;
  89.         for(int i=0;i<paragraphs.size();i++){
  90.             if(paragraphs.get(i).hyperlinks!=null){
  91.                for(int j=0;j<paragraphs.get(i).hyperlinks.size();j++){
  92.                    HyperLink link=paragraphs.get(i).hyperlinks.get(j);
  93.                    if(link.linkRect.contains(mev.getPoint()))
  94.                        return link;
  95.                    }
  96.             }
  97.         }       
  98.         return null;
  99.     }
  100.     
  101.     //TODO: override paintComponent to change link color on mouseover?
  102.     public void mousePressed(MouseEvent mev) { }
  103.     public void mouseReleased(MouseEvent mev) { }
  104.     public void mouseClicked(MouseEvent mev) {
  105.         
  106.         if( isEnabled() && (selectedlink=isOnLink(mev))!=null && mev.getButton() == MouseEvent.BUTTON1) {
  107.             fireActionPerformed(new ActionEvent(this, 0, actionCommand));
  108.         }
  109.     }
  110.     public void mouseEntered(MouseEvent mev) {
  111.         resetCursor(mev);
  112.     }
  113.     public void mouseExited(MouseEvent mev) {
  114.         setCursor(Cursor.getDefaultCursor());
  115.     }
  116.     public void mouseMoved(MouseEvent mev) { 
  117.         resetCursor(mev);
  118.     }
  119.     public void mouseDragged(MouseEvent mev) {
  120.         resetCursor(mev);
  121.     }
  122.     
  123.     private void resetCursor(MouseEvent mev) {
  124.         
  125.         boolean onLink = (selectedlink=isOnLink(mev))!=null;
  126.         boolean isDefaultCursor = getCursor().equals(Cursor.getDefaultCursor());
  127.         // not sure if checking whether it's currently the default cursor is cheaper
  128.         // than setting it each time, but I know setCursor doesn't short-circuit if unchanged.
  129.         if( isEnabled() && onLink && isDefaultCursor) {
  130.             setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
  131.         }
  132.         else if(!onLink && !isDefaultCursor) {
  133.             setCursor(Cursor.getDefaultCursor());
  134.         }
  135.     }
  136.     
  137.     public void setActionCommand(String cmd) {
  138.         actionCommand = cmd;
  139.     }
  140.     
  141.     public void addActionListener(ActionListener al) {
  142.         listenerList.add(ActionListener.class, al);
  143.     }
  144.     public void removeActionListener(ActionListener al) {
  145.         listenerList.remove(ActionListener.class, al);
  146.     }
  147.     public void fireActionPerformed(ActionEvent aev){
  148.         for(Object al : listenerList.getListeners(ActionListener.class)) {
  149.             ((ActionListener) al).actionPerformed(aev);
  150.         }
  151.     }
  152.     
  153.     /**
  154.      * Lie about foreground color so BasicLabelUI.paintEnabledText paints
  155.      * the link text in the link color
  156.      */
  157.     @Override
  158.     public Color getForeground() {
  159.         if(isPaintingLink())
  160.             return linkColor;
  161.         else
  162.             return super.getForeground();
  163.     }
  164.     
  165.     public boolean isPaintingLink() {
  166.         return isPaintingLink;
  167.     }
  168.     public void setPaintingLink(boolean isPaintingLink) {
  169.         this.isPaintingLink = isPaintingLink;
  170.     }
  171.     
  172.     public static void main(String[] args) {
  173.         JFrame f = new JFrame("HyperlinkLabel Demo");
  174.         f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  175.         f.setSize(500,333);
  176.         f.setLocation(200,200);     
  177.         final JPanel contentPanel = new JPanel(new BorderLayout());
  178.         final HyperlinkLabel lbl = new HyperlinkLabel();
  179.         lbl.setIconTextGap(5);
  180.         lbl.setVerticalTextPosition(SwingConstants.TOP);
  181.         lbl.setBounds(new Rectangle(lbl.getWidth(),lbl.getHeight()));
  182.         lbl.setText("游戏名称:xxxxxxxxxxx/n<font size=12 color=red style=bold>游戏类型:</font><a src=1>yyyyyyyy</a><img src=/icon.png /><img src=/icon.png width=12 height=12/><img src=/game1313getor/icon.png width=12 height=12/>/n发布时间:xxxxx/n试玩次数:<a src=2><img src=/game1313getor/icon.png/ width=20 height=20/></a><a src=2><img src=/icon.png/ width=20 height=20/></a><a src=2><img src=/game1313getor/icon.png/ width=20 height=20/></a>/n下载次数:0");
  183.         lbl.setBorder(javax.swing.BorderFactory.createEtchedBorder() );
  184.         Image logoImag = Toolkit.getDefaultToolkit().getImage(lbl.getClass().getResource("/demo1.gif"));
  185.         ImageIcon logo=new ImageIcon(logoImag.getScaledInstance(128,128,Image.SCALE_DEFAULT));
  186.         logoImag=null;
  187.         lbl.setIcon(logo);
  188.         JLabel logoLabel = new JLabel(logo);
  189.         logoLabel.setBackground(Color.WHITE);
  190.         logoLabel.setOpaque(true);
  191.         contentPanel.add(logoLabel, BorderLayout.NORTH);    
  192.         final JLabel picLbl = new JLabel(logo);     
  193.         final Timer swapTimer = new Timer(2000, new ActionListener() {
  194.             public void actionPerformed(ActionEvent aev) {
  195.                 contentPanel.remove(picLbl);
  196.                 contentPanel.add(lbl, BorderLayout.CENTER);
  197.                 contentPanel.validate();
  198.                 contentPanel.repaint();
  199.                 ((Timer) aev.getSource()).stop();
  200.             }
  201.         });
  202.         
  203.         lbl.addActionListener(new ActionListener() {
  204.             public void actionPerformed(ActionEvent aev) {
  205.                 HyperLink link=lbl.getSelectedLink();
  206.                 int linkID=0;
  207.                 if(link.targetUrl!=null)
  208.                     linkID=Integer.parseInt(link.targetUrl);
  209.                 if(linkID==2){
  210.                     contentPanel.remove(lbl);
  211.                     contentPanel.add(picLbl, BorderLayout.CENTER);
  212.                     contentPanel.validate();
  213.                     contentPanel.repaint();
  214.                     swapTimer.start();
  215.                 }
  216.             }
  217.         });     
  218.         contentPanel.add(lbl, BorderLayout.CENTER);
  219.         f.setContentPane(contentPanel);     
  220.         f.setVisible(true);
  221.     }
  222. }
  223. HyperlinkLabelUI.java
  224. package com.palantir.ui;
  225. import java.awt.Color;
  226. import java.awt.Font;
  227. import java.awt.FontMetrics;
  228. import java.awt.Graphics;
  229. import java.awt.Graphics2D;
  230. import java.awt.Image;
  231. import java.awt.Point;
  232. import java.awt.Rectangle;
  233. import java.awt.font.LineMetrics;
  234. import java.util.ArrayList;
  235. import java.util.StringTokenizer;
  236. import javax.swing.ImageIcon;
  237. import javax.swing.JLabel;
  238. import javax.swing.plaf.basic.BasicLabelUI;
  239. public class HyperlinkLabelUI extends BasicLabelUI {
  240.     public static HyperlinkLabelUI instance = new HyperlinkLabelUI();   
  241.     @Override
  242.     protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY){
  243.         if(textX<126)
  244.             textX=126;
  245.         if(textY>18)
  246.             textY=18;
  247.         if(l instanceof HyperlinkLabel) {
  248.             int accChar = l.getDisplayedMnemonic();
  249.             drawString((HyperlinkLabel)l,g, ((HyperlinkLabel)l).getText(), accChar, textX, textY);
  250.         }else {
  251.             super.paintEnabledText(l, g, s, textX, textY);
  252.             return;
  253.         }
  254.     }
  255.     
  256.     protected void paintUnderline(LineMetrics lm, Graphics g, Color c, int linkWidth, int textX, int textY){
  257.         Graphics2D g2d = (Graphics2D) g;    
  258.         double baseline = textY + Math.ceil(lm.getUnderlineOffset());
  259.         if(linkWidth > 0) {
  260.             g.setColor(c);
  261.             g2d.drawLine(textX, (int) baseline, textX + linkWidth, (int) baseline);
  262.         }
  263.     }
  264.     
  265.     protected void drawString(HyperlinkLabel l, Graphics g, String s, int accChar, int textX, int textY ){
  266.         if(l.getParagraph()==null){
  267.             //-----------------------get lines-------------------
  268.             ArrayList<Paragraph> paragraphs=new ArrayList<Paragraph>(0);
  269.             //System.out.println(l.getText());
  270.             StringTokenizer tokenizer=new StringTokenizer(l.getText(),"/n");
  271.             int count=0;
  272.             int height = g.getFontMetrics().getHeight()+2;
  273.             FontMetrics fm = l.getFontMetrics(l.getFont());                           
  274.             while(tokenizer.hasMoreTokens()){
  275.                 Paragraph paragraph=new Paragraph();
  276.                 String token=tokenizer.nextToken();
  277.                 int lastElementWidth=0;
  278.                 int yPos=textY + (height*count);
  279.                 //------------------get all elements in a line--------------------
  280.                 while(token!=null&&token.length()>0){
  281.                     System.out.println("lastElementWidth="+lastElementWidth);
  282.                     int firstTextIndex=token.indexOf("<");                    
  283.                     if(firstTextIndex>0){//
  284.                         String txt=token.substring(0,firstTextIndex);
  285.                         token=token.substring(firstTextIndex);
  286.                         TextElement text=new TextElement(new Point(textX+lastElementWidth, yPos ),txt);
  287.                         paragraph.addText(text);
  288.                         lastElementWidth+=fm.stringWidth(txt);
  289.                         //continue;
  290.                     }else if(token.indexOf("<img")==0){//imgage element
  291.                         int imgEndIndex=token.indexOf("/>");
  292.                         imgEndIndex+="/>".length();
  293.                         String imgText=token.substring(0,imgEndIndex);
  294.                         token=token.substring(imgEndIndex);
  295.                         Image img=HyperLink.parseImage(imgText);
  296.                         ImageElement imgElement=new ImageElement(new Point(textX+lastElementWidth, yPos ),new ImageIcon(img));
  297.                         
  298.                         lastElementWidth=lastElementWidth+imgElement.img.getIconWidth();
  299.                         paragraph.addImage(imgElement);
  300.                         
  301.                     }else if(token.indexOf("<a")==0){//link element
  302.                         int linkEndIndex=token.indexOf("</a>");
  303.                         linkEndIndex+="</a>".length();
  304.                         String linkText=token.substring(0,linkEndIndex);
  305.                         token=token.substring(linkEndIndex);
  306.                         HyperLink link=HyperLink.parseLink(linkText, new Point(textX+lastElementWidth,yPos),g);
  307.                         if(link.linkText!=null)
  308.                             lastElementWidth=lastElementWidth+fm.stringWidth(link.linkText);
  309.                         else
  310.                             lastElementWidth=lastElementWidth+link.image.getIconWidth();
  311.                         paragraph.addHyperLink(link);
  312.                         //-------------------set the rect for every link-----------------------
  313.                         if(link.linkText!=null){
  314.                             int linkWidth = fm.stringWidth(link.linkText);
  315.                             LineMetrics lm=fm.getLineMetrics(link.linkText, g);
  316.                             Rectangle rec=new Rectangle();
  317.                             rec.x=link.startPoint.x;
  318.                             rec.y=link.startPoint.y- Math.round(lm.getHeight())+1;
  319.                             linkWidth = fm.stringWidth(link.linkText);
  320.                             rec.width=linkWidth;
  321.                             rec.height=Math.round(lm.getHeight())+2;
  322.                             link.setRectangle(rec);
  323.                         }else{
  324.                             LineMetrics lm = null;
  325.                             lm=fm.getLineMetrics("", g);
  326.                             Rectangle rec=new Rectangle();
  327.                             rec.x=link.startPoint.x;
  328.                             rec.y=link.startPoint.y- Math.round(lm.getHeight())+1;
  329.                             rec.width=link.image.getIconWidth();
  330.                             rec.height=Math.round(lm.getHeight())+2;
  331.                             link.setRectangle(rec);
  332.                         }
  333.                     }else if(token.indexOf("<font")==0){//font element
  334.                         Font labelFont=l.getFont();
  335.                         fm = l.getFontMetrics(labelFont);
  336.                         int index=token.indexOf(">");
  337.                         int fontEndIndex=token.indexOf("</font>");
  338.                         fontEndIndex+="</font>".length();
  339.                         String fontText=token.substring(0,fontEndIndex);
  340.                         token=token.substring(fontEndIndex);
  341.                         String txt=fontText.substring(fontText.indexOf(">")+1,fontText.indexOf("</font>"));
  342.                         String tagContent=fontText.substring("<font".length(),index);
  343.                         StringTokenizer fontTokenizer=new StringTokenizer(tagContent);
  344.                         String family=labelFont.getFamily();
  345.                         int size=0;
  346.                         int style=Font.PLAIN;
  347.                         Color color=g.getColor();
  348.                         while(fontTokenizer.hasMoreTokens()){
  349.                             String key=fontTokenizer.nextToken();
  350.                             if(key!=null){
  351.                                 key=key.trim();
  352.                                 String value=null;
  353.                                 if(key.indexOf("=")>0){
  354.                                     value=key.substring(key.indexOf("=")+1);
  355.                                     value=value.trim();
  356.                                     if(key.startsWith("color")){
  357.                                        if(value.equals("red")){
  358.                                            color=Color.RED;
  359.                                        }
  360.                                     }else if(key.startsWith("size")){
  361.                                         size=Integer.parseInt(value);
  362.                                     }else if(key.startsWith("style")){
  363.                                         
  364.                                         if(value.equals("bold")){
  365.                                             style=Font.BOLD;
  366.                                         }
  367.                                     }else if(key.startsWith("family")){
  368.                                         family=value;
  369.                                     }
  370.                                 }
  371.                             }
  372.                         }
  373.                         Font littleFont = new Font(family, style, size);
  374.                         FontMetrics fmm=l.getFontMetrics(littleFont);
  375.                         yPos=textY + (fm.getHeight()*(count-1));
  376.                         yPos+=fmm.getHeight();
  377.                         TextElement text=new TextElement(new Point(textX+lastElementWidth, yPos),txt);
  378.                         text.font=littleFont;
  379.                         text.color=color;
  380.                         paragraph.addText(text);
  381.                         lastElementWidth+=fmm.stringWidth(txt);
  382.                         //fm = l.getFontMetrics(labelFont);
  383.                     }else{//not any tag in the whole line
  384.                         TextElement text=new TextElement(new Point(textX+lastElementWidth, yPos),token);
  385.                         paragraph.addText(text);
  386.                         lastElementWidth+=fm.stringWidth(token);
  387.                         break;
  388.                     }
  389.                 }
  390.                 paragraphs.add(paragraph);
  391.                 count++;
  392.             }
  393.             l.setParagraph(paragraphs);
  394.         }
  395.         //draw the lines
  396.         ArrayList<Paragraph> paragraphs=l.getParagraph();
  397.         FontMetrics fm = l.getFontMetrics(l.getFont());
  398.         Color linkColor = l.getLinkColor();
  399.         Color clr=g.getColor();
  400.         
  401.         for(int i=0;i<paragraphs.size();i++){
  402.             Paragraph p=paragraphs.get(i);
  403.             if(p.hyperlinks!=null)
  404.             for(int j=0;j<p.hyperlinks.size();j++){
  405.                 HyperLink link=p.hyperlinks.get(j);
  406.                 if(link!=null){
  407.                     if(link.linkText!=null){
  408.                         g.drawString( link.linkText, link.startPoint.x, link.startPoint.y );
  409.                         l.setPaintingLink(true);
  410.                         super.paintEnabledText(l, g, link.linkText,link.startPoint.x, link.startPoint.y);
  411.                         l.setPaintingLink(false);
  412.                         LineMetrics lm = fm.getLineMetrics(link.linkText, g);
  413.                         int linkWidth = fm.stringWidth(link.linkText);
  414.                         paintUnderline(lm, g, linkColor, linkWidth,link.startPoint.x, link.startPoint.y);
  415.                         g.setColor(clr);
  416.                     }else{
  417.                         LineMetrics lm = null;
  418.                         lm=fm.getLineMetrics("", g);
  419.                         g.drawImage( link.image.getImage(), link.startPoint.x, link.startPoint.y- Math.round(lm.getHeight())+1,null,null );
  420.                         l.setPaintingLink(true);
  421.                         super.paintEnabledText(l, g, link.linkText,link.startPoint.x, link.startPoint.y);
  422.                         l.setPaintingLink(false);
  423.                         g.setColor(clr);
  424.                     }
  425.                 }
  426.             }
  427.             if(p.imgs!=null){
  428.                 LineMetrics lm = null;
  429.                 lm=fm.getLineMetrics("", g);
  430.                 for(int j=0;j<p.imgs.size();j++){
  431.                     ImageElement img=p.imgs.get(j);
  432.                     g.drawImage( img.img.getImage(), img.startPoint.x, img.startPoint.y- Math.round(lm.getHeight())+1,null,null );
  433.                 }
  434.             }
  435.             if(p.texts!=null){
  436.                 for(int j=0;j<p.texts.size();j++){
  437.                     TextElement text=p.texts.get(j);
  438.                     if(text.font!=null){
  439.                         Font labelFont=l.getFont();
  440.                         g.setFont(text.font);
  441.                         if(text.color!=null){
  442.                           g.setColor(text.color);
  443.                         }
  444.                         g.drawString( p.texts.get(j).text, p.texts.get(j).startPoint.x, p.texts.get(j).startPoint.y );
  445.                         g.setColor(clr);
  446.                         g.setFont(labelFont);
  447.                     }else{
  448.                         g.drawString( p.texts.get(j).text, p.texts.get(j).startPoint.x, p.texts.get(j).startPoint.y );
  449.                     }
  450.                 }
  451.             }
  452.         }
  453.     }
  454. }
  455. HyperLink.java
  456. /*
  457.  * To change this template, choose Tools | Templates
  458.  * and open the template in the editor.
  459.  */
  460. package com.palantir.ui;
  461. import java.awt.Graphics;
  462. import java.awt.Image;
  463. import java.awt.Point;
  464. import java.awt.Rectangle;
  465. import java.awt.Toolkit;
  466. import java.util.HashMap;
  467. import java.util.StringTokenizer;
  468. import javax.swing.ImageIcon;
  469. /**
  470.  * @author Sainese
  471.  */
  472. //<a>text</a>
  473. //<a><img src=xxx width=aa height=bb/></a>
  474. //No regrex so , so no spaces in tags.
  475. public class HyperLink {
  476.     public Point startPoint;
  477.     public Rectangle linkRect;
  478.     public String linkText;
  479.     public ImageIcon image;
  480.     public String targetUrl;
  481.     private static HashMap map=new HashMap();
  482.     public HyperLink(Point startPoint,String linkText,String targetUrl){
  483.         this.startPoint=startPoint;
  484.         this.linkText=linkText;
  485.         this.targetUrl=targetUrl;
  486.     }
  487.     public HyperLink(Point startPoint,Image image,String targetUrl){
  488.         this.startPoint=startPoint;
  489.         this.image=new ImageIcon(image);
  490.         this.targetUrl=targetUrl;
  491.     }
  492.     public void setRectangle(Rectangle rec){
  493.         this.linkRect=rec;
  494.     }
  495.     public static HyperLink parseLink(String originString,Point startPoint,Graphics g){
  496.         HyperLink link=null;
  497.         String targetUrl=null;
  498.         if(originString.startsWith("<a")&&originString.endsWith("</a>")){
  499.             int EmbedObjectStartIndex=originString.indexOf(">");
  500.             int srcStartIndex=originString.indexOf("src=");
  501.             if(srcStartIndex>0){
  502.                 srcStartIndex+=4;
  503.                 targetUrl=originString.substring(srcStartIndex,EmbedObjectStartIndex);
  504.             }                       
  505.             int endIndex=originString.indexOf("</a>");         
  506.             EmbedObjectStartIndex+=1;
  507.             String embeddedString=originString.substring(EmbedObjectStartIndex,endIndex);
  508.             //System.out.println("embeddedString="+embeddedString);
  509.             if(embeddedString.startsWith("<img")&&embeddedString.endsWith("/>")){
  510.                 link=new HyperLink(startPoint,parseImage(embeddedString),targetUrl);
  511.             }else{
  512.                 link=new HyperLink(startPoint,embeddedString,targetUrl);
  513.             }
  514.         }
  515.         return link;
  516.     }
  517.     public static Image parseImage(String originString){
  518.         String src=null;
  519.         int width=0;
  520.         int height=0;
  521.         int srcStartIndex="<img".length();
  522.         originString=originString.substring(srcStartIndex,originString.indexOf("/>"));
  523.         StringTokenizer tokenizer=new StringTokenizer(originString," ");
  524.         while(tokenizer.hasMoreTokens()){
  525.             String token=tokenizer.nextToken();
  526.             if(token!=null){
  527.                 token=token.trim();
  528.                 if(token.startsWith("src")){
  529.                     src=token.substring(token.indexOf("=")+1);
  530.                 }else if(token.startsWith("width")){
  531.                     width=Integer.parseInt(token.substring(token.indexOf("=")+1));
  532.                 }else if(token.startsWith("height")){
  533.                     height=Integer.parseInt(token.substring(token.indexOf("=")+1));
  534.                 }
  535.             }
  536.         }
  537.         src=src.trim();
  538.         Object obj=map.get(src);
  539.         Image img =null;
  540.         if(obj!=null){
  541.             img=(Image)obj;
  542.             //System.out.println("image has been created before");
  543.         }else{
  544.             img = Toolkit.getDefaultToolkit().getImage(HyperLink.class.getResource(src));
  545.             if(width==0){
  546.                 width=img.getWidth(null);
  547.                 height=img.getHeight(null);
  548.             }
  549.             img=img.getScaledInstance(width,height,Image.SCALE_DEFAULT);
  550.             map.put(src, img);
  551.             //System.out.println("create a brand new image");
  552.         }
  553.         return img;
  554.         
  555.     }
  556. }
  557. Paragraph.java
  558. /*
  559.  * To change this template, choose Tools | Templates
  560.  * and open the template in the editor.
  561.  */
  562. package com.palantir.ui;
  563. import java.util.ArrayList;
  564. /**
  565.  *
  566.  * @author Sainese
  567.  */
  568. public class Paragraph{
  569.     /*public Point prefixTextPos;
  570.     public Point suffixTextPos;
  571.     public String prefixText;
  572.     public String suffixText;
  573.     public HyperLink hyperlink;*/
  574.     public ArrayList<TextElement> texts;
  575.     public ArrayList<ImageElement> imgs;
  576.     public ArrayList<HyperLink> hyperlinks;
  577.     public void destroy(){
  578.         if(texts!=null)
  579.             texts.clear();
  580.         if(imgs!=null)
  581.             imgs.clear();
  582.         if(hyperlinks!=null)
  583.             hyperlinks.clear();
  584.         texts=null;
  585.         imgs=null;
  586.         hyperlinks=null;
  587.     }
  588.     public void addText(TextElement txt){
  589.         if(texts==null)
  590.             texts=new ArrayList<TextElement>(1);
  591.         texts.add(txt);
  592.     }
  593.     public void addImage(ImageElement img){
  594.         if(imgs==null)
  595.             imgs=new ArrayList<ImageElement>(1);
  596.         imgs.add(img);
  597.     }
  598.     public void addHyperLink(HyperLink link){
  599.         if(hyperlinks==null)
  600.             hyperlinks=new ArrayList<HyperLink>(1);
  601.         hyperlinks.add(link);
  602.     }
  603. }


  1. ImageElement.java
  2. /*
  3.  * To change this template, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6. package com.palantir.ui;
  7. import java.awt.Point;
  8. import javax.swing.ImageIcon;
  9. /**
  10.  *
  11.  * @author Sainese
  12.  */
  13. public class ImageElement {
  14.     public Point startPoint;
  15.     public ImageIcon img;
  16.     public ImageElement(Point startPoint,ImageIcon img){
  17.         this.startPoint=startPoint;
  18.         this.img=img;
  19.     }
  20. }
  21. TextElement.java
  22. /*
  23.  * To change this template, choose Tools | Templates
  24.  * and open the template in the editor.
  25.  */
  26. package com.palantir.ui;
  27. import java.awt.Color;
  28. import java.awt.Font;
  29. import java.awt.Point;
  30. /**
  31.  *
  32.  * @author Sainese
  33.  */
  34. public class TextElement {
  35.     public Point startPoint;
  36.     public String text;
  37.     public Font font;
  38.     public Color color;
  39.     public TextElement(Point startPoint,String text){
  40.         this.startPoint=startPoint;
  41.         this.text=text;
  42.     }
  43.     public void setColor(Font f){
  44.         font=f;
  45.     }
  46.     public void setColor(Color clr){
  47.         color=clr;
  48.     }
  49. }



代码已经在工程中使用,可以直接Copy使用。最初作者的名字和包名应该我都还留着。其实已经没有几行代码是他的了。这个HyperLinkLabel显示的是/n和一些html tag的混合体字符串。当时因为敢工期,所以,很多tag都随手写下,有些错误如<a src=xxx>等tag不符合html规范的,不过没关系,达到我要的目的就可以了。






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值