【问题标题】:Why does this GridBagLayout not appear as planned?为什么这个 GridBagLayout 没有按计划出现?
【发布时间】:2015-02-06 22:23:03
【问题描述】:

我试图达到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);
    }
}

【问题讨论】:

  • 你知道,我花了非常非常长的时间试图让这样的东西工作并最终放弃并编写了我自己的布局管理器:P
  • @MadProgrammer 我试过写一个自定义布局管理器..once。一个ScrollLayout。我由一位布局大师运行它,他评论 WTE 说它“可以使用一些改进”。因为他是一个非常、非常好人,不喜欢冒犯他人——我认为这意味着我的努力更接近“可悲,结果很脆弱”。 ;)
  • 是的,它是专门为该任务而构建的
  • 据我所知,GridBagLayout 不喜欢在列的内容超出该列范围的情况下填满一列 - 这可能与 fill 有关属性
  • 对于example - 不使用GridBagLayout,但这是一个想法

标签: java swing layout-manager gridbaglayout


【解决方案1】:

恐怕只有简单的 GridBagLayout 限制,想要的布局就不那么简单了。 GBL 不尊重与网格宽度的比例。这意味着它无法检测到组件宽度的 2/3。 所以如果你定义

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

期待得到

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

结果将是

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

camickr 的示例有效,因为定义了简单的单元格高度,恕我直言,这是唯一的方法。

【讨论】:

    【解决方案2】:

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

    将 (..) 中的数字相加,表示每行的总数 gridwidth。总数为 22 个。

    GridBagLayout 不知道如何将 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 提供了创建网格并且只用组件填充网格的几个单元格的能力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-07
      • 2019-07-22
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多