4

I need a label that will line wrap the containing text according to the available size. Since a JTextArea can line wrap, I used that and styled it accordingly so it resembles a JLabel.

The problem is that the JTextArea only increases it's width, but never shrinks it again. So I have an initial window size with some wrapped text, then I resize the window to be wider and the text will adjust accordingly, but making the window smaller again won't make the JTextArea smaller, instead a scrollbar appears.

This only happens when both:

  • The JTextArea is on a JPanel that itself is in a JScrollPane
  • setLineWrap(true) is used on the JTextArea

Removing the JScrollPane will yield the expected behaviour, but I do need the whole thing to scroll since there are other elements on the JPanel that may require it.

How can I tell it to get smaller again when the window is made smaller?

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

/**
 * SSCCE to demonstrate the JTextArea behaviour
 */
public class WrapLabelTest {

    public static final void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                testGui();
            }
        });
    }

    private static final String TEST_TEXT = "Textfortestingandstufflongenough"
            + "foralinebreak";

    private static void testGui() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.weightx = 1;
        gbc.weighty = 1;
        panel.add(new WrapLabel(TEST_TEXT), gbc);
//        
//        gbc.gridy = 1;
//        panel.add(new WrapLabel(TEST_TEXT), gbc);

        frame.add(new JScrollPane(panel));

        frame.setSize(200, 100);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

}

class WrapLabel extends JTextArea {

    private static final JLabel LABEL = new JLabel();

    public WrapLabel() {
        setWrapStyleWord(true);
        setLineWrap(true);
        setBackground(LABEL.getBackground());
        setFont(LABEL.getFont());
        setBorder(LABEL.getBorder());
        setFocusable(false);
        setForeground(LABEL.getForeground());
        setOpaque(false);
    }

    public WrapLabel(String text) {
        this();
        setText(text);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension d = super.getPreferredSize();
        // Debug output
        System.out.println(d);
        return d;
    }

}
user2375667
  • 463
  • 3
  • 10
  • You can use a `JLabel`, wrapping the text in `` as demonstrated [here](http://stackoverflow.com/questions/14737810/jlabel-show-longer-text-as-multiple-lines/14738193#14738193) – MadProgrammer Aug 14 '15 at 06:58
  • maybe [doLayout help your with that, see how the getPreferredHeight returns an Insets from the View](http://stackoverflow.com/a/12867849/714968) – mKorbel Aug 14 '15 at 07:26
  • 2
    Don't use the extra panel. TRy to add it directly to JScrollPane. If you need more content in the panel just don't add JTextArea directly but with one more JScrollPane. – StanislavL Aug 14 '15 at 07:59
  • A `JLabel` with `` won't line wrap in this situation (on `JPanel` that is on a `JScrollPane`). And either way, it doesn't wrap within words if they are too long, which the `JTextArea` does. – user2375667 Aug 14 '15 at 16:33
  • I can't add it directly to the `JScrollPane`, I need the whole `JPanel` to be scrollable. If I wrap the `JTextArea` is one more `JScrollPane` it doesn't change the behaviour. – user2375667 Aug 14 '15 at 16:36

1 Answers1

1

JTextArea never shrinks when line wrap is enabled

I have a JTextArea in a JPanel with Gridlayout that has this problem. Mine was solved by simply setting the TextArea minimum size.

textArea.setMinimumSize(new Dimension(20,40));
bob
  • 35
  • 6