我有以下代码在面板中显示许多标签:
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));
}
因为一切正常,所以:
现在,我对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));
}
现在我得到了这个怪物:
不再考虑数字3和4的高度,所有高度都相同。
为什么会这样呢?我怎样才能迫使布局服从我:(?
最佳答案
5号的合同应为1乘1并在第三行。显然,此处的布局不遵循此合同。当数字4和数字5的y和height属性不同时,它们如何具有相同的高度,甚至位于相同的位置?
您对GridBagLayout
的工作方式有些误解
因此,您的原始布局看起来像这样...
单元格1x1
(3
)和2x1
(4
)实际上过大,它们的高度是行1
和2
的高度之和
然后删除3x0
和3x1
的单元格,就可以看到类似这样的内容...
但是,等一下,GridBagLayout
很聪明,可以推断出,由于行跨度的原因,行1实际上是空的(组合大小为0),因此它压缩了行,最终结果是...
您可能会认为这是“错误的”,但事实并非如此,并且需要花费一些时间来思考实际发生的情况。
实际上唯一对行1
的高度有影响的单元格是单元格3x1
,从技术上讲,它现在的大小为0
,因为那里什么都没有,所以行高变成了0
(也(1x1
和1x2
的单元格的首选高度小于之前跨度的两行的总和,也有影响)
因此GridBagLayout
查看单元格1x1
(3
)和2x1
(4
)并将其高度计算为行1
和2
的高度之和,但是因为0
加任何都是什么,该行是“折叠的”,GridBagLayout
依赖于组件的preferred/minimum/maximum
大小来确定要使用的实际高度。
现在,我知道,您将抱怨这没有意义,因为单元格1x1
(3
)和2x1
(4
)从行1
开始,它们的高度会影响从某种意义上说,行的高度和所有内容的高度都可以,但是随后它们又扩展了两行,这在GridBagLayout
的思想中对结果有影响,这正是GridBagLayout
的工作方式。
那么,有什么解决方案?是否喜欢,如果不希望布局不压缩,则需要在3x2
处提供某种具有所需行高的组件。我知道,这不是一个很好的解决方案,过去我做了很多不同的修改来使其工作(使用JLabel
,其前景色与容器的背景色相同,或者具有前景色完全透明的颜色,我什至使用了自己的布局管理器,该管理器忽略了组件的visible
属性,以使其保持容器的大小相同,因此我可以“隐藏”和“显示”组件而无需压缩布局)
另一个解决方案可能是调查其他布局管理器,我建议以MigLayout作为起点。
现在,再次,在您抱怨它“没有意义”或“不正确”或“它一定是错误”之前-记住,这是GridBagLayout
在过去20多年的工作方式-这是它的工作方式-您需要了解它并使用它,或者找到其他选择-很抱歉让您感到痛苦,但这只是它的方式:(