Is there a "word wrap" property for JLabel?
Asked Answered
S

7

55

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?

Survivor answered 22/10, 2011 at 18:30 Comment(6)
Just FYI, Andrew's answer is the best.Mendelson
@HovercraftFullOfEels <VBG>I just knew the screen shots would make the difference!</VBG>Muddy
Yeah, I've got to start doing that a bit more, but still it helps to have the right answer. I suppose I should learn a bit of HTML and styles...Mendelson
@AndrewThompson They're pretty cool, but make you answer slower! :)Beaton
@HovercraftFullOfEels +1 for the 2nd sentence, and not just you, but any server side developer using any language. It astounds me how little that (e.g.) servlet developers understand about the HTML their apps. are spewing out. As to the first.. some might consider my incessant addition of images to be visual 'noise'.Muddy
@Beaton True, so I use a trick. Post the source 1st, then add the images in an edit. Of course, that didn't help here, since it took me longer to write the (v. short) source than it took for 2 answers and a tick. ;)Muddy
B
35

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

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

Beaton answered 22/10, 2011 at 18:35 Comment(9)
I am already wraping the text in HTML e.g <html>some text <br/> <b>some text<b> </html> Do i need to use some specific HTML Tag for wrapingSurvivor
try calling setMaximumSize on that JLabelBeaton
"<html>some text <br/>" Web developers are turning over in their graves. Use styles.Muddy
@AndrewThompson yeah, what about JS. Or Flash! :)Beaton
There's a lot of that going around these days! :)Mendelson
I say, add support for Java applets into Swing components' html text. that would be fun!Beaton
"I say, add support for Java applets into Swing components' html text." See Appleteer - it uses a JEditorPane. "that would be fun!" No, it's not. Trust me. ;)Muddy
@Jame: FYI, Netbeans has nothing to do with your question - it is just the IDE. Java is the main subject of your question...Oglethorpe
I just imagined Flash running inside a JLabel and it made me almost ROFL.Beaton
M
99

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

Muddy answered 22/10, 2011 at 18:49 Comment(6)
Yeah, this one's the winner. :)Mendelson
+1 and if you need to have a variable width label you can use use "100%" instead of "200px" (assuming your GUI uses an appropriate layout manager).Sol
@SteveCohen If this were HTML for a browser, yes. This is merely HTML for Swing components and we can make many shortcuts. One advantage of this is that it allows us to (easily) dynamically add new content to the HTML. E.G. label.setText( label.getText() + "<li>New list bullet" );Muddy
Just noticed that JLabel with <html> in them look differently on Vista and 7 with native L&F: trello-attachments.s3.amazonaws.com/51b5f6a477d99db360005655/…Dissuasive
Remember that certain characters need to be escaped or turned into their HTML equivalents.Cankerworm
@ChrisDennett Yes you're right, something to be aware of and look out for.Muddy
B
35

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

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

Beaton answered 22/10, 2011 at 18:35 Comment(9)
I am already wraping the text in HTML e.g <html>some text <br/> <b>some text<b> </html> Do i need to use some specific HTML Tag for wrapingSurvivor
try calling setMaximumSize on that JLabelBeaton
"<html>some text <br/>" Web developers are turning over in their graves. Use styles.Muddy
@AndrewThompson yeah, what about JS. Or Flash! :)Beaton
There's a lot of that going around these days! :)Mendelson
I say, add support for Java applets into Swing components' html text. that would be fun!Beaton
"I say, add support for Java applets into Swing components' html text." See Appleteer - it uses a JEditorPane. "that would be fun!" No, it's not. Trust me. ;)Muddy
@Jame: FYI, Netbeans has nothing to do with your question - it is just the IDE. Java is the main subject of your question...Oglethorpe
I just imagined Flash running inside a JLabel and it made me almost ROFL.Beaton
M
12

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.

Mendelson answered 22/10, 2011 at 18:36 Comment(3)
"add the HTML hard-breaks" Web developers are turning over in their graves. Use styles.Muddy
I'm obviously not a web developer. Thanks for the heads up, and for all the restless dead web developers -- sorry and RIP.Mendelson
This is the current implementation and it doesn't work once the formatted string is greater than the dimensions of the label.Stypsis
D
9

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);
            }

        });
    }

}
Davy answered 14/3, 2012 at 15:39 Comment(0)
D
0

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.

Dorren answered 19/7, 2014 at 14:14 Comment(2)
Try to stay on topic.Respirable
I believe I stayed on topic. I pointed out 2 problems of using JTextArea (number of lines changing during resize and setting colour in Nimbus), and gave work-arounds for both.Dorren
C
0

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

Cailly answered 20/3, 2021 at 13:13 Comment(0)
S
-2

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!

Symptomatic answered 4/7, 2012 at 14:20 Comment(1)
Sorry Nabin, this is so long ago I can't really remember anything regarding it.Symptomatic

© 2022 - 2024 — McMap. All rights reserved.