Jordan
Jordan

Reputation: 744

JScrollPanes inside GridBagLayout gets resized randomly

Here is a tough one for you guys :)

Basically I have a GridBagLayout with 2 columns : a list wrapped in a scrollpane in each one. The scrollpanes are stretched in BOTH direction.

If I progressively reduce the height of this panel (by dragging the window's edge), I see "random" resizing happening on the scrollpanes:

If i don't wrap my components, don't get this behavior.


And if you replace the right hand list with a tree, it will behaves differently: shrinking the window's height bellow 380-ich px, the tree gets resized...

If i don't wrap my components, the tree gets resized anyway if you keep resizing the window !

Do you guys have any idea what's going on ???

PS: the actual layout i am trying to build is more complex than this example. In the mean time i use SpringLayout to do what i want but it requires to much (not so beautiful) things to setup

protected static ListModel newListModel(int n) {
    DefaultListModel lm = new DefaultListModel();

    for (int i = 0; i < n; ++i)
        lm.addElement("AAA");

    return lm;
}

protected static JComponent createContentPane() {
    JPanel  pane = new JPanel(new GridBagLayout());

    GridBagConstraints  gbc = new GridBagConstraints();

    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.gridy = 0;
    gbc.gridx = 0;

    pane.add(new JScrollPane(new JList(newListModel(12))), gbc);

    ++gbc.gridx;

    pane.add(new JScrollPane(new JList(newListModel(4))), gbc);

    return pane;
}

public static void main(String[] args) {
    JFrame f = new JFrame();

    f.getContentPane().add(createContentPane());
    f.setSize(800, 400);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    f.setVisible(true);
}

Upvotes: 3

Views: 3944

Answers (2)

Goblin Alchemist
Goblin Alchemist

Reputation: 827

I have an application with several ScrollPanes in a GridBagLayout, and they also exhibit sudden resizes when I resize the window. It seems that a jump occurs when the actual size of the ScrollPane steps over its "preferred size". I have found a workaround: set the preferred size to 1x1 pixels. If the component has positive weight and stretches BOTH, it will still occupy the whole cell, but will not jump. If you need several cells to resize in different proportions, you can set preferred size of another one to, say, 2x1 pixels.

Upvotes: 9

mKorbel
mKorbel

Reputation: 109815

  • this is basic principles of GridBagLayout, you forgot for define anchor, then you can be able to fix placed JComponent to the rellative Point, and I think that GridBagLayout complicated your GUI, this LayoutManager is better use for placing lots of JComponents to the one container,(without using nested layout)

for example

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class BorderPanels extends JFrame {

    private static final long serialVersionUID = 1L;

    public BorderPanels() {
        setLayout(new GridBagLayout());// set LayoutManager
        GridBagConstraints gbc = new GridBagConstraints();
        JPanel panel1 = new JPanel();
        Border eBorder = BorderFactory.createEtchedBorder();

        panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
        gbc.gridx = gbc.gridy = 0;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.weightx = gbc.weighty = 20;
        add(panel1, gbc); // add compoenet to the COntentPane

        JPanel panel2 = new JPanel();
        panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "60pct"));
        gbc.gridy = 1;
        gbc.weightx = gbc.weighty = 60;
        //gbc.insets = new Insets(2, 2, 2, 2);
        add(panel2, gbc); // add component to the COntentPane

        JPanel panel3 = new JPanel();
        panel3.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
        gbc.gridy = 2;
        gbc.weightx = gbc.weighty = 20;
        gbc.insets = new Insets(2, 2, 2, 2);
        add(panel3, gbc);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // important
        pack();
        setVisible(true); // important
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() { // important

            public void run() {
                BorderPanels borderPanels = new BorderPanels();
            }
        });
    }
}

to avoiding against to complicating simple things

Upvotes: 2

Related Questions