Tooltip multi-baris di Java?


105

Saya mencoba untuk menampilkan tooltips di Java yang mungkin sepanjang paragraf atau tidak. Bagaimana saya bisa membungkus tooltips panjang?


Berikan contoh kode.
Stefan Thyberg

1
Bukankah tip alat secara otomatis membungkus kata jika dibungkus dalam tag HTML? Saya tidak yakin, jadi saya tidak memasukkan ini sebagai jawaban.
Paul Tomblin

Paul: Hanya jika Anda memiliki pemisah baris yang eksplisit.
Amanda S

Jawaban:


146

Jika Anda membungkus tooltip dengan tag <html>dan </html>, Anda dapat memutus baris dengan <br>tag. Lihat http://www.jguru.com/faq/view.jsp?EID=10653 untuk contoh dan diskusi.

Atau Anda dapat menggunakan kelas JMultiLineToolTip yang dapat ditemukan di banyak tempat di internet, termasuk https://github.com/ls-cwi/yoshiko-app/blob/master/src/main/java/com/yoshiko/internal/ view / JMultiLineToolTip.java


1
Saya menggunakan kelas JMultiLineToolTip yang Anda sarankan. Setelah saya menggunakan setFixedWidth () untuk membatasi tooltip ke ukuran yang wajar, itu bekerja dengan baik. Terima kasih!
Amanda S

24

Teks keterangan alat yang dimulai dengan " <html>" akan diperlakukan sebagai HTML. Tentu saja itu mungkin HTML yang sangat lebar.

Anda dapat mengganti JComponent.createTooltip untuk mengganti tooltip dengan komponen Anda sendiri yang dapat menampilkan apa pun yang Anda suka.


20

Saya tahu yang ini sudah cukup tua tetapi saya menemukan solusi yang cukup sederhana dengan menggunakan kode HTML!

Cukup gunakan Paragraf HTML dengan lebar tetap:

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

Bagaimana jika saya ingin menampilkan teks yang lebih pendek dari ukuran tooltip? Tag "max-width" tidak berfungsi di sini
nickolay.laptev

5

Gunakan tooltips HTML dan hancurkan baris Anda secara manual (pembuat token kata sederhana dengan panjang baris tetap harus melakukannya). Pastikan teks tooltop Anda dimulai dengan "<HTML>". Putuskan baris dengan "<BRaught" atau "<P>". Saya menyadari ini bukan solusi yang paling bersih dan dukungan HTML Java sangat buruk, tetapi harus menyelesaikan banyak hal.


4

Contoh:

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

Ini tidak menjawab pertanyaan penanya. Dia bertanya tentang pembungkusan saat ditampilkan, bukan dalam kode sumber.
Kereta luncur

2
@ArtB kode contoh ini memberikan keterangan alat dua baris seperti yang diminta.
Thelema

4

Ini bisa sedikit ditingkatkan, tetapi pendekatan saya adalah fungsi pembantu yang dipanggil sebelum mengatur tooltip yang membagi teks tooltip pada panjang yang disediakan, tetapi disesuaikan untuk memecah kata-kata di ruang jika memungkinkan.

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

Gunakan seperti

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

2

Anda bisa membuat subkelas JToolTip, yang merupakan Komponen, dan mengganti createToolTip () pada komponen.


1

Ini adalah versi yang telah saya gunakan sebelumnya, ini berfungsi dengan baik jika Anda memuat tip alat Anda dari 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);
    }

}

Dan Anda akan menggunakannya dengan memanggil metode ini, sebelum UI Anda dibuat:

MultiLineToolTipUI.installUI();

Kemudian di file properti Anda cukup masukkan baris baru untuk membungkus tip alat Anda seperti yang diinginkan.


1

Saya membuat kelas utilitas yang secara otomatis memformat string dengan panjang tertentu dengan <br>tag. Ini didasarkan pada kelas MultiLineToolTips yang diposting oleh Paul Taylor, tetapi miliknya memiliki bug di dalamnya yang melewatkan bagian dari string dan tidak benar-benar membatasi string ke panjang tertentu.

Untuk menggunakan kelas saya, cukup aktifkan metode splitToolTip dengan menulis MultiLineToolTips.splitToolTip(yourString);atau MultiLineToolTips.splitToolTip(yourString, maxLength);jika Anda ingin membaginya menjadi panjang maksimum tertentu. Ini akan membuat string ujung alat yang diformat dengan baik.

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

0

Jika Anda hanya menambahkan <html>teks tooltip Anda, itu akan tampak berfungsi sampai Anda memiliki /*...*/atau HTML di teks Anda. Gunakan <html><pre>atau tinggalkan teks Anda. Saya juga harus menggunakannya <font size=3>agar terlihat lumayan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.