GridBagLayout(网格包布局管理器)是在网格基础上提供复杂的布局,是最灵活、最复杂的布局管理器。GridBagLayout 不需要组件的尺寸一致,允许组件扩展到多行多列。每个 GridBagLayout 对象都维护了一组动态的矩形网格单元,每个组件占一个或多个单元,所占有的网格单元称为组件的显示区域。
GridBagLayout 所管理的每个组件都与一个 GridBagConstraints 约束类的对象相关。这个约束类对象指定了组件的显示区域在网格中的位置,以及在其显示区域中应该如何摆放组件。除了组件的约束对象,GridBagLayout 还要考虑每个组件的最小和首选尺寸,以确定组件的大小。
为了有效地利用网格包布局管理器,在向容器中添加组件时,必须定制某些组件的相关约束对象。GridBagConstraints 对象的定制是通过下列变量实现的。
1. gridx 和 gridy
用于指定组件左上角在网格中的行和列,网格默认的布局方向是从左到右、从上到下,容器中最左边列的 gridx 为 0,最上边行的 gridy 为 0。这两个变量的默认值是 GridBagConstraints.RELATIVE,表示对应的组件将放在前一个组件的右边或下面。
2. gridwidth 和 gridheight
用于指定组件显示区域所占的水平与竖直方向的网格数,即列数和行数,以网格单元而不是像素为单位,默认值为 1。
3. anchor
指定组件在显示区域中的摆放位置。可设置的值如下:
- GridBagConstraints.CENTER(默认值)
- GridBagConstraints.NORTH
- GridBagConstraints.NORTHEAST
- GridBagConstraints.EAST
- GridBagConstraints.SOUTH
- GridBagConstraints.SOUTHEAST
- GridBagConstraints.WEST
- GridBagConstraints.SOUTHWEST
- GridBagConstraints.NORTHWEST
4. fill
指定组件填充网格的方式,可设置的值如下:
- GridBagConstraints.NONE:默认值;
- GridBagConstraints.HORIZONTAL:组件横向充满显示区域,但是不改变组件高度;
- GridBagConstraints.VERTICAL:组件纵向充满显示区域,但是不改变组件宽度;
- GridBagConstraints.BOTH:组件横向、纵向充满其显示区域。
5. ipadx 和 ipady
指定组件显示区域的内部填充,即在组件最小尺寸之外需要附加的像素数,默认值为 0。通过该参数设置后,组件大小固定,不推荐通过该方式进行设置。
- ipadx:设置ipadx之后会使组件宽度变大,使得新组件的宽度变为:原组件宽度+ipadx,当取值为负数时组件宽度会缩小。
- ipady:设置ipady之后会使组件高度变大,使得新组件的高度变为:原组件高度+ipady,当取值为负数时组件高度会缩小。
6. insets
是指组件与其显示区域边缘之间的空间,默认组件没有外部填充,可通过TOP、BOTTOM、RIGHT、LEFT进行设置,设置方式如下。 注:当间隔为负数时,组件会显示在网格外面而不会将网格撑大。
button1.Insets=new Insets(TOP1,LEFT1,BOTTOM1,RIGHT1)
button2.Insets=new Insets(TOP2,LEFT2,BOTTOM2,RIGHT2)
7. weightx 和 weighty
当指定容器大小改变时,可通过 weightx 和 weighty 设置组件之间宽度和高度变化的分配权重,即增加/减少的空间在组件间分配的权重,数值大表明组件所在的行或者列将获得更多的空间。默认值为 0,即所有的组件将聚拢在容器的中心,多余的空间将放在容器边缘与网格单元之间。
- weightx、weighty设置页面拉伸时,组件网格的大小按比例进行伸缩。
- 因为同一列网格的宽度是相同的,所以当其中的一个网格变动时,其他网格也会随之变动。
- 如果整个面板中所有网格的weightx均为0,则多余的空白区域会分布在面板的左右两端。weighty在竖直方向上同理。
下图中对话框中的按钮的weightx、weighty设置和显示效果如下:
- PanelA :weightA1按钮的setWeight(weightx:0, weighty:0),weightA2按钮的setWeight(weightx:1, weighty:0);因此,对话框拉大时,weightA1按钮宽高不拉伸,weightA2按钮宽度拉伸,高度不变。
- PanelB :weightB1按钮的setWeight(weightx:1, weighty:0),weightB2按钮的setWeight(weightx:1, weighty:0);因此,对话框拉大时,weightB1、weightB2按钮宽度拉伸比例一致,高度不变。
- PanelC :weightC1按钮的setWeight(weightx:1, weighty:0),weightC2按钮的setWeight(weightx:2, weighty:0);因此,对话框拉大时,weightC2按钮宽度拉伸比例是weightC1的2倍,高度不变。
示例
在JFrame中,设置两个Label布局参数。具体实现代码如下:
package com.supermap.desktop.samplecode.layout.gridbaglayout;
import javax.swing.*;
import java.awt.*;
public MyGridBagLayout() {
JPanel panel = new JPanelShowGrid();
this.add(panel);
GridBagLayout mgr = new GridBagLayout();
panel.setLayout(mgr);
panel.add(new JLabel("left"),new GridBagConstraintsHelper(0,0).setFill(GridBagConstraints.HORIZONTAL).setWeight(1,0));
panel.add(new JLabel("right"), new GridBagConstraintsHelper(1, 0).setFill(GridBagConstraints.HORIZONTAL).setWeight(0, 1).setInsets(0, 10, 0, 0));
}
public static void main(String[] args) {
MyGridBagLayout frame = new MyGridBagLayout();
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
示例代码运行结果如下,left标签靠左显示,right标签靠右显示,拉大或缩小界面,left标签大小会随界面的大小而变化,right标签大小不变: