Java 中的多行工具提示?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/868651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:26:46  来源:igfitidea点击:

Multi-line tooltips in Java?

javaswingtooltip

提问by Amanda S

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

我正在尝试用 Java 显示工具提示,它可能是段落长度,也可能不是。如何对长工具提示进行自动换行?

采纳答案by Paul Tomblin

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=10653for examples and discussion.

如果将工具提示包裹在<html></html>标签中,则可以使用<br>标签换行。有关示例和讨论,请参见http://www.jguru.com/faq/view.jsp?EID=10653

Or you can use the JMultiLineToolTip class that can be found many places on the net, including https://github.com/ls-cwi/yoshiko-app/blob/master/src/main/java/com/yoshiko/internal/view/JMultiLineToolTip.java

或者你可以使用 JMultiLineToolTip 类,可以在网上找到很多地方,包括 https://github.com/ls-cwi/yoshiko-app/blob/master/src/main/java/com/yoshiko/internal/视图/JMultiLineToolTip.java

回答by basszero

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.

使用 HTML 工具提示并手动换行(一个简单的具有固定行长的单词标记器应该可以做到)。只要确保您的工具栏文本以“<HTML>”开头。用“<BR/>”或“<P>”换行。我意识到这不是最干净的解决方案,Java 的 HTML 支持很糟糕,但它应该可以完成任务。

回答by Tom Hawtin - tackline

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

以“ <html>”开头的工具提示文本将被视为 HTML。当然,这可能是非常宽的 HTML。

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

您可以覆盖JComponent.createTooltip以用您自己的组件替换工具提示,该组件可以显示您喜欢的任何内容。

回答by user101884

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

您可以子类化 JToolTip,它是一个组件,并覆盖组件上的 createToolTip()。

回答by ja4

Example:

例子:

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

回答by Paul Taylor

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

回答by Ian Phillips

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

这是我以前使用过的一个版本,如果您从 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:

在创建 UI 之前,您可以通过调用此方法来使用它:

MultiLineToolTipUI.installUI();

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

然后在您的属性文件中插入换行符以根据需要包装您的工具提示。

回答by phwoelfel

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

我知道这个已经很老了,但我找到了一个使用 HTML 代码的非常简单的解决方案!

Just use a HTML Paragraph with a fixed width:

只需使用固定宽度的 HTML 段落:

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

回答by NateS

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.

如果您只是添加<html>到您的工具提示文本,它会一直工作,直到您/*...*/的文本中有或 HTML。使用<html><pre>或转义您的文本。我还不得不使用<font size=3>它来让它看起来有点像样。

回答by Andrew LeMaitre

I created a utility class that automatically formats strings to a specific length with <br>tags. It is based on the MultiLineToolTips class posted by Paul Taylor, but his has a bug in it that skips portions of the string and does not actually limit the string to a specific length.

我创建了一个实用程序类,它自动将字符串格式化为带有<br>标签的特定长度。它基于 Paul Taylor 发布的 MultiLineToolTips 类,但他有一个错误,它跳过部分字符串并且实际上并未将字符串限制为特定长度。

To use my class, simply invoke the splitToolTip method by writing MultiLineToolTips.splitToolTip(yourString);or MultiLineToolTips.splitToolTip(yourString, maxLength);if you want to split it to a specific maximum length. This will create nicely formatted tool tip strings.

要使用我的类,只需通过编写MultiLineToolTips.splitToolTip(yourString);MultiLineToolTips.splitToolTip(yourString, maxLength);要将其拆分为特定的最大长度来调用 splitToolTip 方法。这将创建格式良好的工具提示字符串。

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

/** A helper class to split strings into a certain length,
 * formatted with html {@literal<br>} tags for multi-line tool tips.
 * Based on the MultiLineToolTips class posted by
 * <a href="https://stackoverflow.com/users/1480018/paul-taylor">Paul Taylor</a>
 * on <a href="https://stackoverflow.com/a/13503677/9567822">Stack Overflow</a>
 * @author <a href="https://stackoverflow.com/users/9567822/andrew-lemaitre?tab=profile">Andrew LeMaitre</a>
 */
public final class MultiLineToolTips {

    /** Private constructor for utility class. */
    private MultiLineToolTips() {
    }

    /** Default max length of the tool tip when split with {@link #splitToolTip(String)}. */
    private static final int DIALOG_TOOLTIP_MAX_SIZE = 75;

    /** A function that splits a string into sections of {@value #DIALOG_TOOLTIP_MAX_SIZE} characters or less.
     * If you want the lines to be shorter or longer call {@link #splitToolTip(String, int)}.
     * @param toolTip The tool tip string to be split
     * @return the tool tip string with HTML formatting to break it into sections of the correct length
     */
    public static String splitToolTip(final String toolTip) {
        return splitToolTip(toolTip, DIALOG_TOOLTIP_MAX_SIZE);
    }

    /**  An overloaded function that splits a tool tip string into sections of a specified length.
     * @param toolTip The tool tip string to be split
     * @param desiredLength The maximum length of the tool tip per line
     * @return The tool tip string with HTML formatting to break it into sections of the correct length
     */
    public static String splitToolTip(final String toolTip, final int desiredLength) {
        if (toolTip.length() <= desiredLength) {
            return toolTip;
        }

        List<String>  parts = new ArrayList<>();
        int stringPosition = 0;

        while (stringPosition < toolTip.length()) {
            if (stringPosition + desiredLength < toolTip.length()) {
                String tipSubstring = toolTip.substring(stringPosition, stringPosition + desiredLength);
                int lastSpace = tipSubstring.lastIndexOf(' ');
                if (lastSpace == -1 || lastSpace == 0) {
                    parts.add(toolTip.substring(stringPosition, stringPosition + desiredLength));
                    stringPosition += desiredLength;
                } else {
                    parts.add(toolTip.substring(stringPosition, stringPosition + lastSpace));
                    stringPosition += lastSpace;
                }
            } else {
                parts.add(toolTip.substring(stringPosition));
                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();
    }
}