JScrollPanes inside GridBagLayout gets randomly resized

Here's the rude guys :)

Basically I have a GridBagLayout with two columns: a list enclosed by a scrollpane in each one. The scroll bars are stretched in the BOTH direction .

If I gradually decrease the height of this panel (by dragging the edge of the window), I see a "random" resizing on the scrolls:

  • the second width decreases when the first Hscroll panel appears

  • then the second width shrinks again for no reason ...

If I am not porting my components, don't get this behavior.

And if you replace the right-hand list with a tree , it behaves differently: by decreasing the window height 380-ich px, the tree changes ...

If I don't migrate my components, the tree will still be resized if you resize the window!

Do you guys know what's going on?

PS: The actual layout I'm trying to build is more complex than this example. At the same time, I use SpringLayout to do what I want, but it takes a lot (not so pretty) things to set up

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

    for (int i = 0; i < n; ++i)

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


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

    return pane;

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

    f.setSize(800, 400);



source to share

2 answers

I have an application with multiple ScrollPanes in a GridBagLayout and they also exhibit abrupt resizing when the window is resized. The jump appears to occur when the ScrollPane's actual size goes over its "preferred size". I found a workaround: set your preferred size to 1x1 pixel. If a component has a positive weight and is stretched BOTH, it will still fill the entire cell, but it will not jump. If you need multiple cells to resize in different proportions, you can set the preferred size to another, for example 2x1 pixels.



  • This is the basic principles of GridBagLayout , you forgot to define anchor

    , then you can fix the placed JComponent

    in the rellative Poin

    t and I think that GridBagLayout

    complicated your GUI, this LayoutManager is better to use to place a lot of JComponents

    for one container (no use nested layout



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
        setVisible(true); // important

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

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


to avoid the complications of simple things

  • use a GridLayout (all JComponents

    have the same Dimmension

    on screen)

  • use BoxLayout or BorderLayout



All Articles