GridBagLayout为列提供额外的余量
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GridBagLayout为列提供额外的余量相关的知识,希望对你有一定的参考价值。
我已经和Swing一起工作了一段时间,我终于找到了学习GridBadLayout的自信。
我还在学习它,在这种情况下我无法理解为什么以下代码没有按预期响应:特别是我无法理解为什么布局以这种方式显示列。
通过运行代码片段,您将看到表示意大利语标志的面板未正确定位:最后一列(标志的红色部分)与标志的其余部分(标志的白色部分)分离。那么,我做错了什么,我能解决什么才能代表国旗呢?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class test extends JPanel {
private GridBagConstraints gbc;
private final int CELL_WIDTH = 90;
private final int CELL_HEIGHT = 110;
public test() {
setLayout(new GridBagLayout());
putBanner(0);
putFlagRow(1);
putFlagRow(2);
putFlagRow(3);
putFlagRow(4);
}
public JPanel getUserPanel(Color c) {
JPanel ol = new JPanel();
ol.setPreferredSize(new Dimension(CELL_WIDTH * 10, CELL_HEIGHT));
ol.setBackground(c);
return ol;
}
public JPanel gettestPanel() {
JPanel ol = new JPanel();
ol.setPreferredSize(new Dimension(CELL_WIDTH, CELL_HEIGHT));
ol.setBackground(Color.white);
return ol;
}
private void putFlagRow(int gridy) {
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = gridy;
JPanel p1=gettestPanel();
p1.setBackground(Color.green);
add(p1, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 3;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 4;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 5;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 6;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 7;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 8;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 9;
gbc.gridy = gridy;
JPanel p=gettestPanel();
p.setBackground(Color.red);
add(p, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 10;
gbc.gridy = gridy;
add(gettestPanel(), gbc);
}
private void putBanner(int gridy) {
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = gridy;
gbc.gridwidth = 1;
add(gettestPanel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = gridy;
gbc.gridwidth = 9;
add(getUserPanel(Color.black), gbc);
}
public static void main(String[] args) {
JFrame frame = new JFrame("GridBagLayoutTest");
frame.add(new test());
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
除了解这个特定问题及其原因外,我希望能够理解这一点,直接来自GridBagLayout Oracle文档:
weightx,weighty指定权重是一种艺术,可以对GridBagLayout控制的组件的外观产生重大影响。权重用于确定如何在列(weightx)和行(weighty)之间分配空间;这对于指定调整大小行为非常重要。除非您为weightx或weighty指定至少一个非零值,否则所有组件在其容器的中心聚集在一起。这是因为当权重为0.0(默认值)时,GridBagLayout会在其单元格网格与容器边缘之间放置任何额外空间。通常,权重指定为0.0和1.0作为极值:根据需要使用其间的数字。较大的数字表示组件的行或列应该获得更多空间。对于每列,权重与为该列中的组件指定的最高权重x相关,每个多列组件的权重在组件所在的列之间以某种方式分割。类似地,每行的权重与为a指定的最高权重相关。该行中的组件。额外的空间倾向于最右边的列和底行。
表达式如
是一门艺术
和
必要时使用两者之间的数字
真的给我的印象是,即使是文档作者也不认为可以教这种约束的用法。这不好
最后一列(标志的红色部分)与标志的其余部分(标志的白色部分)分离。
调试GridBagLayout
时要做的一件事是将Border
添加到组件中,这样您就可以看到每个单元格的大小。我在getTestPanel()
方法中添加了以下内容:
ol.setBorder( new LineBorder(Color.BLUE) );
您可以看到面板尺寸正确但面板周围有额外的空间。
然后你看看你的用户面板:
ol.setPreferredSize(new Dimension(CELL_WIDTH * 10, CELL_HEIGHT));
即使您只将网格宽度设置为9个单元格,您也会看到大小设置为10个单元格。所以现在9个单元格必须适合用户面板的空间,看起来额外的空间被赋予9列的最后一列。
代码应该是:
//ol.setPreferredSize(new Dimension(CELL_WIDTH * 10, CELL_HEIGHT));
ol.setPreferredSize(new Dimension(CELL_WIDTH * 9, CELL_HEIGHT));
另一种选择是不向用户面板提供首选大小,但随后使用“填充”约束,以便用户面板现在占用与九列相同的空间。
weightx,weighty指定权重是一门艺术......
这与您的问题无关。要查看此效果,请将框架拖大。现在所有整个面板都将位于框架的中心,因为您的任何组件都不使用weightx / weighty约束。这意味着如果帧没有任何组件将增长以填充空白空间。
如果其中一个组件的权重约束为1.0,那么该列将展开并在调整框架大小时填充额外的空间。
weightX和weighty非常容易使用,但教程没有帮助...让我们说当你进行对话并且你pack()
它时,组件采取位置和大小,一切都好(或不是)。如果您调整对话框并使其变大,会发生什么?突然间有更多的空间,组件必须增长,这就是Swing看起来weight*
参数的时刻。
如果一个组件有weightx=1.0
,其余的weightx=0.0
意味着第一个组件获得所有新空间而第二个组件保持其大小。如果组件有weightx=0.5
意味着两个组件共享新的大小,每个组件50%。如果组件的weightx值大于1.0,则意味着组件需要超过100%的新空间,所以......好吧,有些神奇......
想象一下,你正在做一个网络浏览器。你希望带有标签,按钮和菜单的顶部面板保持相同的大小,而网页的中心面板获得所有新的额外尺寸,所以你给顶部面板的中心面板weight*=1.0
和weight*=0.0
。
尽量不要在任何行或列中分配超过1.0的重量,一切都会好的。
我认为你想要实现的是这样的:
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test extends JPanel {
private static final long serialVersionUID = 1L;
public Test() {
setLayout(new GridBagLayout());
putBanner(0);
putFlagRow(1);
}
public JPanel getUserPanel(Color c) {
JPanel panel = new JPanel();
panel.setBackground(c);
return panel;
}
private void putFlagRow(int gridy) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = gridy;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 0.5;
gbc.weighty = 1;
add(getUserPanel(Color.green), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = gridy;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
add(getUserPanel(Color.white), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = gridy;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 0.5;
gbc.weighty = 1;
add(getUserPanel(Color.red), gbc);
}
private void putBanner(int gridy) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = gridy;
gbc.ipady = 50;
gbc.fill = GridBagConstraints.BOTH;
add(getUserPanel(Color.white), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = gridy;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
add(getUserPanel(Color.black), gbc);
}
public static void main(String[] args) {
JFrame frame = new JFrame("GridBagLayoutTest");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(new Test());
frame.setSize(450, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
GridBagLayout是一种非常复杂和强大的方式来对齐你的内容,用两句话来解释它并不容易,所以最简单的方法是玩游戏或看一些教程,但我会尝试:
您必须考虑编辑Excel表格。如果您调整一个单元格宽度,整个列将具有此宽度,行/高度相同。所以现在你不必添加白色平面的色调,你只需要一个并正确调整它的大小。
接下来的事情不是设置固定的大小,布局会为你做,这是它们的用途或使用绝对坐标(没有布局:setLayout(null)
)。
所以现在你必须告诉GridBagLayout如何对齐组件。不同的比对有不同的变量。首先(你应该已经知道)gridx
和gridy
保持组件的位置(在Excel中类似于A1或C12)。比你可以'组合细胞'与gridwidth
和gridheight
。
所以现在您的组件已定位,但它不会随窗口大小而改变其大小。直到知道单元格只有其组件的大小getPreferredSize()
。 weightx
和weighty
是下一个要看的变量。这些定义了应该使用多少剩余空间。例如,您有两个组件(水平并排),它们的首选宽度总和为300px,但窗口的宽度为1000px,不使用700px。因此,如果您现在将weightx
设置为1,他们会尝试使用百分之百的剩余像素,但是它们不能同时拥有700px,因此每个人都会获得350px。如果你现在将一个weightx
设置为0而另一个设置为1,则第一个没有额外的像素,另一个没有700px。
如果你到现在为止尝试过,你会在面板之间看到很多空白区域,因为只有单元格被调整大小,而不是它们的内容。现在你可以设置组件应该在其单元格中显示anchor
(例如GridBagConstraints.NORTH
/ SOUTH
/ SOUTHEAST
),但是你仍然有那些空格并且没有标志有空格,你要找的是fill
。
fill
让您选择,如何处理单元格中的空白区域。使用GridBagConstraints.NONE
时,组件不会调整大小,HORIZONTAL
只调整宽度到单元格的宽度(VERTICAL
只调整高度),BOTH
调整组件大小以适应单元格大小。
变量insets
添加了空插图,例如你选择将fill
设置为BOTH
,但是sill想要在组件上方留空空间(插入是固定的,如果你想要动态插入,你必须通过添加空组件来解决方法)特定的GridBagConstraints用于对齐要显示的插图)。
ipadx
和ipady
是要添加到单元格大小的固定值,例如ipadx
设置为5,单元格将至少具有组件最小宽度加上ipadx
的5px的宽度。换句话说,单元格的宽度将始终比组件的宽度大至少5px(如果fill
设置为BOTH
或HORIZONTAL
,则组件将随后调整为新宽度)。
以上是关于GridBagLayout为列提供额外的余量的主要内容,如果未能解决你的问题,请参考以下文章