为什么GridBagLayout在我的组件上强制一些高度?

时间:2017-06-09 11:39:18

标签: java swing layout-manager gridbaglayout

我有以下代码在面板中显示多个标签:

    private static class Bordered extends JLabel {
        public Bordered(final String text) {
            super(text);
            this.setBorder(new MatteBorder(2,2,2,2,Color.BLACK));
        }
    }

    public static void main(String[] args) {
        Frame frame = new Frame("toto");

        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(new Bordered("0"), new GridBagConstraints(0,0,1,3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("1"), new GridBagConstraints(1,0,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("2"), new GridBagConstraints(2,0,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("3"), new GridBagConstraints(1,1,1,2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("4"), new GridBagConstraints(2,1,1,2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("5"), new GridBagConstraints(3,2,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("6"), new GridBagConstraints(4,0,1,3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("7"), new GridBagConstraints(3,0,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("7bis"), new GridBagConstraints(3,1,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));


        frame.add(panel);

        frame.pack();
        SwingUtilities.invokeLater(() -> frame.setVisible(true));
    }

因为一切正常:

Layout

现在,我并没有真正使用7和7bis,我只是添加它们来向您展示我想要的东西。所以让我们删除它们:

    private static class Bordered extends JLabel {
        public Bordered(final String text) {
            super(text);
            this.setBorder(new MatteBorder(2,2,2,2,Color.BLACK));
        }
    }

    public static void main(String[] args) {
        Frame frame = new Frame("toto");

        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(new Bordered("0"), new GridBagConstraints(0,0,1,3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("1"), new GridBagConstraints(1,0,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("2"), new GridBagConstraints(2,0,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("3"), new GridBagConstraints(1,1,1,2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("4"), new GridBagConstraints(2,1,1,2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("5"), new GridBagConstraints(3,2,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
        panel.add(new Bordered("6"), new GridBagConstraints(4,0,1,3, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
//        panel.add(new Bordered("7"), new GridBagConstraints(3,0,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));
//        panel.add(new Bordered("7bis"), new GridBagConstraints(3,1,1,1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(3, 3, 3, 3), 0, 0));


        frame.add(panel);

        frame.pack();
        SwingUtilities.invokeLater(() -> frame.setVisible(true));
    }

现在我得到了这个怪物:

Monstrosity

不再考虑3号和4号的高度,一切都是相同的高度。

为什么会这样?我怎么能强迫布局服从我:(?

1 个答案:

答案 0 :(得分:4)

  

5号合约将是1比1和第3行。这个合同显然没有遵循这里的布局。当数字和高度属性不同时,数字4和数字5如何具有相同的高度,或者甚至在相同的位置?

您对GridBagLayout的工作方式有一些误解

因此,您的原始布局看起来像这样......

Original

单元格1x13)和2x14)实际上是超大的,其高度是行1和{的高度的总和{1}}

然后你删除23x0的单元格,你就会有这样的期望......

Expectations

但是,等等,3x1很聪明,推断出,由于行跨度,第1行实际上是空的(组合大小为0)所以它会压缩行并结束...... ...

Actual

你可能会认为这是错误的",但事实并非如此,而且需要一些时间来思考实际发生的事情。

实际上对行GridBagLayout的高度有任何影响的唯一单元格是单元格1,技术上现在的大小为3x1,因为那里没有任何内容,所以行高变为0(单元格@ 01x1的首选高度也小于之前跨度的两行之和,它也有影响)

因此1x2会查看单元格GridBagLayout1x1)和32x1),并将其高度计算为行高的总和{ {1}}和4,但因为1加上任何东西都是什么,所以行是#34;折叠"并且2依赖于0组件的大小来确定要使用的实际高度。

现在,我知道,你会抱怨说这没有意义,因为单元格GridBagLayoutpreferred/minimum/maximum)和1x1({{1 }})从行3开始,它们的高度应该影响行的高度和所有内容,在某种意义上它们会影响它们,但是它们也会扩展两行,这在2x1的头脑中有对结果有影响,这就是4的工作原理。

那么,解决方案是什么?不管您喜欢与否,如果您希望布局不要压缩,您需要在1处提供某种具有所需行高的组件。我知道,它不是一个很好的解决方案,我过去做了很多不同的黑客工作(使用GridBagLayout,其前景色与背景色相同容器,或者具有完全透明的前景色。我甚至使用了我自己的布局管理器,忽略了组件的GridBagLayout属性,使其保持容器的大小相同,所以我可以"隐藏"和#34;显示"组件没有布局压缩)

另一个解决方案可能是调查其他布局管理器,我建议将MigLayout作为起点。

现在,再次,在你抱怨之前,#34;没有意义"或者"不正确"或者"它必须是bug" - 请记住,这就是3x2过去20多年来的工作方式 - 这就是它的工作方式 - 你需要了解它并使用它或找到另一种选择 - 抱歉对此感到痛苦,但那& #39;就是这样:(