Есть ли свойство "word wrap" для JLabel?

Я показываю некоторый текст в JLabel. В основном я генерирую этот текст динамически, а затем я применяю некоторые HTML-теги (например, BR и B) для форматирования текста. Наконец, я присваиваю этот форматированный текст моей JLabel.

Теперь я хочу, чтобы моя Jlabel автоматически обертывала текст на следующую строку, когда она достигла конца экрана, например, функция "Word Wrap" в Note Pad.

Как я могу это сделать?

Ответ 1

Должен работать, если вы завернете текст в <html>...</html>

UPDATE: Возможно, вы также должны установить максимальный размер.

Ответ 2

Ширина может быть установлена для body с использованием стилей HTML (CSS). Это, в свою очередь, будет определять количество отображаемых линий и, исходя из этого, предпочтительную высоту метки.

Установка ширины в CSS избавляет от необходимости вычислять, где должны произойти разрывы строк (или лучший размер) надписи.

import javax.swing.*;

public class FixedWidthLabel {

    public static void main(String[] srgs) {
        final String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu nulla urna. Donec sit amet risus nisl, a porta enim. Quisque luctus, ligula eu scelerisque gravida, tellus quam vestibulum urna, ut aliquet sapien purus sed erat. Pellentesque consequat vehicula magna, eu aliquam magna interdum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sollicitudin sapien non leo tempus lobortis. Morbi semper auctor ipsum, a semper quam elementum a. Aliquam eget sem metus.";
        final String html = "<html><body style='width: %1spx'>%1s";

        Runnable r = () -> {
            JOptionPane.showMessageDialog(
                    null, String.format(html, 200, s));
            JOptionPane.showMessageDialog(
                    null, String.format(html, 300, s));
        };
        SwingUtilities.invokeLater(r);
    }
}

enter image description hereenter image description here

Ответ 3

Одним из способов было бы использовать JTextArea вместо JLabel с setWrapStyleWord и setLineWrap установленными в true, и с настройками, чтобы он выглядел и вел себя как JLabel (удалите границу, сделайте ее непрозрачной, сделайте ее не редактируемой и не редактируемой). фокусируемый).

В противном случае, если вам абсолютно необходимо использовать JLabel, вы будете вынуждены использовать FontMetrics для измерения текста, проверки пробелов, а затем самостоятельно добавлять жесткие переходы HTML в соответствующие позиции.

Ответ 4

Я обнаружил, что это решение является самым простым и корректно работает с изменением размера. Помимо обертывания текста в тегах <html>, вы также должны поместить ярлык в контейнер, который соответствует предпочтительной высоте, и устанавливает максимальную ширину. Например, вы можете поместить ярлык в СЕВЕРНЫЙ из BorderLayout.

Вот простую, но полную рабочую программу, чтобы проиллюстрировать это. Вы можете изменить размер кадра любым способом; метка будет занимать всю ширину, а высота будет корректироваться, чтобы обернуть текст. Обратите внимание, что все, что я делаю, использует теги <html> и помещает метку в СЕВЕРУ BorderLayout.

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Dimension;

public class LabelWrap {

    public static JPanel createPanel() {
        JLabel label = new JLabel();
        label.setText("<html>"
            + "<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>"
            + "<p>Duis a tincidunt urna. Phasellus tristique interdum mauris, "
            + "ut vestibulum purus suscipit eget. Aenean massa elit, accumsan "
            + "non faucibus vel, dictum placerat urna. In bibendum est sagittis "
            + "urna iaculis quis sagittis velit commodo. Cum sociis natoque "
            + "penatibus et magnis dis parturient montes, nascetur ridiculus "
            + "mus. Nam quis lacus mauris. Phasellus sem libero, convallis "
            + "mattis sagittis vel, auctor eget ipsum. Vivamus molestie semper "
            + "adipiscing. In ac neque quis elit suscipit pharetra. Nulla at "
            + "orci a tortor consequat consequat vitae sit amet elit. Praesent "
            + "commodo lacus a magna mattis vehicula. Curabitur a hendrerit "
            + "risus. Aliquam accumsan lorem quis orci lobortis malesuada.</p>"
            + "<p>Proin quis viverra ligula. Donec pulvinar, dui id facilisis "
            + "vulputate, purus justo laoreet augue, a feugiat sapien dolor ut "
            + "nisi. Sed semper augue ac felis ultrices a rutrum dui suscipit. "
            + "Praesent et mauris non tellus gravida mollis. In hac habitasse "
            + "platea dictumst. Vestibulum ante ipsum primis in faucibus orci "
            + "luctus et ultrices posuere cubilia Curae; Vestibulum mattis, "
            + "tortor sed scelerisque laoreet, tellus neque consectetur lacus, "
            + "eget ultrices arcu mi sit amet arcu. Nam gravida, nulla interdum "
            + "interdum gravida, elit velit malesuada arcu, nec aliquam lectus "
            + "velit ut turpis. Praesent pretium magna in nibh hendrerit et "
            + "elementum tellus viverra. Praesent eu ante diam. Proin risus "
            + "eros, dapibus at eleifend sit amet, blandit eget purus. "
            + "Pellentesque eu mollis orci. Sed venenatis diam a nisl tempor "
            + "congue.</p>"
            + "</html>");

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(label, BorderLayout.NORTH);
        panel.setPreferredSize(new Dimension(640, 480));
        return panel;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() { 
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(createPanel());
                frame.pack();
                frame.setVisible(true);
            }

        });
    }

}

Ответ 5

Просто подумал, что я должен опубликовать это для всех, кто ищет в Интернете, поскольку это была крошечная ошибка, которая стоила мне 30 минут, но убедитесь, что вы на самом деле обернули текст в HTML. Возможно, вы думали, что сделали, но не сделали этого. Проверьте это, я забыл, и когда я завернул их в HTML, он исправил это для меня.

JLabel label = new JLabel("Lorem ipsum long paragraph"); неверно.

JLabel label = new JLabel("<html>Lorem ipsum long paragraph</html>"); правильный!

Ответ 6

Мне нравится подход JTextArea, упомянутый выше, потому что он красиво изменяется на SOUTH на панели BorderLayout (пока компонент CENTER может занять слабину, если изменяется количество строк в JTextArea).

Однако в Nimbus L & F есть фиксация при настройке цвета фона JTextArea. Кажется, что Nimbus использует волшебные цвета (расширенный класс java.awt.Color), которые становятся прозрачными в JTextArea. Поэтому, если вы копируете цвет фона из JPanel в область JText, вам нужно преобразовать Color в ARGB и обратно в Color. Следующий код работает для меня во всех L & Fs в моей JRE (Nimbus, CDE Motif, Metal, Mac OS X):

    JTextArea ta = new JTextArea(text);
    ta.setEditable(false);
    ta.setLineWrap(true);
    ta.setWrapStyleWord(true);
    JLabel lb = new JLabel();
    Font f = lb.getFont();
    ta.setFont(f.deriveFont(f.getSize2D() * 0.9f));
    ta.setBorder(lb.getBorder());
    ta.setBackground(new Color(lb.getBackground().getRGB(), true));
    ta.setForeground(new Color(lb.getForeground().getRGB(), true));
    ta.setOpaque(lb.isOpaque());

Я сделал шрифт немного меньше. Конечно, вы можете сохранить размер шрифта JLabel, если хотите.