Java中的多行工具提示?

Posted

技术标签:

【中文标题】Java中的多行工具提示?【英文标题】:Multi-line tooltips in Java? 【发布时间】:2010-10-26 12:02:08 【问题描述】:

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

【问题讨论】:

请提供代码示例。 如果工具提示包含在 html 标记中,它们不会自动换行吗?我不确定,所以我不会把它作为答案。 保罗:只有当你有明确的换行符。 【参考方案1】:

如果您将工具提示包装在 <html></html> 标记中,则可以使用 <br> 标记换行。有关示例和讨论,请参阅https://web.archive.org/web/20060625031340/http://www.jguru.com/faq/view.jsp?EID=10653。该讨论的主要内容:fButton.setToolTipText("<html><font face=\"sansserif\" color=\"green\">first line<br>second line</font></html>");

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

【讨论】:

我使用了您建议的 JMultiLineToolTip 类。一旦我使用 setFixedWidth() 将工具提示限制在合理的大小,它就很好用。谢谢! 第一个链接似乎不再有效。它已将我重定向到电影网页 @KevinCrum 替换为回程机器的链接。毕竟是 12 年前的事了。【参考方案2】:

使用 HTML 工具提示并手动断行(应该使用具有固定行长度的简单单词标记器来完成)。只需确保您的工具提示文本以“”开头。用“”或“

”换行。我意识到这不是最干净的解决方案,而且 Java 的 HTML 支持很糟糕,但它应该可以完成任务。

【讨论】:

【参考方案3】:

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

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

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

例子:

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

【讨论】:

这没有回答提问者的问题。他问的是在显示时包装,而不是在源代码中。 @ArtB 此示例代码确实按照要求提供了两行工具提示。 @ja4 这个示例代码帮助我制作多行工具提示,非常简单的方法 @Sled 实际上,它确实回答了这个问题,无论是否无意。 Java 中包含在 标记中的所有工具提示文本都会自动换行。因此,例如,如果“第 1 行”真的很长,它本身就会多行,使“第 2 行”成为第三或第四行。【参考方案6】:

这可能会有所改进,但我的方法是在设置工具提示之前调用一个辅助函数,以提供的长度分割工具提示文本,但在可能的情况下调整为在空间上分词。

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

使用喜欢

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

【讨论】:

【参考方案7】:

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


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

MultiLineToolTipUI.installUI();

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

【讨论】:

【参考方案8】:

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

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

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

【讨论】:

如果我想显示比工具提示尺寸短得多的文本怎么办? “最大宽度”标签在这里不起作用 您甚至可以跳过结束标签。也许它不是一个有效的 html,但它工作正常。【参考方案9】:

如果您只是将&lt;html&gt; 添加到您的工具提示文本中,它似乎可以工作,直到您的文本中有/*...*/ 或HTML。使用&lt;html&gt;&lt;pre&gt; 或转义您的文本。我还必须使用&lt;font size=3&gt; 让它看起来有点像样。

【讨论】:

重要的是要提到转义,干得好:)【参考方案10】:

我创建了一个实用程序类,它使用&lt;br&gt; 标签自动将字符串格式化为特定长度。它基于 Paul Taylor 发布的 MultiLineToolTips 类,但其中有一个错误,它会跳过部分字符串,实际上并没有将字符串限制为特定长度。

要使用我的类,只需编写 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://***.com/users/1480018/paul-taylor">Paul Taylor</a>
 * on <a href="https://***.com/a/13503677/9567822">Stack Overflow</a>
 * @author <a href="https://***.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();
    

【讨论】:

以上是关于Java中的多行工具提示?的主要内容,如果未能解决你的问题,请参考以下文章

pydot 图的多行工具提示

如何使 Twitter Bootstrap 工具提示有多行?

如何在 MFC 中获得多行工具提示

如何自动将工具提示文本内容包装到多行?

谷歌图表:带有自定义工具提示的多行

如何使剑道工具提示内容左对齐