Search code examples
javaswingjscrollpanegridbaglayout

Line wrapped JTextArea using too much space with GridBagLayout


I've been trying to get a scrollable JTextArea to appear to the right of a JList where the JTextArea takes up most of the space but leaves a good portion for the JList (3/4 of the frame for the JTextArea, 1/4 for the JList). The problem is that the weights of the constraints seem to be ignored when LineWrap on the JTextArea is set to true.

Without line wrap, the JTextArea takes up about 3/4 of the frame and the JList takes up the other 1/4, which is what I want. But when line wrapping is turned on, the JTextArea attempts to take up as much space as possible and crushes the JList down to the width of the strings it contains. The interesting thing is that this only appears to happen once you resize the window (looks fine initially), and if you type anything into the JTextArea, it slowly expands, pushing the JList back. This has been confusing me to say the least.

I made a screenshot of what it looks like without line wrapping and with line wrapping after resizing the window: Example

Here's some example code showing you what I mean. Remove the line wrap statements and it'll look fine, but keep them there and you'll see that upon resizing, the JList is squished.

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.*

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());

        JTextArea area = new JTextArea();
        DefaultListModel<String> model = new DefaultListModel<>();
        JList<String> list = new JList<String>(model);
        JScrollPane scroll = new JScrollPane(area,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        for (int i = 0; i < 5; i++)
            model.addElement("Example" + i);

        area.setLineWrap(true);
        area.setWrapStyleWord(true);

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
        c.weightx = 0.3;
        panel.add(scroll, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
        c.weightx = 0.1;
        panel.add(list, c);

        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 300);
        frame.setVisible(true);

    }
}

Solution

  • You can use ipadx to define minimal possible width

        c.weightx = 0.1;
        c.ipadx=desiredPixelsWidthForTheList;
        panel.add(list, c);
    

    UPDATE

    Also you can place both in a JSplitPane and define desired proportions.