Hello,

I created such a class, and am attaching it for anybody who would lie to use it. It
is a bit of a hack, but it works. Any modifications or suggestions will be most
welcome!

-Armen


> Hi,
>
> I am wondering is that possible to create Mutiple line tooltips.  By
> default, the swing is only able to display single line tooltips.
>
> Any idea is much appreciated.
>
> Zhichao

--
Armen Yampolsky
Axiom Software Labs
New York

import java.awt.*;
import java.util.*;
import java.io.*;
import javax.swing.*;

/**
*       A custom tooltip class;
*       Here we determine the dimensions of the tooltip based on the quantity and
*       size of text to be displayed. We overide paint() and setPreferredSize() in
*       order to implement the tooltip as multiline within the new dimensions, and
*       add a few other minor visual tweaks.
*
*       @author Armen Yampolsky
*   Copyright(c) Axiom Software Labs
*/ 
public class CoolTip extends JToolTip
{
        /** default values for tooltip maxwidth, and hpad/vpad for the text */
        public static final int MAX_WIDTH_DEFAULT = 200;
        public static final int HPAD_DEFAULT  = 3;
        public static final int VPAD_DEFAULT = 3;

        /** instance values for tooltip maxwidth, and hpad/vpad for the text */
        private int _maxwidth = MAX_WIDTH_DEFAULT;
        private int _hpad = HPAD_DEFAULT;
        private int _vpad = VPAD_DEFAULT;

        /** the tooltip text, broken down by lines */
        private Vector _textvector = new Vector();
        
        public CoolTip()
        {
                super();
        }

        /** set the tooltip window width */
        public void setMaxWidth(int maxwidth)
        {
                _maxwidth = maxwidth;
        }

        /** set the tooltip text hpadding */    
        public void setHpad(int hpad)
        {
                _hpad = hpad;
        }

        /** set the tooltip text vpadding */            
        public void setVpad(int vpad)
        {
                _vpad = vpad;
        }

        /** overrides JComponent's paint, in order to draw mulitple lines */
        public void paint(Graphics g)
        {
                Font font = this.getFont();
                FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
                Dimension size = this.getSize();
                int line_number = 1;

                g.setColor(this.getBackground());
                g.fillRect(0, 0, size.width, size.height);
                g.setColor(Color.gray);
                g.drawRect(0, 0, size.width-1, size.height-1);
                g.setColor(this.getForeground());               
                g.setFont(font);

                for (Enumeration e = _textvector.elements(); e.hasMoreElements(); 
line_number++)
                {
                        g.drawString((String)e.nextElement(), _hpad, (_vpad + 
metrics.getAscent())*line_number);
                }
        }

        /**
        *       override super's getPreferredSize in order to determine width/height 
such that
        *       each line fits within a specified tooltip window width.
        */
        public Dimension getPreferredSize()
        {
                Font font = this.getFont();
                FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
                String tip_text = this.getTipText();
                String current_line;
                String current_token = "";
                String spacer;
                StringTokenizer st;
                boolean eol;
                int max_width = _maxwidth - (_hpad * 2);
                int width, height;

                // fix for bug 4094153 (Solaris pre-swing1.1 only)              
                if (tip_text == null)
                {
                        return new Dimension(6,metrics.getHeight() + 4);
                }
                else
                {
                        if (metrics.stringWidth(tip_text) > max_width)  //multi-line 
tooltip
                        {
                                st = new StringTokenizer(tip_text);                    
         
                                while (st.hasMoreTokens())
                                {
                                        eol = false;
                                        current_line = current_token;   //make unused 
token from last loop first part of current line
                                        while ( (!eol) && (st.hasMoreTokens()) )
                                        {
                                                current_token = st.nextToken();
                                                if (metrics.stringWidth(current_line + 
" " + current_token) < max_width )
                                                {
                                                        spacer = 
(current_line.length() > 0) ? " " : "";
                                                        current_line = current_line + 
spacer + current_token;
                                                        current_token = "";
                                                }
                                                else
                                                {
                                                        eol = true;
                                                }
                                        }                                       
                                        _textvector.addElement(current_line);
                                }
                                if (current_token.length() > 0)
                                        _textvector.addElement(current_token);
                                
                                width = _maxwidth;
                                height = (_textvector.size())*(metrics.getAscent() + 
_vpad) + _vpad*2;                  
                        }
                        else //single-line tooltip
                        {
                                _textvector.addElement(tip_text);                      
         
                                width = metrics.stringWidth(tip_text) + (_hpad * 2);
                                height = metrics.getHeight() + (_vpad * 2);
                        }
                        return new Dimension(width, height);
                }
        }
        
}

Reply via email to