Multi-line tooltips in Java?

I’m trying to display tooltips in Java which may or may not be paragraph-length. How can I word-wrap long tooltips?

Make all tooltips multiline in Java (Swing)

Tooltips in my application can be quite long, therefore I’d like them to have line breaks. I don’t want to use html as I’d prefer to set a (max) width of my tooltips instead and have the line breaks d

Are multiline tooltips possible using CWnd::EnableTooltips()?

I’m attempting to make my tooltips multiline, but I don’t seem to be having much luck with it. I call CWnd::EnableTooltips() directly after creation (in this case, an edit box) and I handle the TTN_NE



Multiline JLabels – Java

I want JLabel text in multiline format otherwise text will be too long. How can we do this in Java?

Java 7 – Multiline strings

I’ve read that multiline string literals were proposed to be added in Java 7. Although I can’t find any documentation saying definitely that they have been. I’d like to know if they are, because this

Java regex replaceAll multiline

I have a problem with the replaceAll for a multiline string: String regex = //s*///*.*//*/; String testWorks = /** this should be replaced **/ just text; String testIllegal = /** this should be

Java annotation utility for multiline text

WRT Any Future Plans for Multiline Java String. How difficult is it to write a utility that does the following? @AllYouCanEatText(return=query) private String getQuery(String empid, String[] columns

Logstash multiline filter configuration and java exceptions

We started recently to gather all java server logs with logstash. Default log4j configuration works fine, but for exceptions and sql queries we use : http://logstash.net/docs/1.2.2/filters/multiline

Java3D stuttering issue with Swing tooltips

A Java project I am working on is having a bizarre conflict between Java3d and Swing tooltips. Our program is setup with a Java3D Canvas3D in the center surrounded by Swing JComponents (buttons, slide

Java multiline string

Coming from Perl, I sure am missing the here-document means of creating a multi-line string in source code: $string = <<EOF # create a three line string text text text EOF In Java I have to

Java multiline string formation

I’m by no means a java programmer, so this may seem pretty basic. Which of these are ‘better’ when you want to keep your code lines short. String str = First part of a string.; str += Second part

Answers

If you wrap the tooltip in <html> and </html> tags, you can break lines with <br> tags. See http://www.jguru.com/faq/view.jsp?EID=10653 for examples and discussion.

Or you can use the JMultiLineToolTip class that can be found many places on the net, including http://code.ohloh.net/search?s=jmultilinetooltip

Use HTML tooltips and manually break your lines (a simple word tokenizer with a fixed line length should do it). Just make sure your tooltop text starts with “<HTML>”. Break lines with “<BR/>” or “<P>”. I realize it’s not the most clean solution and Java’s HTML support is horrible, but it should get things done.

Tooltip text which starts with “<html>” will be treated as HTML. Of course that might be very wide HTML.

You can override JComponent.createTooltip to replace the tooltip with your own component which can display whatevee you like.

You can subclass JToolTip, which is a Component, and override createToolTip() on the component.

Example:

jTextField1.setToolTipText("<html>"
                              + "Line One"
                              +"<br>"
                              + "Line 2"
                         + "</html>");

This could be improved somewhat, but my approach was a helper function called before setting tooltip that split the tooltip text at provided length, but adjusted to break words on space where possible.

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class MultiLineTooltips
{
    private static int DIALOG_TOOLTIP_MAX_SIZE = 75;
    private static final int SPACE_BUFFER = 10;

    public static String splitToolTip(String tip)
    {
        return splitToolTip(tip,DIALOG_TOOLTIP_MAX_SIZE);
    }
    public static String splitToolTip(String tip,int length)
    {
        if(tip.length()<=length + SPACE_BUFFER )
        {
            return tip;
        }

        List<String>  parts = new ArrayList<>();

        int maxLength = 0;
        String overLong = tip.substring(0, length + SPACE_BUFFER);
        int lastSpace = overLong.lastIndexOf(' ');
        if(lastSpace >= length)
        {
            parts.add(tip.substring(0,lastSpace));
            maxLength = lastSpace;
        }
        else
        {
            parts.add(tip.substring(0,length));
            maxLength = length;
        }

        while(maxLength < tip.length())
        {
            if(maxLength + length < tip.length())
            {
                parts.add(tip.substring(maxLength, maxLength + length));
                maxLength+=maxLength+length;
            }
            else
            {
                parts.add(tip.substring(maxLength));
                break;
            }
        }

        StringBuilder  sb = new StringBuilder("<html>");
        for(int i=0;i<parts.size() - 1;i++)
        {
            sb.append(parts.get(i)+"<br>");
        }
        sb.append(parts.get(parts.size() - 1));
        sb.append(("</html>"));
        return sb.toString();
    }
}

Use like

jComponent.setToolTipText(MultiLineTooltips.splitToolTip(TOOLTIP));

Here is a version which I have used before, it works well if you are loading your tool tips from ResourceBundles:

import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ToolTipUI;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.util.regex.Pattern;

/**
 * A tooltip that wraps multi-line text.
 */
public final class MultiLineToolTipUI extends ToolTipUI {

    private static final int INSET = 2;

    private static final Pattern LINE_SPLITTER = Pattern.compile("$", Pattern.MULTILINE);

    private static final MultiLineToolTipUI SHARED_INSTANCE = new MultiLineToolTipUI();

    /**
     * Install the multi-line tooltip into the UI manager.
     */
    public static void installUI() {
        String toolTipUI = MultiLineToolTipUI.class.getName();
        UIManager.put("ToolTipUI", toolTipUI);
        UIManager.put(toolTipUI, MultiLineToolTipUI.class);
    }

    @SuppressWarnings("UnusedDeclaration")
    public static ComponentUI createUI(JComponent c) {
        return SHARED_INSTANCE;
    }

    private MultiLineToolTipUI() {}

    @Override
    public Dimension getMaximumSize(JComponent c) {
        return getPreferredSize(c);
    }

    @Override
    public Dimension getMinimumSize(JComponent c) {
        return getPreferredSize(c);
    }

    @Override
    public Dimension getPreferredSize(JComponent c) {
        String[] lines = LINE_SPLITTER.split(((JToolTip) c).getTipText());
        if (lines.length == 0) {
            return new Dimension(2 * INSET, 2 * INSET);
        }
        FontMetrics metrics = c.getFontMetrics(c.getFont());
        Graphics g = c.getGraphics();
        int w = 0;
        for (String line : lines) {
            w = Math.max(w, (int) metrics.getStringBounds(line, g).getWidth());
        }
        int h = lines.length * metrics.getHeight();
        return new Dimension(w + 2 * INSET, h + 2 * INSET);
    }

    @Override
    public void installUI(JComponent c) {
        LookAndFeel.installColorsAndFont(c, "ToolTip.background", "ToolTip.foreground", "ToolTip.font");
        LookAndFeel.installBorder(c, "ToolTip.border");
    }

    @Override
    public void paint(Graphics g, JComponent c) {
        int w = c.getWidth(), h = c.getHeight();
        g.setColor(c.getBackground());
        g.fillRect(0, 0, w, h);
        g.setColor(c.getForeground());
        g.drawRect(0, 0, w, h);
        String[] lines = LINE_SPLITTER.split(((JToolTip) c).getTipText());
        if (lines.length != 0) {
            FontMetrics metrics = c.getFontMetrics(c.getFont());
            int height = metrics.getHeight();
            int y = INSET + metrics.getAscent();
            for (String line : lines) {
                g.drawString(line, INSET, y);
                y += height;
            }
        }
    }

    @Override
    public void uninstallUI(JComponent c) {
        LookAndFeel.uninstallBorder(c);
    }

}

And you would use it by calling this method, before your UI is created:

MultiLineToolTipUI.installUI();

Then in your properties files just insert newlines to wrap your tool tips as desired.

I know this one is quite old but i found a quite simple solution using HTML code!

Just use a HTML Paragraph with a fixed width:

setToolTipText("<html><p width=/"500/">" +value+"</p></html>");

If you just add <html> to your tooltip text, it will appear to work until you have /*…*/ or HTML in your text. Use <html><pre> or escape your text. I also had to use <font size=3> to get it looking somewhat decent.