Why does this GridBagLayout not appear as planned?

2019-01-12 10:43发布

问题:

I was trying to achieve the end result required in Setting an arbitrary width in GridBagLayout.

For easy reference, here it is:

This is the current result:

Button number and row is shown in the form 1,1, followed by the number of columns (2) declared for this cell.

As you can see, it starts with buttons 1,1 (3) and below it 1,2 (4) being the same width, while declaring different numbers of columns.

Can anyone determine how to correct the code?

The current code:

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

public class KeyBoardLayout {

    private JComponent ui = null;

    KeyBoardLayout() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new GridBagLayout());
        ui.setBorder(new EmptyBorder(4,4,4,4));

        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 3;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        ui.add(new JButton("1,1 (3)"), gbc);

        gbc.gridx = 3;
        gbc.gridwidth = 2;
        ui.add(new JButton("2,1 (2)"), gbc);

        gbc.gridx = 5;
        ui.add(new JButton("3,1 (2)"), gbc);

        gbc.gridx = 7;
        ui.add(new JButton("4,1 (2)"), gbc);

        gbc.gridx = 9;
        ui.add(new JButton("5,1 (2)"), gbc);

        gbc.gridx = 11;
        ui.add(new JButton("6,1 (2)"), gbc);

        gbc.gridx = 13;
        ui.add(new JButton("7,1 (2)"), gbc);

        gbc.gridx = 15;
        gbc.gridwidth = 3;
        ui.add(new JButton("8,1 (3)"), gbc);

        gbc.gridx = 18;
        gbc.gridwidth = 4;
        ui.add(new JButton("9,1 (4)"), gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        ui.add(new JButton("1,2 (4)"), gbc);

        gbc.gridx = 4;
        gbc.gridwidth = 2;
        ui.add(new JButton("2,2 (2)"), gbc);

        gbc.gridx = 6;
        ui.add(new JButton("3,2 (2)"), gbc);

        gbc.gridx = 8;
        ui.add(new JButton("4,2 (2)"), gbc);

        gbc.gridx = 10;
        ui.add(new JButton("5,2 (2)"), gbc);

        gbc.gridx = 12;
        ui.add(new JButton("6,2 (2)"), gbc);

        gbc.gridx = 14;
        ui.add(new JButton("7,2 (2)"), gbc);

        gbc.gridx = 16;
        ui.add(new JButton("8,2 (2)"), gbc);

        gbc.gridx = 18;
        gbc.gridwidth = 4;
        ui.add(new JButton("9,2 (4)"), gbc);

        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 5;
        ui.add(new JButton("1,3 (5)"), gbc);

        gbc.gridx = 5;
        gbc.gridwidth = 2;
        ui.add(new JButton("2,3 (2)"), gbc);

        gbc.gridx = 7;
        ui.add(new JButton("3,3 (2)"), gbc);

        gbc.gridx = 9;
        ui.add(new JButton("4,3 (2)"), gbc);

        gbc.gridx = 11;
        ui.add(new JButton("5,3 (2)"), gbc);

        gbc.gridx = 13;
        ui.add(new JButton("6,3 (2)"), gbc);

        gbc.gridx = 15;
        ui.add(new JButton("7,3 (2)"), gbc);

        gbc.gridx = 17;
        ui.add(new JButton("8,3 (2)"), gbc);

        gbc.gridx = 19;
        gbc.gridwidth = 3;
        ui.add(new JButton("9,3 (3)"), gbc);

        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 3;
        ui.add(new JButton("1,4 (3)"), gbc);

        gbc.gridx = 3;
        ui.add(new JButton("2,4 (3)"), gbc);

        gbc.gridx = 6;
        gbc.gridwidth = 10;
        ui.add(new JButton("3,4 (10)"), gbc);

        gbc.gridx = 16;
        gbc.gridwidth = 3;
        ui.add(new JButton("4,4 (3)"), gbc);

        gbc.gridx = 19;
        ui.add(new JButton("5,4 (3)"), gbc);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                KeyBoardLayout o = new KeyBoardLayout();

                JFrame f = new JFrame("Keyboard Layout");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

回答1:

Think I got it to work. I created a row with 22 components that each take up one column:

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

public class KeyBoardLayout {

    private JComponent ui = null;

    KeyBoardLayout() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new GridBagLayout());
        ui.setBorder(new EmptyBorder(4,4,4,4));

        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridx = 0;
//        gbc.gridy = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 3;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        ui.add(new JButton("1,1 (3)"), gbc);

        gbc.gridx = 3;
        gbc.gridwidth = 2;
        ui.add(new JButton("2,1 (2)"), gbc);

        gbc.gridx = 5;
        ui.add(new JButton("3,1 (2)"), gbc);

        gbc.gridx = 7;
        ui.add(new JButton("4,1 (2)"), gbc);

        gbc.gridx = 9;
        ui.add(new JButton("5,1 (2)"), gbc);

        gbc.gridx = 11;
        ui.add(new JButton("6,1 (2)"), gbc);

        gbc.gridx = 13;
        ui.add(new JButton("7,1 (2)"), gbc);

        gbc.gridx = 15;
        gbc.gridwidth = 3;
        ui.add(new JButton("8,1 (3)"), gbc);

        gbc.gridx = 18;
        gbc.gridwidth = 4;
        ui.add(new JButton("9,1 (4)"), gbc);

        gbc.gridx = 0;
//        gbc.gridy = 1;
        gbc.gridy = 2;
        ui.add(new JButton("1,2 (4)"), gbc);

        gbc.gridx = 4;
        gbc.gridwidth = 2;
        ui.add(new JButton("2,2 (2)"), gbc);

        gbc.gridx = 6;
        ui.add(new JButton("3,2 (2)"), gbc);

        gbc.gridx = 8;
        ui.add(new JButton("4,2 (2)"), gbc);

        gbc.gridx = 10;
        ui.add(new JButton("5,2 (2)"), gbc);

        gbc.gridx = 12;
        ui.add(new JButton("6,2 (2)"), gbc);

        gbc.gridx = 14;
        ui.add(new JButton("7,2 (2)"), gbc);

        gbc.gridx = 16;
        ui.add(new JButton("8,2 (2)"), gbc);

        gbc.gridx = 18;
        gbc.gridwidth = 4;
        ui.add(new JButton("9,2 (4)"), gbc);

        gbc.gridx = 0;
//        gbc.gridy = 2;
        gbc.gridy = 3;
        gbc.gridwidth = 5;
        ui.add(new JButton("1,3 (5)"), gbc);

        gbc.gridx = 5;
        gbc.gridwidth = 2;
        ui.add(new JButton("2,3 (2)"), gbc);

        gbc.gridx = 7;
        ui.add(new JButton("3,3 (2)"), gbc);

        gbc.gridx = 9;
        ui.add(new JButton("4,3 (2)"), gbc);

        gbc.gridx = 11;
        ui.add(new JButton("5,3 (2)"), gbc);

        gbc.gridx = 13;
        ui.add(new JButton("6,3 (2)"), gbc);

        gbc.gridx = 15;
        ui.add(new JButton("7,3 (2)"), gbc);

        gbc.gridx = 17;
        ui.add(new JButton("8,3 (2)"), gbc);

        gbc.gridx = 19;
        gbc.gridwidth = 3;
        ui.add(new JButton("9,3 (3)"), gbc);

        gbc.gridx = 0;
//        gbc.gridy = 3;
        gbc.gridy = 4;
        gbc.gridwidth = 3;
        ui.add(new JButton("1,4 (3)"), gbc);

        gbc.gridx = 3;
        ui.add(new JButton("2,4 (3)"), gbc);

        gbc.gridx = 6;
        gbc.gridwidth = 10;
        ui.add(new JButton("3,4 (10)"), gbc);

        gbc.gridx = 16;
        gbc.gridwidth = 3;
        ui.add(new JButton("4,4 (3)"), gbc);

        gbc.gridx = 19;
        ui.add(new JButton("5,4 (3)"), gbc);

        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.gridwidth = 1;

        for (int i = 0; i < 22; i++)
        {
            gbc.gridx = i;
            gbc.gridy = 4;
            ui.add(new JButton());
//          ui.add(Box.createHorizontalStrut(15));
        }


    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                KeyBoardLayout o = new KeyBoardLayout();

                JFrame f = new JFrame("Keyboard Layout");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Of course you don't want the buttons to show, so you can also use in invisible component.

Now, I have a question of my own. Why do the buttons appear on the first row, even though I set gridy = 4?



回答2:

I am afraid the desired layout is not so simple with simple GridBagLayout restriction. GBL does not respect proportions with gridwidth. It means it can't detect 2/3 of component's width. So if you define

c1 (gridwidth=2) c2 (gridwidth=1)
c3 (gridwidth=3)

Expecting to get

|****|**|
|*******|

The result will be

|**|**|
|*****|

The camickr's example works because the simple cell heights were defined and IMHO that's the only way.