Есть ли свойство "перенос слов" для JLabel?
Я показываю некоторый текст в JLabel. В основном я генерирую этот текст динамически, а затем я применяю некоторые теги HTML (например, BR
а также B
) отформатировать текст. Наконец, я назначил этот форматированный текст моей JLabel.
Теперь я хочу, чтобы мой Jlabel автоматически переносил текст на следующую строку, когда он достигнет конца экрана, как функция "Перенос по словам" в Note Pad.
Как я могу это сделать?
7 ответов
Должно работать, если вы оберните текст в <html>...</html>
ОБНОВЛЕНИЕ: Вероятно, вам также следует установить максимальный размер.
Ширина может быть установлена для 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 html1 = "<html><body style='width: ";
final String html2 = "px'>";
Runnable r = new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(
null, new JLabel(html1 + "200" + html2 + s));
JOptionPane.showMessageDialog(
null, new JLabel(html1 + "300" + html2 + s));
}
};
SwingUtilities.invokeLater(r);
}
}
Одним из способов было бы использовать JTextArea
вместо JLabel
с setWrapStyleWord
а также setLineWrap
установить в true и с настройками, чтобы он выглядел и вел себя как JLabel
(удалите границу, сделайте ее непрозрачной, сделайте ее недоступной для редактирования и не фокусируемой).
В противном случае, если вам абсолютно необходимо использовать JLabel
вы будете вынуждены использовать FontMetrics для измерения текста, проверки пробелов, а затем самостоятельно добавлять жесткие переходы HTML в соответствующие позиции.
Я обнаружил, что это решение самое простое и правильно работает с изменением размера. Кроме переноса текста в <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);
}
});
}
}
Смешайте обычный текст, и HTML отключит автоматический перенос слов в HTML:
jLabel_01.setText("<html>Lorem ipsum long paragraph</html>"); // work good
...
jLabel_01.setText(""); // will switch off HTML words wrap!!!
...
jLabel_01.setText("<html>Lorem ipsum long paragraph</html>"); // will not work properly
Таким образом, вы не можете смешивать разные типы (HTML и простой текст) текста в одном JLabel.
Просто подумал, что я должен опубликовать это для всех, кто ищет в Интернете, потому что это была маленькая ошибка, которая стоила мне 30 минут, но убедитесь, что вы на самом деле завернули текст в HTML. Возможно, вы думали, что сделали, и все же не сделали. Проверьте это, я забыл, и когда я обернул их в HTML, это исправило это для меня.
JLabel label = new JLabel("Lorem ipsum long paragraph");
неправильно.
JLabel label = new JLabel("<html>Lorem ipsum long paragraph</html>");
правильный!
Мне нравится подход JTextArea, упомянутый выше, потому что он прекрасно изменяется в SOUTH на панели 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, если хотите.