Java 为什么GridBagLayout会强制我的组件具有一定的高度?
我使用以下代码在面板中显示多个标签:Java 为什么GridBagLayout会强制我的组件具有一定的高度?,java,swing,layout-manager,gridbaglayout,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
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和7的用途,我只是添加它们来告诉你我想要什么。因此,让我们删除它们:
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,在第三排。这里的布局显然没有遵循该合同。当y和高度属性不同时,4号和5号怎么可能具有相同的高度,甚至处于相同的位置
您对GridBagLayout
的工作原理有些误解
所以,您的原始布局看起来像这样
单元格1x1
(3
)和2x1
(4
)实际上尺寸过大,它们的高度是行1
和2
高度的总和
然后移除3x0
和3x1
处的单元格,您会期望得到类似的结果
但是,等等,GridBagLayout
很聪明,可以推断,由于行的跨度,第1行实际上是空的(合并大小为0),因此它压缩了行,结果是
你可能会认为这是“错误的”,但事实并非如此,你需要一些时间来思考到底发生了什么
实际对行高度有任何影响的唯一单元格是cell3x1
,从技术上讲,它现在的大小为0
,因为没有任何内容驻留在那里,所以行高度变为,0
(此外,@1x1
和1x2
单元格的首选高度小于之前跨度的两行之和,这也会产生影响)
因此,GridBagLayout
查看单元格1x1
(3
)和2x1
(4
)并将它们的高度计算为行1
和2
的高度之和,但因为0
加上任何东西,所以行是“折叠的”而GridBagLayout
依赖于组件的首选/最小/最大尺寸来确定要使用的实际高度
现在,我知道,你会抱怨这没有意义,因为单元格1x1
(3
)和2x1
(4
)从第1行开始,它们的高度应该会影响行的高度和所有内容,从某种意义上说,它们确实会影响,但是它们也会扩展两行,在GridBagLayout
的思想中,这会影响结果,这就是GridBagLayout
的工作方式
那么,解决方案是什么呢?不管你喜欢与否,如果你不想压缩布局,你需要在3x2
提供某种组件,它具有所需的行高度。我知道,这不是一个很好的解决方案,我在过去做过很多不同的破解来让它工作(使用前景色与容器背景色相同的JLabel
,或者前景色是完全透明的。我甚至使用了自己的布局管理器,它忽略了组件的visible
属性,使其使容器保持相同的大小,因此我可以“隐藏”并在不压缩布局的情况下“显示”组件)
另一个解决方案可能是调查其他布局管理器,我建议将miglayet作为起点
现在,再一次,在你抱怨它“没有意义”或“不对”或“它一定是错误”之前-请记住,GridBagLayout
在过去20多年中就是这样工作的-这就是它的工作方式-你需要理解它并使用它,或者找到一个替代方案-很抱歉为此感到痛苦,但这就是它的工作方式:(将空白JLabel放在7和7bis位置。但GridBagLayout就是这样工作的。要获得更详细的解释,请在本网站上搜索数百个类似的问题。感谢您批评试图免费帮助您的人。该布局现在实际上是在尊重您组件的高度。事实上,它们更高因为3
和4
是用来填充两行并在水平方向上填充的。这里真正的问题是,为什么在更改布局条件后,你会期望它们保持“过大”——我同意HovercraftFullOfEels,如果你是为了“效果”,那么就是“填充物”组件将有助于实现您的期望result@BhalchandraSW:他无论如何都应该这样做,所以你的评论不是第一个。@Saffron它不是一个bug,这就是GridBagLayout
的工作原理-它可能对你没有意义,但是GridBagLayout
是一个非常复杂的布局,需要理解很多可能的场景,因此,它优先于某些条件,行/列跨度在该列表中并不高。第二,在布局要求“强调”标准布局要求的情况下,使用第三方布局管理器。另一个解决方案是深入研究创建自定义布局管理器。1+