Is there a "word wrap" property for JLabel?

JavaSwingJlabel

Java Problem Overview


I am displaying some text in a JLabel. Basically I am generating that text dynamically, and then I apply some HTML tags (e.g., BR and B) to format the text. Finally I assign this formatted text to my JLabel.

Now I want my Jlabel to automatically wrap the text to the next line when it reaches the end of screen, like the "Word Wrap" feature in Note Pad.

How can I do that?

Java Solutions


Solution 1 - Java

A width can be set for the body using HTML styles (CSS). This in turn will determine the number of lines to render and, from that, the preferred height of the label.

Setting the width in CSS avoids the need to compute where line breaks should occur in (or the best size of) the label.

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

Solution 2 - Java

Should work if you wrap the text in <html>...</html>

UPDATE: You should probably set maximum size, too, then.

Solution 3 - Java

One way would be to use a JTextArea instead of a JLabel with setWrapStyleWord and setLineWrap set to true and with settings to make it look and behave like a JLabel (remove the border, make it non-opaque, make it non-editable and non-focusable).

Otherwise if you absolutely need to use a JLabel, you'd be forced to use FontMetrics to measure your text, check for white-space, and then add the HTML hard-breaks in the appropriate positions yourself.

Solution 4 - Java

I found that this solution is the simplest and works correctly with resizing as well. Other than wrapping the text in <html> tags, you also have to put the label into a container that respects the preferred height and sets the width to maximum. For example, you can put the label in to the NORTH of a BorderLayout.

Here is a simple but complete working program to illustrate this. You can resize the frame in any way you want; the label will occupy the whole width and the height will adjust accordingly to wrap the text. Notice that all that I'm doing is using <html> tags and putting the label in the NORTH of the 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);
			}
			
		});
	}

}

Solution 5 - Java

I like the JTextArea approach mentioned above, because it resizes nicely at SOUTH in a BorderLayout panel (as long as the CENTER component can take up the slack if the number of lines in the JTextArea changes).

However, in Nimbus L&F there is a catch in setting the JTextArea's background colour. It seems that Nimbus uses magic colours (extended class of java.awt.Color) that go transparent in JTextArea. So if you are copying the background colour from a JPanel to the JText area you need to convert the Color to ARGB and back to Color. The following code works for me in all the L&Fs in my 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());

I made the font a bit smaller. Of course you can keep JLabel's font size if you want.

Solution 6 - Java

Mix plain text and HTML will switch off auto words wrap in 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

So you can not mix different types (HTML and plain text) of text in one JLabel

Solution 7 - Java

Just thought I should post this for anyone searching the internet, as it was the tiny little mistake that cost me 30 minutes, but make sure you've actually wrapped the text in HTML. You may have thought you did and yet didn't. Check it, I forgot, and when I wrapped them in HTML it fixed it for me.

JLabel label = new JLabel("Lorem ipsum long paragraph"); wrong.

JLabel label = new JLabel("<html>Lorem ipsum long paragraph</html>"); correct!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJameView Question on Stackoverflow
Solution 1 - JavaAndrew ThompsonView Answer on Stackoverflow
Solution 2 - JavaMarianPView Answer on Stackoverflow
Solution 3 - JavaHovercraft Full Of EelsView Answer on Stackoverflow
Solution 4 - JavaAndrei Vajna IIView Answer on Stackoverflow
Solution 5 - JavaAdam Gawne-CainView Answer on Stackoverflow
Solution 6 - JavaDmitrii ErmolaevView Answer on Stackoverflow
Solution 7 - JavaAdam K DeanView Answer on Stackoverflow