Mehrzeilige Tooltips in Java?

105

Ich versuche, Tooltips in Java anzuzeigen, die möglicherweise eine Absatzlänge haben oder nicht. Wie kann ich lange Tooltips in Zeilenumbrüche umschließen?

Amanda S.
quelle
Bitte geben Sie ein Codebeispiel an.
Stefan Thyberg
1
Werden QuickInfos nicht automatisch in Zeilenumbrüche umgewandelt, wenn sie in HTML-Tags eingeschlossen sind? Ich bin mir nicht sicher, also gebe ich das nicht als Antwort ein.
Paul Tomblin
Paul: Nur wenn Sie explizite Zeilenumbrüche haben.
Amanda S

Antworten:

146

Wenn Sie den Tooltip <html>und die </html>Tags einschließen, können Sie Zeilen mit <br>Tags unterbrechen. Beispiele und Diskussionen finden Sie unter http://www.jguru.com/faq/view.jsp?EID=10653 .

Oder Sie können die JMultiLineToolTip-Klasse verwenden, die an vielen Stellen im Internet zu finden ist, einschließlich https://github.com/ls-cwi/yoshiko-app/blob/master/src/main/java/com/yoshiko/internal/ view / JMultiLineToolTip.java

Paul Tomblin
quelle
1
Ich habe die von Ihnen vorgeschlagene JMultiLineToolTip-Klasse verwendet. Nachdem ich setFixedWidth () verwendet hatte, um den Tooltip auf eine angemessene Größe zu beschränken, funktionierte es hervorragend. Vielen Dank!
Amanda S
24

Tooltip-Text, der mit " <html>" beginnt , wird als HTML behandelt. Das könnte natürlich sehr breites HTML sein.

Sie können JComponent.createTooltip überschreiben , um den Tooltip durch Ihre eigene Komponente zu ersetzen, die anzeigen kann, was Sie möchten.

Tom Hawtin - Tackline
quelle
20

Ich weiß, dass dies ziemlich alt ist, aber ich habe eine ziemlich einfache Lösung mit HTML-Code gefunden!

Verwenden Sie einfach einen HTML-Absatz mit einer festen Breite:

setToolTipText("<html><p width=\"500\">" +value+"</p></html>");
Phwoelfel
quelle
Was ist, wenn ich Text anzeigen möchte, der viel kürzer als die QuickInfo-Größe ist? "max-width" -Tag funktioniert hier nicht
nickolay.laptev
5

Verwenden Sie HTML-QuickInfos und unterbrechen Sie Ihre Zeilen manuell (ein einfacher Wort-Tokenizer mit fester Zeilenlänge sollte dies tun). Stellen Sie einfach sicher, dass Ihr Tooltop-Text mit "<HTML>" beginnt. Unterbrechen Sie die Zeilen mit "<BR/>" oder "<P>". Mir ist klar, dass es nicht die sauberste Lösung ist und Javas HTML-Unterstützung schrecklich ist, aber es sollte alles erledigen.

Basszero
quelle
4

Beispiel:

jTextField1.setToolTipText("<html>"
                              + "Line One"
                              +"<br>"
                              + "Line 2"
                         + "</html>");
ja4
quelle
Dies beantwortet nicht die Frage des Fragestellers. Er fragte nach dem Umbrechen, wenn es angezeigt wird, nicht im Quellcode.
Schlitten
2
@ArtB Dieser Beispielcode enthält einen zweizeiligen Tooltip, wie gefragt.
Thelema
4

Dies könnte etwas verbessert werden, aber mein Ansatz war eine Hilfsfunktion, die vor dem Festlegen des Tooltips aufgerufen wurde und den Tooltip-Text in der angegebenen Länge aufteilte, aber angepasst wurde, um Wörter im Leerzeichen nach Möglichkeit zu unterbrechen.

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

Verwenden Sie wie

jComponent.setToolTipText(MultiLineTooltips.splitToolTip(TOOLTIP));
Paul Taylor
quelle
2

Sie können JToolTip, eine Komponente, unterordnen und createToolTip () für die Komponente überschreiben.

user101884
quelle
1

Hier ist eine Version, die ich zuvor verwendet habe. Sie funktioniert gut, wenn Sie Ihre Tooltipps aus ResourceBundles laden:

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

}

Und Sie würden es verwenden, indem Sie diese Methode aufrufen, bevor Ihre Benutzeroberfläche erstellt wird:

MultiLineToolTipUI.installUI();

Fügen Sie dann in Ihre Eigenschaftendateien einfach Zeilenumbrüche ein, um Ihre QuickInfos wie gewünscht zu verpacken.

Ian Phillips
quelle
1

Ich habe eine Utility-Klasse erstellt, die Zeichenfolgen automatisch mit <br>Tags auf eine bestimmte Länge formatiert . Es basiert auf der von Paul Taylor veröffentlichten MultiLineToolTips-Klasse, hat jedoch einen Fehler, der Teile der Zeichenfolge überspringt und die Zeichenfolge nicht auf eine bestimmte Länge beschränkt.

Um meine Klasse zu verwenden, rufen Sie einfach die splitToolTip-Methode auf, indem Sie schreiben MultiLineToolTips.splitToolTip(yourString);oder MultiLineToolTips.splitToolTip(yourString, maxLength);wenn Sie sie auf eine bestimmte maximale Länge teilen möchten. Dadurch werden gut formatierte Tooltip-Zeichenfolgen erstellt.

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();
    }
}
Andrew LeMaitre
quelle
0

Wenn Sie nur <html>Ihren Tooltip-Text hinzufügen , scheint er zu funktionieren, bis Sie /*...*/oder HTML in Ihrem Text haben. Verwenden <html><pre>oder entkommen Sie Ihrem Text. Ich musste es auch benutzen <font size=3>, um es etwas anständig aussehen zu lassen.

NateS
quelle