1、GridBagLayout 网格包布局管理器网格包布局管理是最复杂和灵活的布局管理,在下面偶会作详细的介绍。与网格布局管理器不同的是,网格包布局管理器允许容器中各个组件的大小各不相同,还允许组件跨越多个网格,也允许组件之间相互部分重叠。网格包布局理解为网格单元布局更合理,因为一个容器被划分为若干个网格单元,而每个组件放置在一个或多个网格单元中。要注意的是,网格包布局不能指定一个容器的网格单元的大小其网格单元的划分是通过 weightx 和 weighty 参数来设置的,但也不是直接指定其网格单元的大小。当把一个组件放置在网格单元中时,组件所占据的位置和大小是由一组与他们相关联的约束来决定的。这
2、些约束是由 GridBagConstraints 类型的对象来设置的,关于 GridBagConstraints 类型,后面会做专门的介绍。由上所述使用网格包布局的一般步骤为:1、创建一个 GridBagLayout 网格包布局对象,并使其成为当前容器的布局管理器。2、创建一个 GridBagConstraints 类型的约束对象,然后使用该对象设置各种约束条件,注意这里设置的约束条件并没有针对某一组件,要使某一组件具有设置的约束,需要使用第 3 步骤的方法。3、然后使用 GridBagLayout 网格包布局中的 setConstraints(Component com, GridBagCo
3、nstraints cons)方法将GridBagConstraints 类型对象设置的约束添加到被设置的组件中,这样该组件就具有了 GridBagConstraints 设置的约束。其中 setConstraints()的第一个参数是将要添加的组件,第二个参数是 GridBagConstraints 类型的约束对象。4、最后将设置了约束的组件添加到容器中。使用网格包布局的第二种方法为:1、使 GridBagLayout 布局成为当前容器的布局管理器,这里也可以不用创建 GridBagLayout 对象。2、创建一个 GridBagConstraints 类型的约束对象,然后使用该对象设置约束
4、条件。注意这里设置的约束条件并没有针对某一组件,要使某一组件具有设置的约束,需要使用第 3 步骤的方法。3、然后使用 add(Component com, Object cons)方法将组件和约束同时添加进容器中,这样添加进容器的组件就具有了第 2 步的约束。注意其中的 add(Component com, Object cons);第一个参数是将要添加的组件,第二个参数是要添加的 GridBagConstraints 类型的约束对象。GridBagConstraints 类型的约束参数:double weightx 和 double weighty 参数(默认值为 0)这是两个非常重要的参数
5、,该参数直接影响到怎样设置网格单元的大小,因此常握好该参数就可以对网格包布局应用自如。该参数对 x 方向和 y 方向指定一个加权值。这个加权值直接影响到网格单元的大小,比如 weightx 的值分别为10,20,30,则在容器的 x 方向也就是列的方向,按一定的比例(比如 1:2:3 其具体算法请参看 java 文件)分配三个网格单元,其中加权值越大网格单元就越大,可以看出值的大小是没有关系的,加权值的作用是让容器以设定的值的比例在横向和纵向分配网格,且在容器的大小改变时这个比例不改变。如果 weightx 只设置了一个值,而组件却不只一个以上,则被设置了的这个组件的网格单元的大小为容器在 x
6、 方向的大小减去那两个组件的最小尺寸就是该组件的网格单元大小。默认情况下组件的最小尺寸是比较小的。如果两个参数都为 0(默认值),则组件会被显示在容器的中央,不管容器是放大还是缩小组件都只会显示在容器的中央。由上所述,在使用网格包布局时首先应先使用 weightx 和 weighty 来划分网格单元(不是直接划分,而是按一定比例来划分),网格单元划分出来后,组件放置在网格单元中的位置和大小就由后面介绍的约束来决定。一定要注意的是设置权值后要使当前的设置生效应使用 setConstraints()函数一次,如果连续设置多个同一方向的权值,则只有最后一次设置的权值有效,比如出现同时两行都设置了 x
7、 方向的权值,则以最后一行设置的 x 方向的权值为标准来划分网格单元。因此在使用 GridBagLayout 网格包布局管理器之前应先设置好网格单元,即要把容器划分为几行几列的网格单元,每行每列在容器中的宽度和高度比例,每个组件应在哪个网格单元。int fill 参数(默认值为 GridBagConstraints.NONE)fill 参数指定组件填充网格的方式,当某组件的网格单元大于组件的大小时被使用,一般情况下组件是以最小的方式被显示的,如果不使用 fill 参数,则有可能组件占不完整个网格单元,也就是说组件占据的空间比划分的网格单元小,这时组件将显示在网格单元中的某个位置(具体在什么位置
8、由网格包中的参数来设置) 。其可取的值如下:GridBagConstraints.NONE 默认值,不改变组件的大小。GridBagConstraints.HORIZONTAL 使组件足够大,以填充其网格单元的水平方向,但不改变高度,其值等于整数2。GridBagConstraints.VERTICAL 使组件足够大,以填充其网格单元的垂直方向,但不改变宽度,其值等于整数 3。GridBagConstraints.BOTH 使组件足够大,以填充其整个网格单元,其值等于整数 1。int gridwidth和int gridheight参数(默认值为1)该参数指定组件占据多少个网格单元,gridw
9、idth指定组件占据多少个网格单元的宽度,gridheight指定组件占据多少个网格单元的高度。两个参数的默认值都为1。其中值GridBagConstraints.REMAINDER表示当前组件在其行或列上为最后一个组件,也就是说如果是行上的最后一个组件的话,那么下一个组件将会被添加到容器中的下一行,如果在行上不指定该值(同时也不指定gridx和gridy参数) ,那么无论添加多少个组件都是在同一行上,同样如果在列上不指定该值(同时也不指定gridx和gridy 参数) 则无论添加多少行组件,都无法把容器填满。值 GridBagConstraints.RELATIVE表示当前组件在其行或列上为
10、倒数第二个组件。import java.awt.*;public class Programpublic static void main(String args) Frame ff = new Frame();GridBagLayout gr = new GridBagLayout();GridBagConstraints gc = new GridBagConstraints(); /创建一个名为gc的约束对象ff.setLayout(gr); /将容器ff的布局设为GridBagLayout/创建一组按钮组件Button bb1 = new Button(“bb1“); Button b
11、b2 = new Button(“bb2“); Button bb3 = new Button(“bb3“);Button bb4 = new Button(“bb4“); Button bb5 = new Button(“bb5“); Button bb6 = new Button(“bb6“);Button bb7 = new Button(“bb7“); Button bb8 = new Button(“bb8“);gc.fill = GridBagConstraints.BOTH;/设置约束的fill参数,该参数表示当组件的大小小于网格单元的大小时在水平和垂直方向都填充,gc.weig
12、htx =11; /设置x方向的加权值为11。gc.weighty = 11;/设置y方向的加权值为11。gr.setConstraints(bb1, gc); /将以上gc所设置的约束应用到按钮组件bb1gc.weightx = 22;/设置x方向的加权值为22,如果不设置weightx则以下的组件都将自动应用上面所设置的weightx值11。gr.setConstraints(bb2, gc); /将以上所设置的约束应用到按钮组件bb2。/gc.weighty=111; /注意如果不注释掉该行,则以后使用gc约束的按钮组件在y方向的加权值将为111,而在前面设置的y方向的加权值11将失去作
13、用。gc.weightx =33;gc.gridwidth = GridBagConstraints.REMAINDER;/设置gridwidth参数的值为REMAINDER这样在后面使用该约束的组件将是该行的最后一个组件。gr.setConstraints(bb3, gc); /第一行添加了三个按钮组件bb1,bb2,bb3,且这3个按钮的宽度按weightx设置的值11,22,33按比例设置宽度GridBagConstraints gc1 = new GridBagConstraints();/创建第二个约束gc1gc1.fill = GridBagConstraints.BOTH;gc1
14、.weighty = 22; /将第2行的y方向加权值设为22gr.setConstraints(bb4, gc1);gr.setConstraints(bb5, gc1);gc1.gridwidth = GridBagConstraints.REMAINDER;gr.setConstraints(bb6, gc1); /第二行添加了三个按钮组件bb4,bb5,bb6gc1.weighty =33;gc1.gridwidth = GridBagConstraints.REMAINDER;gr.setConstraints(bb7, gc1);/第三行添加了一个按钮组件bb7gc1.weight
15、y=0;gr.setConstraints(bb8, gc1); /第四行添加了一个按钮组件bb8,bb8并没有添加到bb7的后面,因为bb8使用了bb7前面的gridwidth参数设置的值,所以bb8也是单独的一行。ff.setSize(500, 300);ff.add(bb1); ff.add(bb2);ff.add(bb3); ff.add(bb4); ff.add(bb5); ff.add(bb6); ff.add(bb7); ff.add(bb8);ff.setVisible(true); int gridx和int gridy参数(默认值为GridBagConstraints.RE
16、LATIVE)该参数表示组件被添加到容器中的X 或者Y 坐标处,坐标以网格单元为单位,也就是说不管网格单元有多大,一个网格单元就是1X1的大小,也就是说如果把 gridx和gridy都设为1,那么该组件会被显示到第二行的行二列上。其中值GridBagConstraints.RELATIVE(默认值) 表示当前组件紧跟在上一个组件的后面。int ipadx和int ipady参数(默认值为0)ipadx和inady也被称为内部填充,该参数用以设置组件的最小尺寸,如果参数值为正值则组件的最小尺寸将比原始最小尺寸大,如果为负值,则组件的最小尺寸将会变得比原始的最小尺寸小。该参数也可以理解为直接为组件
17、指定大小,这个设置的大小就是组件的最小尺寸。其设置后组件的大小为组件的原始最小尺寸加上ipadx*2个像素。int anchor 参数(默认值为 GridBagConstraints.CENTER)该参数指定当组件的大小小于网格单元时,组件在网格单元中的位置。一般情况下,在设置了 weightx 或者 weighty的加权值时,如果不使用 fill 参数填充空白区域,则组件的大小将小于网格单元的大小,这时使用 anchor 参数就能看到其中的效果了。anchor 参数可取的值有:GridBagConstraints.CENTER; GridBagConstraints.NORTH;GridBa
18、gConstraints.NORTHEAST;GridBagConstraints.EAST;GridBagConstraints.SOUTHEAST;GridBagConstraints.SOUTH;GridBagConstraints.SOUTHWEST;GridBagConstraints.WEST;GridBagConstraints.NORTHWEST ;即居中,北,东北,东,东南,南,西南,西,西北方向。Insets insets 参数( 默认值为 0)insets 参数也被称为外部填充,该参数指定组件与网格单元之间的最小空白区域大小,要注意的是即使使用了 fill 参数填充横向和
19、纵向但只要设置了 insets 参数,同样会留出 insets 所设置的空白区域,在 insets 设置的空白区域不会被填充。在使用该参数时需要设置对象的 top,left,right,bottom 四个方向的值来调整组件与网格单元之间的空白区域大小,比如 gc.insets=new Insets(10,10,10,10);其中 gc 是 GridBagConstraints 类型的约束对象,这里要注意后面的 new Insets 其中的 Insets 第一个字母是大写的。当然也可以为 insets 指定负值,以扩大其网格单元。示例:import java.awt.*;public class
20、 Programpublic static void main(String args)/将容器ff的布局设为GridBagLayoutFrame ff = new Frame();GridBagLayout gr = new GridBagLayout();GridBagConstraints gc = new GridBagConstraints(); /创建一个名为gc的约束对象ff.setLayout(gr);/创建一组按钮组件Button bb1 = new Button(“bb1“); Button bb2 = new Button(“bb2“); Button bb3 = new
21、 Button(“bb3“);这两行的 weightx 的值分别为 11,22,33 可以看到 bb1,bb2,bb3 按钮的宽度是不一样的,他们是按 weightx 设置的比例来设定的,因此当容器进行缩放时,组件会随之缩放这 3 列的 weighty 的值分别为 11,22,33 可以看到 3 行按钮的高度是不一样的,他们是按weighty 设置的比例来设定的,因此当容器进行缩放时,组件会随之缩放参数 fill 设置为 GridBagConstraints.BOTH 时的效果按钮 bb1,bb2,bb3 的 fill 参数使用默认值的情况,从此图可以看出来,当 fill 设为默认值时,在组件
22、的网格单元中,多余的空间是空白的,没有被填充,如果把 fill 设为GridBagConstraints.BOTH 则 bb1,bb2,bb3 的效果将与bb4,bb5,bb6 相同。从此图中也可以看出使用 weightx 和weighty 设置网格单元的情形,bb1,bb2,bb3 组件占据的网格单元大于组件的大小。参数 fill 使用默认值(即不填充) 时的情况Button bb4 = new Button(“bb4“); Button bb5 = new Button(“bb5“); Button bb6 = new Button(“bb6“);Button bb7 = new Butt
23、on(“bb7“); Button bb8 = new Button(“bb8“);gc.fill = GridBagConstraints.BOTH;gc.weightx = 11; gc.weighty = 11; gr.setConstraints(bb1, gc);gc.weightx = 22;gc.gridx = 1; gc.gridy = 1; /将下一个组件放置在坐标为1,1的位置。gr.setConstraints(bb2, gc);gc.weightx = 33;gc.gridx = 2; gc.gridy = 1; /将下一个组件放置在坐标为2,1的位置。gc.inset
24、s = new Insets(-10, -10, -10, -10); /将下一个组件与网格单元的空白区域向外扩展10个像素,在这里可以看到网格包布局允许组件之间重叠。gc.gridwidth = GridBagConstraints.REMAINDER; gr.setConstraints(bb3, gc); GridBagConstraints gc1 = new GridBagConstraints(); gc1.weighty = 22;gc1.ipadx = 50; gc1.ipady = 50; /将组件的最小尺寸加大ipadx*2个像素。gr.setConstraints(bb4
25、, gc1);gc1.ipadx = 0; gc1.ipady = 0; /将以后的组件的最小尺寸设置为默认值,如果省掉该行,则以后组件的最小尺寸都会加大ipadx*2个像素。gc1.anchor = GridBagConstraints.NORTHWEST; /将下一个组件bb5的位置放置在单元网格的西北方向。gr.setConstraints(bb5, gc1); /因为bb5未设置fill,同时bb5设置了weightx(由gc参数设置)和weighty两个值以确定bb5所在的网格单元的大小,因而组件bb5的原始最小尺寸无法占据整个网格单元。gc1.fill = GridBagConst
26、raints.BOTH;gc1.gridwidth = GridBagConstraints.REMAINDER;gr.setConstraints(bb6, gc1); gc1.weighty = 33;gc1.insets = new Insets(5, 15,40,150); /使下一个组件bb7与网格单元之间在上,左,下,右,分别保持5,15,40,150个像素的空白位置。gr.setConstraints(bb7, gc1); gc1.weighty = 0;gc1.insets = new Insets(0, 0, 0, 0); /将insets的参数值设为默认值。gr.setCo
27、nstraints(bb8, gc1); ff.setSize(500, 300);ff.add(bb1); ff.add(bb2); ff.add(bb3); ff.add(bb4); ff.add(bb5); ff.add(bb6); ff.add(bb7); ff.add(bb8);ff.setVisible(true);组件 bb2 被放在坐标为 1,1 的位置 部分重叠的地方组件 bb3 被 insets 设置为-10,-10,-10,-10bb4 被 ipadx 和 ipady 扩大了 ipad*2 个像素的大小组件 bb5 被 anchor 设置在了西北角位置因为 bb5未设置 fill,同时bb5设置了 weightx(由 gc参数设置)和 weighty两个值以确定 bb5所在的网格单元的大小,因而组件 bb5的原始最小尺寸无法占据整个网格单元。组件 bb7 设置了 fill 同时insets 被设置为 5,15,40,150可以看到 bb7与网格单元的上,左,右,下分别保留了5,15,40,150 个像素的空白区域。网格包布局的参数 ipadx,ipady, anchor, insets, gridx, gridy 示例