GridBagLayout weights error?

The layout of the components in the project I'm working on didn't look right, I suspect there is an error in Swing. Basically, it seems that what happens is that the proportion weightxand weightyare not observed when the cells have different lays out minimum sizes and / or preferred sizes. I created a sample program to demonstrate this, here is the source:

package com.ensoftcorp.product.simmerge.gui.swing.dialogs;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestClass {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new TestClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static final GridBagConstraints GBC_CELL = new GridBagConstraints();
    static final GridBagConstraints GBC_ROWEND = new GridBagConstraints();
    static final GridBagConstraints GBC_FILLROW = new GridBagConstraints();
    static {
        GBC_CELL.anchor = GridBagConstraints.NORTHWEST;
        GBC_CELL.weightx = 0.5;
        GBC_CELL.fill = GridBagConstraints.BOTH;

        GBC_ROWEND.gridwidth = GridBagConstraints.REMAINDER;

        GBC_FILLROW.gridwidth = GridBagConstraints.REMAINDER;
        GBC_FILLROW.weightx = 1.0;
        GBC_FILLROW.fill = GridBagConstraints.BOTH;
    }

    public TestClass() {
        JFrame frame = new JFrame();

        JPanel pnlContent = new JPanel(new GridBagLayout());
        pnlContent.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        /*
         * Layout "ruler" panel
         */
        JPanel pnlRuler = new JPanel(new GridBagLayout());

        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);
        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);

        pnlRuler.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "correct" panel
         */
        JPanel pnlGoodLayout = new JPanel(new GridBagLayout());

        pnlGoodLayout.add(new JButton("JButton1"),GBC_CELL);
        pnlGoodLayout.add(new JButton("JButton2"),GBC_CELL);

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlGoodLayout.add(new JButton("JButton3"),GBC_CELL);
        pnlGoodLayout.add(new JButton("JButton4"),GBC_CELL);

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "incorrect" panel
         */
        JPanel pnlBadLayout = new JPanel(new GridBagLayout());

        pnlBadLayout.add(new JButton("JButton1"),GBC_CELL);
        pnlBadLayout.add(new JButton("JButton2"),GBC_CELL);

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlBadLayout.add(new JButton("JButton number 3 is wide"),GBC_CELL);
        pnlBadLayout.add(new JButton("JButton4"),GBC_CELL);

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Add panels to main panel
         */
        pnlContent.add(pnlRuler,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlGoodLayout,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlBadLayout,GBC_FILLROW);

        /*
         * Configure frame
         */
        frame.getContentPane().add(pnlContent);
        frame.setTitle("GridBagLayout Weight Bug?");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,200);
        frame.setVisible(true);
}

    JComponent createRulerCell(Color border, Color background) {
        JPanel glue = new JPanel();
        glue.setBorder(BorderFactory.createLineBorder(border));
        glue.setBackground(background);

        return glue;
    }

}

The sample program consists of three groups: the first is the "line", showing a 50% mark. The second and third groups are panels using the GridBagLayout, where each cell has weightx0.5. The only difference between the groups is the length of the button text, but the second group does not evenly distribute the columns, even if it has enough space for this.

: - , ?

P.S. - jdk1.6.0_11, .

+3
5

GridBagConstraints.weightx JavaDoc:

, .

. , , , .

, , , . , .

:

, GBC_CELL.gridx GBC_CELL.gridy , , ,

GBC_CELL.ipadx=100;

0 (# 3). .

+4

GridBagLayout .

FormLayout - TableLayout.

- HTML, .

+4

GroupLayout. , GridBagLayout.

+2

():

, . , P , ^ ^ i, ^ ( ^ * P)/ (----). , 1 1 2 2, - 90 , 1 30 , 2 60 . .

+1

. preferredSize.width JButton preferredSize.width=0.

:

private JButton createButton(String text) {
    JButton button = new JButton(text);
    button.setPreferredSize(new Dimension(0, button.getPreferredSize().height));
    return button;
}

Here is your modified example (I noted the changes with a comment // <==============):

public class TestClass {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new TestClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static final GridBagConstraints GBC_CELL = new GridBagConstraints();
    static final GridBagConstraints GBC_ROWEND = new GridBagConstraints();
    static final GridBagConstraints GBC_FILLROW = new GridBagConstraints();
    static {
        GBC_CELL.anchor = GridBagConstraints.NORTHWEST;
        GBC_CELL.weightx = 0.5;
        GBC_CELL.fill = GridBagConstraints.BOTH;

        GBC_ROWEND.gridwidth = GridBagConstraints.REMAINDER;

        GBC_FILLROW.gridwidth = GridBagConstraints.REMAINDER;
        GBC_FILLROW.weightx = 1.0;
        GBC_FILLROW.fill = GridBagConstraints.BOTH;
    }

    public TestClass() {
        JFrame frame = new JFrame();

        JPanel pnlContent = new JPanel(new GridBagLayout());
        pnlContent.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        /*
         * Layout "ruler" panel
         */
        JPanel pnlRuler = new JPanel(new GridBagLayout());

        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);
        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);

        pnlRuler.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "correct" panel
         */
        JPanel pnlGoodLayout = new JPanel(new GridBagLayout());

        pnlGoodLayout.add(createButton("JButton1"),GBC_CELL); // <==============
        pnlGoodLayout.add(createButton("JButton2"),GBC_CELL); // <==============

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlGoodLayout.add(createButton("JButton3"),GBC_CELL); // <==============
        pnlGoodLayout.add(createButton("JButton4"),GBC_CELL); // <==============

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "incorrect" panel
         */
        JPanel pnlBadLayout = new JPanel(new GridBagLayout());

        pnlBadLayout.add(createButton("JButton1"),GBC_CELL); // <==============
        pnlBadLayout.add(createButton("JButton2"),GBC_CELL); // <==============

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlBadLayout.add(createButton("JButton number 3 is wide"),GBC_CELL); // <==============
        pnlBadLayout.add(createButton("JButton4"),GBC_CELL); // <==============

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Add panels to main panel
         */
        pnlContent.add(pnlRuler,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlGoodLayout,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlBadLayout,GBC_FILLROW);

        /*
         * Configure frame
         */
        frame.getContentPane().add(pnlContent);
        frame.setTitle("GridBagLayout Weight Bug?");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,200);
        frame.setVisible(true);
    }

    JComponent createRulerCell(Color border, Color background) {
        JPanel glue = new JPanel();
        glue.setBorder(BorderFactory.createLineBorder(border));
        glue.setBackground(background);

        return glue;
    }

    private JButton createButton(String text) {
        JButton button = new JButton(text);
        button.setPreferredSize(new Dimension(0, button.getPreferredSize().height));
        return button;
    }

}

And here is the result. See? Now the space is evenly distributed:

enter image description here

enter image description here

0
source

Source: https://habr.com/ru/post/1710728/


All Articles