实例化使用模板
GridBagLayout gbl = new GridBagLayout();
// gbl.columnWidths = new int[]{200,200,200}; // 用数组设置列
// gbl.rowHeights = new int[]{100,100,100,100,100}; // 用数组设置行
GridBagConstraints gbc = new GridBagConstraints();
/**
* gridBagConstraints.fill
* 当子组件比所在网格小时:
* 设置 fill =
* GridBagConstraints.NONE; 不拉伸, 是默认值
* GridBagConstraints.HORIZONTAL; 水平填满所在网格
* GridBagConstraints.VERTICAL; 垂直填满所在网格
* GridBagConstraints.BOTH; 拉伸到所在网格大小,填满所在网格,
*/
gbc.fill = GridBagConstraints.NONE;
// gbc.fill = GridBagConstraints.BOTH ;
/**
* gridBagConstraints.anchor , `anchor`中文意思是: 锚(n), 抛锚(v)
* 当子组件比所在网格小时:
* 设置 anchor =
* GridBagConstraints.CENTER; 位于水平和垂直的正中央,(默认值)
* GridBagConstraints.EAST; 东
* GridBagConstraints.SOUTH; 南
* GridBagConstraints.WEST; 西
* GridBagConstraints.NORTH; 北
* GridBagConstraints.NORTHEAST;(东北,右上)
* GridBagConstraints.SOUTHEAST;(东南,右下)
* GridBagConstraints.SOUTHWEST;(西南,左上)
* GridBagConstraints.NORTHWEST;(西北,左上)
* 还有很多选项
* 此属性接受三种类型的值:相对于方向(orientation relative)、相对于基线(baseline relative)和绝对位置(absolute)。
绝对位置值不依赖于其他因素,包括:CENTER(中心)、NORTH(北)、NORTHEAST(东北)、EAST(东)、SOUTHEAST(东南)、SOUTH(南)、SOUTHWEST(西南)、WEST(西)和NORTHWEST(西北)。
相对于方向的值依赖于容器的组件方向属性,包括:PAGE_START(页面开始)、PAGE_END(页面结束)、LINE_START(行开始)、LINE_END(行结束)、FIRST_LINE_START(第一行开始)、FIRST_LINE_END(第一行结束)、LAST_LINE_START(最后一行开始)和LAST_LINE_END(最后一行结束)。
相对于基线的值依赖于基线位置,包括:BASELINE(基线)、BASELINE_LEADING(基线前导)、BASELINE_TRAILING(基线后尾)、ABOVE_BASELINE(基线之上)、ABOVE_BASELINE_LEADING(基线之上前导)、ABOVE_BASELINE_TRAILING(基线之上后尾)、BELOW_BASELINE(基线之下)、BELOW_BASELINE_LEADING(基线之下前导)和BELOW_BASELINE_TRAILING(基线之下后尾)。
默认值是CENTER,表示组件居中放置。
*/
gbc.anchor = GridBagConstraints.CENTER;
// gbc.anchor = GridBagConstraints.NORTH;
gbc.gridx = -1; gbc.gridy = GridBagConstraints.RELATIVE; //网格的横纵坐标,从0开始, -1是RELATIVE相对自动
gbc.gridwidth = 1; gbc.gridheight = 1; //横向或纵向站几个网格,如同html的td的colspan和rowspan
gbc.ipadx = 0; gbc.ipady = 0; //增加子组件宽高, gbc.weightx = 0; gbc.weighty = 0; 才有效
gbc.weightx = 0; gbc.weighty = 0; //值为浮点数, 功能有点像css的grid的fr , 不为0时
GridBagLayout
columnWidths
用int数组设置列的数量和宽度rowHeights
用int数组设置行的数量和宽度columnWeights
double数组, 默认是空,rowWeights
double数组, 默认是空,
columnWidths 和 rowHeights
三行三列
GridBagLayout gbl = new GridBagLayout(); frame.setLayout(gbl);
gbl.columnWidths=new int[]{200,200,200}; // 用数组设置列
gbl.rowHeights = new int[]{100,100,100}; // 用数组设置行
单行单列
GridBagLayout gbl = new GridBagLayout(); frame.setLayout(gbl);
gbl.columnWidths=new int[]{200}; // 用数组设置列
gbl.rowHeights = new int[]{100}; // 用数组设置行
columnWeights 和 rowWeights
columnWeights
columnWeights是一个double数组,它包含一组可以覆盖已计算列权重的值。如果这个字段是非空的,那么在所有列的权重被计算之后,这些值将被应用到GridBag布局中。如果columnWeights数组中的某个元素的值大于对应列的权重,那么该列将被分配columnWeights数组中对应元素的值作为权重。然而,如果columnWeights数组的元素数量超过列的数量,多余的元素将被忽略,而不会导致创建更多的列。
/**
* This field holds the overrides to the column weights.
* If this field is non-{@code null} the values are
* applied to the gridbag after all of the columns
* weights have been calculated.
* If {@code columnWeights[i] >} weight for column i, then
* column i is assigned the weight in {@code columnWeights[i]}.
* If {@code columnWeights} has more elements than the number
* of columns, the excess elements are ignored - they do
* not cause more columns to be created.
*
* @serial
*/
public double[] columnWeights;
此字段包含列权重的覆盖。如果此字段非空,则值将在计算完所有列权重后应用于网格包。如果columnWeights[i] > column i的权重,则column i被分配columnWeights[i]中的权重。如果columnWeights的元素多于列数,则多余的元素将被忽略 - 它们不会导致创建更多的列。
rowWeights
rowWeights是一个double数组,它包含行权重的覆盖值。如果该字段不为空,则在计算完所有行权重后,这些值将被应用到网格包中。如果rowWeights[i]的值大于第i行的权重,则第i行将被分配rowWeights[i]中的权重。如果rowWeights的元素数量超过行数,多余的元素将被忽略,并且不会导致创建更多的行。
/**
* This field holds the overrides to the row weights.
* If this field is non-{@code null} the values are
* applied to the gridbag after all of the rows
* weights have been calculated.
* If {@code rowWeights[i] > } weight for row i, then
* row i is assigned the weight in {@code rowWeights[i]}.
* If {@code rowWeights} has more elements than the number
* of rows, the excess elements are ignored - they do
* not cause more rows to be created.
*
* @serial
*/
这个字段持有对行权重的覆盖。如果这个字段非空,那么这些值将在所有行权重被计算后应用于网格包(GridBag)。如果rowWeights[i] > i行的权重,那么i行将分配rowWeights[i]中的权重。如果rowWeights的元素数量超过行数,多余的元素将被忽略,它们不会导致创建更多的行。
public double[] rowWeights;
GridBagConstraint
GridBagConstraints
类包含许多用于定义这些约束的字段和方法。以下是一些常用的字段:
gridx
和gridy
:指定组件在网格中的位置。gridwidth
和gridheight
:指定组件跨越的网格单元数量。weightx
和weighty
:指定组件在其行或列中的额外空间分配比例。anchor
:指定组件在其网格单元中的对齐方式。fill
:指定组件在其网格单元中的填充方式。insets
:指定组件的边缘间距。
GridBagConstraints源码的无参构造方法,可看出默认值
public GridBagConstraints () {
gridx = RELATIVE; //从0开始第几列; 默认RELATIVE=-1,表示add时自动加列
gridy = RELATIVE; //从0开始第几行; 默认RELATIVE=-1,表示add时自动加行
gridwidth = 1; //如同colspan,横跨几列
gridheight = 1; //如共同rowspan,竖跨几行
weightx = 0; //浮点数, 功能有点像css的grid的fr
weighty = 0; //浮点数, 功能有点像css的grid的fr
anchor = CENTER;
fill = NONE;
insets = new Insets(0, 0, 0, 0);
ipadx = 0; // 增加子件宽度, weightx=0时才有用
ipady = 0; // 增加子件高度, weighty=0时才有用
}
GridBagConstraints源码的设参构造方法
public GridBagConstraints(int gridx, int gridy,
int gridwidth, int gridheight,
double weightx, double weighty,
int anchor, int fill,
Insets insets, int ipadx, int ipady) {
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth = gridwidth;
this.gridheight = gridheight;
this.fill = fill;
this.ipadx = ipadx;
this.ipady = ipady;
this.insets = insets;
this.anchor = anchor;
this.weightx = weightx;
this.weighty = weighty;
}
anchor
anchor
中文意思是: 锚(n), 抛锚(v)
anchor
属性决定了组件在其单元格中的位置。例如,如果 anchor
被设置为 GridBagConstraints.WEST
,组件将被左对齐。
以下是一些可能的 anchor
值:
GridBagConstraints.CENTER
:将组件居中在其单元格中(默认)。GridBagConstraints.NORTH
:将组件与其单元格的顶部对齐。GridBagConstraints.SOUTH
:将组件与其单元格的底部对齐。GridBagConstraints.EAST
:将组件与其单元格的右侧对齐。GridBagConstraints.WEST
:将组件与其单元格的左侧对齐。GridBagConstraints.NORTHWEST
:将组件与其单元格的左上角对齐。GridBagConstraints.NORTHEAST
:将组件与其单元格的右上角对齐。GridBagConstraints.SOUTHWEST
:将组件与其单元格的左下角对齐。GridBagConstraints.SOUTHEAST
:将组件与其单元格的右下角对齐。
还有更多取值,如与基线对齐相关的: GridBagConstraints.BASELINE
, GridBagConstraints.BASELINE_LEADING
, 和 GridBagConstraints.BASELINE_TRAILING
等值
anchor还有更多的取值,
此属性接受三种类型的值:相对于方向(orientation relative)、相对于基线(baseline relative)和绝对位置(absolute)。
-
绝对位置值不依赖于其他因素,包括:CENTER(中心)(默认值)、NORTH(北)、NORTHEAST(东北)、EAST(东)、SOUTHEAST(东南)、SOUTH(南)、SOUTHWEST(西南)、WEST(西)和NORTHWEST(西北)。
-
相对于方向的值依赖于容器的组件方向属性,包括:PAGE_START(页面开始)、PAGE_END(页面结束)、LINE_START(行开始)、LINE_END(行结束)、FIRST_LINE_START(第一行开始)、FIRST_LINE_END(第一行结束)、LAST_LINE_START(最后一行开始)和LAST_LINE_END(最后一行结束)。
-
相对于基线的值依赖于基线位置,包括:BASELINE(基线)、BASELINE_LEADING(基线前导)、BASELINE_TRAILING(基线后尾)、ABOVE_BASELINE(基线之上)、ABOVE_BASELINE_LEADING(基线之上前导)、ABOVE_BASELINE_TRAILING(基线之上后尾)、BELOW_BASELINE(基线之下)、BELOW_BASELINE_LEADING(基线之下前导)和BELOW_BASELINE_TRAILING(基线之下后尾)。
默认值是 CENTER,表示组件居中放置。GridBagConstraints.CENTER
fill
这个字段用于当组件的显示区域大于组件所请求的大小时。它决定了是否要调整组件的大小,以及如果要调整,该如何调整。
对于填充(fill)属性,以下值是有效的:
• NONE:不调整组件的大小。(默认值)
• HORIZONTAL:使组件足够宽,以水平填充其显示区域,但不改变其高度。
• VERTICAL:使组件足够高,以垂直填充其显示区域,但不改变其宽度。
• BOTH:使组件完全填充其显示区域。
默认值是NONE。这意味着,除非明确指定,否则组件的大小不会进行调整以适应其显示区域。
weightx
和weighty
gbc.weightx ; gbc.weighty; 可实现css的grid的fr的效果
注意f下面代码or循环中的gbc.weighty = gbc.weightx = r*c;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class T2311300901 {
public static void main(String...arguments)throws Exception{
JFrame frame = new JFrame(Thread.currentThread().getStackTrace()[1].getClassName());
frame.setBounds(100, 100, 800, 600);
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent wev) {
System.exit(100);
}
});
GridBagLayout gbl = new GridBagLayout();
// gbl.columnWidths = new int[]{200,200,200}; // 用数组设置列
// gbl.rowHeights = new int[]{100,100,100,100,100}; // 用数组设置行
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
// gbc.anchor = GridBagConstraints.EAST;
gbc.gridwidth = 1; gbc.gridheight = 1;
gbc.ipadx = 0; gbc.ipady = 0;
gbc.weightx = 0; gbc.weighty = 0;
JPanel panel = new JPanel(gbl); frame.getContentPane().add(panel);
int xc=3 , yc=3;
JButton jbtA2[][] = new JButton[yc][];
for(int r=0;r<yc;r++) {
jbtA2[r] = new JButton[xc];
for(int c=0;c<xc;c++) {
gbc.gridx=c;
gbc.gridy=r;
gbc.weighty = gbc.weightx = r*c;
JButton jbt = new JButton("<html><div style='color:red;'>"+"R"+r+"C"+c+"</div></html>");
// gbl.setConstraints(jbt, gbc); panel.add(jbt); // 可用 panel.add(jbt, gbc); 取代
//👆👇上下句效果一样,二选一
panel.add(jbt, gbc);
}
}
frame.setVisible(true);
}
}
用 GridBagLayout 和 GridBagConstraints 来居中
例1 , 单网格居中
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBag居中 {
static JFrame frame = new JFrame(Thread.currentThread().getStackTrace()[1].getClassName());
static GridBagLayout frameGbl = new GridBagLayout();
static GridBagConstraints frameGbc = new GridBagConstraints();
static {
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
frame.setBounds(100, 100, 800, 600);
frame.setLayout(frameGbl);
}
static JButton jbt = new JButton("jbt001");
static {
GridBagLayout gbl = frameGbl; GridBagConstraints gbc = frameGbc;
// 将布局设为一列一行, 如果不设定, 在只加入一个子组件时也会自动变为一列一行, 但是没有高宽, 即便fill=BOTH,由于网格的高宽为0,子组件依然是原始大小
gbl.columnWidths = new int[] {300}; // 网格宽度
gbl.rowHeights = new int[] {100}; // 网格高度
gbc.fill = GridBagConstraints.BOTH; // 横纵拉伸为和网格一样的宽高, 就可以用 columnWidths 和 rowHeights 来设定子组件的宽高
frame.add(jbt, gbc);
// 注意: 此时布局大小只是整个Button的大小,并不是容器的大小, 居中是因为容器的默认, 而不是 anchor 属性默认值的作用
}
public static void main(String...arguments)throws Exception{
frame.setVisible(true);
}
}
效果
关键代码
// 将布局设为一列一行, 如果不设定, 在只加入一个子组件时也会自动变为一列一行, 但是没有高宽, 即便fill=BOTH,由于网格的高宽为0,子组件依然是原始大小
gbl.columnWidths = new int[] {300}; // 网格宽度
gbl.rowHeights = new int[] {100}; // 网格高度
gbc.fill = GridBagConstraints.BOTH; // 横纵拉伸为和网格一样的宽高, 就可以用 columnWidths 和 rowHeights 来设定子组件的宽高
frame.add(jbt, gbc);
// 注意: 此时布局大小只是整个Button的大小,并不是容器的大小, 居中是因为容器的默认, 而不是 anchor 属性默认值的作用
还有一些属性因为默认值就满足要求,所以不用设置
注意: 此时布局大小只是整个Button的大小,并不是容器的大小, 居中是因为容器的默认, 而不是 anchor 属性默认值的作用
例2 , 九网格居中
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBag居中2 {
static JFrame frame = new JFrame(Thread.currentThread().getStackTrace()[1].getClassName());
static GridBagLayout frameGbl = new GridBagLayout();
static GridBagConstraints frameGbc = new GridBagConstraints();
static {
frame.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent ev) {
System.exit(0);
}
});
frame.setBounds(100, 100, 800, 600);
frame.setLayout(frameGbl);
}
static JButton jbt = new JButton("""
<html>
<span style="font-size:30px; color:blue; ">按钮1</span>
</html>
""");
static {
GridBagLayout gbl = frameGbl; GridBagConstraints gbc = frameGbc;
// 将布局设为一列一行, 如果不设定, 在只加入一个子组件时也会自动变为一列一行, 但是没有高宽, 即便fill=BOTH,由于网格的高宽为0,子组件依然是原始大小
gbl.columnWidths = new int[] {9999,300,9999}; // 网格宽度, 设置3列, 只要左右相等,就能居中,即便总数超过容器宽度
gbl.rowHeights = new int[] {666,300,666}; // 网格高度, 设置3列, 只要左右相等,就能居中,即便总数超过容器高度
gbc.fill = GridBagConstraints.BOTH; // 横纵拉伸为和网格一样的宽高, 就可以用 columnWidths 和 rowHeights 来设定子组件的宽高
gbc.gridx=1; gbc.gridy=1; // 放到中间格(横竖第二格),索引从0开始,所以第二格的索引号是1
gbc.anchor = GridBagConstraints.WEST;
frame.add(jbt, gbc);
}
public static void main(String...arguments)throws Exception{
frame.setVisible(true);
}
效果
关键代码
// 将布局设为一列一行, 如果不设定, 在只加入一个子组件时也会自动变为一列一行, 但是没有高宽, 即便fill=BOTH,由于网格的高宽为0,子组件依然是原始大小
gbl.columnWidths = new int[] {9999,300,9999}; // 网格宽度, 设置3列, 只要左右相等,就能居中,即便总数超过容器宽度
gbl.rowHeights = new int[] {666,300,666}; // 网格高度, 设置3列, 只要左右相等,就能居中,即便总数超过容器高度
gbc.fill = GridBagConstraints.BOTH; // 横纵拉伸为和网格一样的宽高, 就可以用 columnWidths 和 rowHeights 来设定子组件的宽高
gbc.gridx=1; gbc.gridy=1; // 放到中间格(横竖第二格),索引从0开始,所以第二格的索引号是1
gbc.anchor = GridBagConstraints.WEST;
frame.add(jbt, gbc);
可以用边缘网格控制中间网格的位置, 只居中时, 可以将左右上下网格的高宽设很大,只要左等于右,上等于下,就能居中,并且可以用中间网格的大小调整子组件的大小