有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么这个GridBagLayout没有按计划出现?

我试图达到Setting an arbitrary width in GridBagLayout中要求的最终结果

为了便于参考,这里是:

这是当前的结果:

按钮编号和行以1,1的形式显示,后跟为此单元格声明的(2)列数

如您所见,它以按钮1,1 (3)开始,其下1,2 (4)的宽度相同,同时声明了不同的列数

有人能确定如何更正代码吗

当前代码:

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

共 (2) 个答案

  1. # 1 楼答案

    从图片上看,每行包含5到9个按钮,这意味着GridBagLayout只知道9个单独列的宽度

    把(…)中的数字加起来表示每行的总gridwidth。总数是22

    {}不知道如何将9列转换为22列。它不知道在列中没有组件的列要使用什么宽度。因此布局不知道如何处理gridwidth约束

    解决方案是告诉GridBagLayout网格中预期的列数和网格中每列的最小宽度

    这可以通过设置GridBagLayout本身的值来实现:

    //ui = new JPanel(new GridBagLayout());
    int[] columns = new int[22];
    Arrays.fill(columns, 30);
    GridBagLayout gbl = new GridBagLayout();
    gbl.columnWidths = columns;
    ui = new JPanel(gbl);
    

    数组的大小定义列数

    分配给数组中每个条目的值是列的“最小宽度”(每个列的宽度可能不同)

    现在GridBagLayout知道如何计算每个列的宽度,并且使用gridwidth作为每个组件的约束将按预期工作

    更新代码如下:

    import java.awt.*;
    import java.util.Arrays;
    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());
            int[] columns = new int[22];
            Arrays.fill(columns, 30);
            GridBagLayout gbl = new GridBagLayout();
            gbl.columnWidths = columns;
            ui = new JPanel(gbl);
    
            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);
        }
    }
    

    这种方法也可以用于行

    这意味着GridBagLayout提供了创建网格的能力,并且只使用组件填充网格中的少数单元格

  2. # 2 楼答案

    我恐怕想要的布局没有简单的GridBagLayout限制那么简单。GBL不考虑gridwidth的比例。这意味着它无法检测组件宽度的2/3。 所以如果你定义

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

    期待得到

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

    结果将是

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

    camickr的示例之所以有效,是因为定义了简单的单元高度,而IMHO是唯一的方法