Багаторядкові підказки на Java?


105

Я намагаюся відобразити підказки на Java, які можуть бути або не бути абзацами. Як я можу перегорнути слова довгими підказками?


Наведіть приклад коду.
Стефан Тіберг

1
Не підкажіть автоматичні підказки, якщо вони загорнуті в теги HTML? Я не впевнений, тому не ставлю це як відповідь.
Пол Томблін

Пол: Тільки якщо у вас є явні перерви у рядках.
Аманда S

Відповіді:


146

Якщо ви укладаєте підказку в <html>і </html>тегах, ви можете розбити рядки з <br>тегами. Див. Http://www.jguru.com/faq/view.jsp?EID=10653 для прикладів та обговорень.

Або ви можете використовувати клас JMultiLineToolTip, який можна знайти в багатьох місцях в мережі, включаючи https://github.com/ls-cwi/yoshiko-app/blob/master/src/main/java/com/yoshiko/internal/ view / JMultiLineToolTip.java


1
Я використовував запропонований вами клас JMultiLineToolTip. Коли я використав setFixedWidth (), щоб обмежити підказку до розумного розміру, він спрацював чудово. Дякую!
Amanda S

24

Текст підказки, який починається з " <html>", розглядатиметься як HTML. Звичайно, це може бути дуже широкий HTML.

Ви можете замінити JComponent.createTooltip, щоб замінити підказку своїм власним компонентом, який може відображати вподобаний вам whatevee.


20

Я знаю, що це досить старе, але я знайшов досить просте рішення за допомогою HTML-коду!

Просто використовуйте абзац HTML з фіксованою шириною:

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

Що робити, якщо я хочу відобразити текст, який значно коротший за розмір підказки? Тут не працює тег "max-width"
nickolay.laptev

5

Використовуйте підказки HTML і вручну розбивайте рядки (це повинен зробити простий токенізатор слова з фіксованою довжиною). Просто переконайтеся, що текст на вашій панелі інструментів починається з "<HTML>". Перерив ліній на "<BR/>" або "<P>". Я усвідомлюю, що це не найчистіше рішення, і підтримка HTML Java - жахлива, але це повинно зробити все.


4

Приклад:

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

Це не відповідає на запитання запитувача. Він запитував про обгортку, коли вона відображається, а не у вихідному коді.
Sled

2
@ArtB цей приклад код дає дворядковий підказки, як запитували.
Телема

4

Це можна було дещо вдосконалити, але мій підхід був допоміжною функцією, яка називалася перед встановленням підказки, яка розділяла текст підказки на задану довжину, але коригувалась для розбиття слів на пробіл, де це можливо.

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

2

Ви можете підкласифікувати JToolTip, який є Компонент, і переосмислити createToolTip () на компоненті.


1

Ось версія, яку я використовував раніше, вона добре працює, якщо ви завантажуєте поради щодо інструментів з 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);
    }

}

І ви б використали його, зателефонувавши до цього методу, перш ніж буде створений інтерфейс користувача:

MultiLineToolTipUI.installUI();

Потім у свої файли властивостей просто вставляйте нові рядки, щоб обернути підказки інструментів за бажанням.


1

Я створив клас утиліти, який автоматично форматує рядки на певну довжину <br> тегами. Він заснований на класі MultiLineToolTips, опублікованому Полом Тейлором, але в нього є помилка, яка пропускає частини рядка і насправді не обмежує рядок певною довжиною.

Щоб використовувати мій клас, просто попросіть метод splitToolTip, написавши MultiLineToolTips.splitToolTip(yourString);або MultiLineToolTips.splitToolTip(yourString, maxLength);якщо ви хочете розділити його на певну максимальну довжину. Це створить добре відформатовані рядки наконечників інструменту.

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

Якщо ви просто додасте <html>текст підказки, він буде працювати, поки у вас не /*...*/буде тексту або HTML. Використовуйте <html><pre>або уникайте текст. Мені також довелося скористатися, <font size=3>щоб виглядати дещо пристойно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.