JLabels для переноса текста без предпочтительного / максимального / минимального размера

#java #swing #text #jlabel #word-wrap

#java #swing #текст #jlabel #перенос слов

Вопрос:

Я использую JLabels в качестве гиперссылок. Я хочу, чтобы они выглядели и функционировали точно так же, как ссылка в браузере, поэтому использование текстовых панелей / панелей редактора и т.д. нежелательно. Проблема в том, что многие контейнеры, в которые будут помещены эти ссылки, не имеют указанного размера: они зависят от размера своих родителей (или даже прародителей).

Я использую поля для макетов, и если текст ссылки занимает более двух третей ширины поля, содержимое поля начинает выходить за фактические границы поля (так что, если бы это поле было окружено JScrollPane, появилась бы горизонтальная полоса прокрутки).

Есть ли какой-либо способ принудительно перенести JLabel? Во многих прочитанных мной сообщениях говорится, что помещение текста в HTML-теги приведет к его автоматическому переносу при необходимости — но независимо от того, что я делаю, я не могу заставить это работать. Я не могу использовать <br /> теги, потому что я не знаю точно, куда они пойдут, если это не может быть автоматизировано, т. Е.:

 if(text.length() > wrapLength)
{
    //break the text into substrings and insert a <br /> at wrapLength
    //the difficulty is in figuring out the value of wrapLength
}
  

Вот код для класса hyperlink:

 import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JLabel;

public class Hyperlink extends JLabel
{
    private URI uri;
    private String baseText;

    public Hyperlink(String text, String uri, Font font, Color textColor)
    {
        super(text);
        baseText = text;
        setFont(font);
        setForeground(textColor);
        setOpaque(false);

        if(Desktop.isDesktopSupported())
        {
            try
            {
                setToolTipText(uri);
                this.uri = new URI(uri);
                addMouseListener(new LinkMouseListener());
            }
            catch(URISyntaxException ex)
            {
            }
        }
    }

    private class LinkMouseListener extends MouseAdapter
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            Desktop desktop = Desktop.getDesktop();
            try
            {
                desktop.browse(uri);
            }
            catch(IOException ioe)
            {
                System.out.println("Something went wrong..."); //DELETE
            }
        }

        @Override
        public void mouseEntered(MouseEvent e)
        {
            setText("<html><u>"   baseText   "</u></html>");
        }

        @Override
        public void mouseExited(MouseEvent e)
        {
            setText(baseText);
        }
    }
}
  

Ответ №1:

На ярлыке попробуйте setPreferredSize(new Dimension(width, height)) , setSize(new Dimension(width, height)) или setMaximumSize(new Dimension(width, height)) и установите ширину на ту ширину, на которую вы хотите его перенести. Я думаю, в вашем случае это будет setMaximumSize (…).

Это не переносится автоматически из-за вашего менеджера компоновки. Некоторые менеджеры компоновки будут игнорировать предпочтительный размер или другие измерения. В вашем случае вам, вероятно, просто нужно поиграть с различными методами setXXXSize () и найти тот, который соблюдается вашим менеджером макета.

Чтобы получить предпочтительную ширину, вам нужно будет получить ширину от одного из родителей. Еще раз, в зависимости от диспетчера компоновки, вам может потребоваться получить предпочтительную ширину, максимальную ширину или getSize().getWidth() . Не зная больше о макете, трудно сказать, как именно вам нужно это сделать, но вам нужно установить некоторую ширину метки для ее переноса — с этим ничего не поделаешь.

Единственным другим вариантом, который я могу придумать, было бы установить предпочтительную ширину метки на что-то произвольное, что, как вы знаете, всегда должно умещаться в доступном пространстве.

Ответ №2:

Используйте JTextArea. Текст можно настроить на перенос автоматически. Вы можете поиграть со свойствами текстовой области, чтобы она выглядела как метка.

Вы можете использовать пользовательский маркер, чтобы «подчеркнуть» текст. Затем вы просто добавляете / удаляете маркер по мере необходимости. Rectangle Painter поможет вам начать.