Java GridBagLayout not working

前端 未结 2 1517
小蘑菇
小蘑菇 2021-02-08 05:12

I\'m trying to use GridBagLayout, but I don\'t get what I expect and I can\'t find the error in this code:

public class GridBagEx1 extends JPanel {
         


        
相关标签:
2条回答
  • 2021-02-08 05:55

    The problem is that nothing is persuading the second grid column (gridx=1) to have any width, because there is no component that needs to fit only in the second column. The second column thus has 0 width, so although Button1 does straddle the first two columns, it doesn't look that way because all of its width need is satisfied by the first column; and although Button5 and Button7 straddle the second and third columns, all of their width need is satisfied by the third column.

    To fix it you must persuade the buttons which should to be wider (1, 5, 7) to take up more space. Here I added padding to those buttons by setting c.ipadx = 35;. (I also removed the weightx = 1.0 constraint. For reasons I don't quite understand, it didn't work when that was left in.):

    screenshot

    Source:

    public void init() {
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        setLayout(gridbag);
    
        c.fill = c.BOTH;
    
        //c.weightx = 1.0;
        //c.weighty = 1.0;
    
        c.anchor = c.CENTER;
    
        c.insets.top = 5;
        c.insets.bottom = 5;
        c.insets.left = 5;
        c.insets.right = 5;
    
        c.gridx = 0;
        c.gridy = 0;
        c.gridheight = 1;
        c.gridwidth = 2;
        c.ipadx = 35;
        makebutton("Button1", gridbag, c);
    
        c.gridx = 2;
        c.gridy = 0;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.ipadx = 0;
        makebutton("Button2", gridbag, c);
    
        c.gridx = 3;
        c.gridy = 0;
        c.gridheight = 2;
        c.gridwidth = 2;
        c.ipadx = 0;
        makebutton("Button3", gridbag, c);
    
        c.gridx = 0;
        c.gridy = 1;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.ipadx = 0;
        makebutton("Button4", gridbag, c);
    
        c.gridx = 1;
        c.gridy = 1;
        c.gridheight = 1;
        c.gridwidth = 2;
        c.ipadx = 35;
        makebutton("Button5", gridbag, c);
    
        c.gridx = 0;
        c.gridy = 2;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.ipadx = 0;
        makebutton("Button6", gridbag, c);
    
        c.gridx = 1;
        c.gridy = 2;
        c.gridheight = 1;
        c.gridwidth = 2;
        c.ipadx = 35;
        makebutton("Button7", gridbag, c);
    
        c.gridx = 3;
        c.gridy = 2;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.ipadx = 0;
        makebutton("Button8", gridbag, c);
    
        c.gridx = 4;
        c.gridy = 2;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.ipadx = 0;
        makebutton("Button9", gridbag, c);
    }
    

    Edit: As pointed out in the comments, the above approach is not suitable because it prevents the layout being resized dynamically. To have the layout expand to fill the size of its container, the weightx and weighty constraints are needed, but then the second column does not get any width.

    Here is an attempt at an alternative solution. It's a dirty hack that inserts an invisible component at the bottom of the second column to force the column to have width:

        c.gridx = 1;
        c.gridy = 3;
        c.gridheight = 1;
        c.gridwidth = 1;
        c.insets.set(0, 0, 0, 0);
        c.weighty = 0;
        add(Box.createRigidArea(new Dimension(50, 0)), c);
    

    This copes fairly well when the window is resized because although the component is given a fixed initial size, GridBagLayout scales up it proportionally with the other components. It is still not perfect, though. Maybe there is a better solution but I can't find it.

    0 讨论(0)
  • 2021-02-08 05:55

    I managed to design the needed layout without any hack and supporting dynamic resizing by using JGoodies FormLayout:

    import java.awt.Component;
    
    import javax.swing.JButton;
    import javax.swing.JPanel;
    
    import com.jgoodies.forms.factories.FormFactory;
    import com.jgoodies.forms.layout.ColumnSpec;
    import com.jgoodies.forms.layout.FormLayout;
    import com.jgoodies.forms.layout.RowSpec;
    
    public class FormLayoutPanel extends JPanel
        {
        public FormLayoutPanel()
            {
            setAlignmentY( Component.BOTTOM_ALIGNMENT );
            setAlignmentX( Component.RIGHT_ALIGNMENT );
            setLayout( new FormLayout( new ColumnSpec[] {
                ColumnSpec.decode( "41px:grow" ),
                FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                ColumnSpec.decode( "25px:grow" ),
                FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                ColumnSpec.decode( "41px:grow" ),
                FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                ColumnSpec.decode( "41px:grow" ),
                FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
                ColumnSpec.decode( "41px:grow" ), },
                new RowSpec[] {
                    RowSpec.decode( "25px:grow" ),
                    FormFactory.LINE_GAP_ROWSPEC,
                    RowSpec.decode( "25px:grow" ),
                    FormFactory.LINE_GAP_ROWSPEC,
                    RowSpec.decode( "25px:grow" ), } ) );
    
            JButton button1 = new JButton( "1" );
            add( button1, "1, 1, 3, 1, fill, fill" );
            JButton button2 = new JButton( "2" );
            add( button2, "5, 1, fill, fill" );
            JButton button3 = new JButton( "3" );
            add( button3, "7, 1, 3, 3, fill, fill" );
            JButton button4 = new JButton( "4" );
            add( button4, "1, 3, fill, fill" );
            JButton button5 = new JButton( "5" );
            add( button5, "3, 3, 3, 1, fill, fill" );
            JButton button6 = new JButton( "6" );
            add( button6, "1, 5, fill, fill" );
            JButton button7 = new JButton( "7" );
            add( button7, "3, 5, 3, 1, fill, fill" );
            JButton button8 = new JButton( "8" );
            add( button8, "7, 5, fill, fill" );
            JButton button9 = new JButton( "9" );
            add( button9, "9, 5, fill, fill" );
            }
        }
    
    0 讨论(0)
提交回复
热议问题