Есть ли свойство "перенос слов" для JLabel? - PullRequest
45 голосов
/ 22 октября 2011

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

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

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

Ответы [ 6 ]

90 голосов
/ 22 октября 2011

Ширина может быть установлена ​​для 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 here enter image description here

27 голосов
/ 22 октября 2011

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

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

11 голосов
/ 22 октября 2011

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

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

7 голосов
/ 14 марта 2012

Я обнаружил, что это решение самое простое и правильно работает с изменением размера.Помимо переноса текста в теги <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);
            }

        });
    }

}
.
0 голосов
/ 19 июля 2014

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

Однако в Nimbus L & F есть ловушка при настройке цвета фона JTextArea. Похоже, что Nimbus использует магические цвета (расширенный класс java.awt.Color), которые становятся прозрачными в JTextArea. Поэтому, если вы копируете цвет фона из JPanel в область JText, вам необходимо преобразовать цвет в ARGB и обратно в цвет. Следующий код работает для меня во всех L & F в моем 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, если хотите.

0 голосов
/ 04 июля 2012

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

JLabel label = new JLabel("Lorem ipsum long paragraph"); неправильно.

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

...