Home > Back-end >  GridBagLayout 25% 50% 25%
GridBagLayout 25% 50% 25%

Time:02-19

Is this the right way to prevent GridBagLayout cells from being resized relative to their contents?

gbl_panel.columnWidths = new int[] {1000, 4000, 1000};

enter image description here

SSCCE

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.AbstractListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

public class GridBagLayoutTemplate extends JFrame {

private JPanel contentPane;

public GridBagLayoutTemplate() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);


    JPanel panel = new JPanel();
    contentPane.add(panel);

    GridBagLayout gbl_panel = new GridBagLayout();
    gbl_panel.rowHeights = new int[] {1};
    gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
    gbl_panel.columnWeights = new double[]{1.0, 4.0, 1.0};
    gbl_panel.rowWeights = new double[]{1.0};
    panel.setLayout(gbl_panel);

    JScrollPane scrollPane = new JScrollPane();
    GridBagConstraints gbc_scrollPane = new GridBagConstraints();
    gbc_scrollPane.insets = new Insets(0, 0, 0, 5);
    gbc_scrollPane.fill = GridBagConstraints.BOTH;
    gbc_scrollPane.gridx = 0;
    gbc_scrollPane.gridy = 0;
    panel.add(scrollPane, gbc_scrollPane);

    JList list = new JList();
    scrollPane.setViewportView(list);
    list.setModel(new AbstractListModel() {
        String[] values = new String[] {"qwe"};
        public int getSize() {
            return values.length;
        }
        public Object getElementAt(int index) {
            return values[index];
        }
    });

    JScrollPane scrollPane_1 = new JScrollPane();
    GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
    gbc_scrollPane_1.insets = new Insets(0, 0, 0, 5);
    gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
    gbc_scrollPane_1.gridx = 1;
    gbc_scrollPane_1.gridy = 0;
    panel.add(scrollPane_1, gbc_scrollPane_1);

    JList list_1 = new JList();
    scrollPane_1.setViewportView(list_1);
    list_1.setModel(new AbstractListModel() {
        String[] values = new String[] {"qwe"};
        public int getSize() {
            return values.length;
        }
        public Object getElementAt(int index) {
            return values[index];
        }
    });

    JScrollPane scrollPane_2 = new JScrollPane();
    GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints();
    gbc_scrollPane_2.fill = GridBagConstraints.BOTH;
    gbc_scrollPane_2.gridx = 2;
    gbc_scrollPane_2.gridy = 0;
    panel.add(scrollPane_2, gbc_scrollPane_2);

    JList list_3 = new JList();
    scrollPane_2.setViewportView(list_3);
    list_3.setModel(new AbstractListModel() {
        String[] values = new String[] {"qweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqweqweqweqweqweqwqweqweqweqwe"};
        public int getSize() {
            return values.length;
        }
        public Object getElementAt(int index) {
            return values[index];
        }
    });
}
}

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GridBagLayoutTemplate frame = new GridBagLayoutTemplate();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

CodePudding user response:

Interesting. I've never seen an approach like this before.

Typically the GridBagLayout is used such that:

  1. Each component is allocated space based on its preferred size
  2. If extra space is available then space is allocated to to each component based on the weightx (weighty) values assigned to each component.

Therefore only the extra space is allocated in the 25% 50% 25% ratio.

Your approach seems to ignore the preferred size of components and allocate space in the 25% 50% 25% ratio.

However, you would first need to make the following change to get the proper ratio:

//gbl_panel.columnWidths = new int[] {1000, 4000, 1000};
//gbl_panel.columnWeights = new double[]{1.0, 4.0, 1.0};
gbl_panel.columnWidths = new int[] {1000, 2000, 1000};
gbl_panel.columnWeights = new double[]{1.0, 2.0, 1.0};

Below is the simplified code I used to test allocating space to components on a panel that is 400 pixels wide:

import java.awt.*;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class GridBagLayoutTemplate2 extends JFrame {

    public GridBagLayoutTemplate2()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel contentPane = new JPanel();
//      contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel panel = new JPanel();
        panel.setPreferredSize( new Dimension(400, 300) );
        contentPane.add(panel);

        GridBagLayout gbl_panel = new GridBagLayout();
        gbl_panel.columnWidths = new int[] {1000, 2000, 1000};
//      gbl_panel.columnWidths = new int[] {50, 100, 50}; // also works
        gbl_panel.columnWeights = new double[]{1.0, 2.0, 1.0};
//      gbl_panel.rowHeights = new int[] {1}; // doesn't appear to be needed.
        gbl_panel.rowWeights = new double[]{1.0};
        panel.setLayout(gbl_panel);

        GridBagConstraints gbc_scrollPane = new GridBagConstraints();
//      gbc_scrollPane.insets = new Insets(0, 0, 0, 5);
        gbc_scrollPane.fill = GridBagConstraints.BOTH;

        JPanel red = new JPanel();
        red.setBackground( Color.RED );
        red.setPreferredSize( new Dimension(30, 200) );
        gbc_scrollPane.gridx = 0;
        gbc_scrollPane.gridy = 0;
        panel.add(red, gbc_scrollPane);

        JPanel green = new JPanel();
        green.setBackground( Color.GREEN );
        green.setPreferredSize( new Dimension(40, 200) );
        gbc_scrollPane.gridx = 1;
        gbc_scrollPane.gridy = 0;
        panel.add(green, gbc_scrollPane);

        JPanel blue = new JPanel();
        blue.setBackground( Color.BLUE );
        blue.setPreferredSize( new Dimension(50, 200) );
        gbc_scrollPane.gridx = 2;
        gbc_scrollPane.gridy = 0;
        panel.add(blue, gbc_scrollPane);

        //setSize(400, 300);
        pack();
        setVisible(true);

        System.out.println( red.getSize());
        System.out.println( green.getSize());
        System.out.println( blue.getSize());
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GridBagLayoutTemplate2 frame = new GridBagLayoutTemplate2();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

And the results are:

java.awt.Dimension[width=100,height=300]
java.awt.Dimension[width=200,height=300]
java.awt.Dimension[width=100,height=300]

So I would say the approach works.

Note: In case you are interested, in the past I have suggested you can use the Relative Layout which was designed specifically for this type of layout and is easier to use.

  • Related