0、
    GirdBagLayout(网格包布局管理器)是最灵活、最复杂的布局管理器。与 GridLayout 布局管理器类似,不同的是,它允许网格中的组件大小各不相同,而且允许一个组件跨越一个或者多个网格。

    1、
    使用 GirdBagLayout 布局管理器的步骤如下。
    1、创建 GirdBagLayout 布局管理器,并使容器采用该布局管理器。

    1. GridBagLayout layout = new GridBagLayout();
    2. container.setLayout(layout);

    2、创建 GridBagConstraints 对象(布局约束条件),并设置该对象的相关属性。

    1. GridBagConstraints constraints = new GridBagConstraints();
    2. constraints.gridx = 1; //设置网格的左上角横向引索
    3. constraints.gridy = 1; //设置网格的左上角纵向引索
    4. constraints.gridwidth = 1; //设置组件横向跨越的网格
    5. constraints.gridheight = 1; //设置组件纵向

    3、调用 GirdBagLayout 对象的 setConstraints()方法建立 GridBagConstraints 对象和受控组件之间的关联。

    1. layout.setConstraints(component, constraints)

    4、向容器中添加组件。

    1. container.add(component);

    GridBagConstraints 对象可以重复使用,只需要改变它的属性即可。如果要向容器中添加多个组件,则重复步骤 2、步骤 3、步骤 4。

    2、
    从上面的步骤可以看出,使用 GridBagLayout 布局管理器的关键在于 GridBagConstraints 对象,它才是控制容器中每个组件布局的核心类,在 GridBagConstraints 类中有很多表示约束的属性,下面对 GridBagConstraints 类的一些常用属性进行介绍,如下表所示。

    属性 作用
    gridx 和 gridy 设置组件的左上角所在的网格的横向和纵向引索(即所在的行和列)。如果将 gridx 和 gridy 的值设置为 GridBadConstraints.RELATIVE(默认值),表示当前组件紧跟在上一个组件后面
    gridwidth 和 gridheight 设置组件横向、纵向跨越几个网格,两个属性的默认值都是 1。如果把这两个属性的值设为 GridBagConstraints.REMAINER,表示当前组件在其行或列上为倒数第 1 个组件。如果把这两个属性的值设为 GridBagConstraints.RELATIVE,表示当前组件在其行或列上为倒数第 2 个组件
    fill 如果当组件的显示区域大于组件需要的大小,设置是否及如何改变大小,该属性接受以下几个属性
    - NONE:默认,不改变组件大小
    - HORIZNTAL:使组件水平方向足够长以填充显示区域,但高度不变、
    - BERTICAL:使组件垂直方向足够高以填充显示区域但长度不变
    - BOTH:使组件足够大,以填充整个显示区域
    weightx 和 weighty 设置组件占领容器中多余的水平方向和垂直方向空白的比例(也称为权重)。假设容器的水平方向放置 3 个组件,其 weightx 分别为 1、2、3,当容器宽度增加10、20 和 30 的像素这两个属性的默认值是 0,即不占领多余的空间

    上表中列出了 GridBagConstraints 的常用属性。其中,gridx 和 gridy 用于设置组件左上角所在网格的横向和纵向引索,gridwith 和 griheight 用于设置组件横向、纵向跨越几个网格,fill 用于设置是否及如何改变大小,weightx 和 weighty 用于设置组件在容器中的水平方向和垂直方向的权重。

    需要注意的是,如果希望组件的大小随着容器的增大而增大,必须同时设置 GridBagConstrains 对象的 fill 属性和 weightx、weighty 属性。

    3、
    接下来通过一个案例来演示 GridBagLayout 的用法,如下所示。

    1. import java.awt.*;
    2. class Layout extends Frame{
    3. public Layout(String title) {
    4. GridBagLayout layout = new GridBagLayout();
    5. GridBagConstraints c = new GridBagConstraints();
    6. this.setLayout(layout);
    7. c.fill = GridBagConstraints.BOTH; //设置组件横向纵向可以拉伸
    8. c.weightx = 1; //设置横向权重为 1
    9. c.weighty = 1; //设置纵向权重为 1
    10. this.addComponent("btn1", layout, c);
    11. this.addComponent("btn2", layout, c);
    12. this.addComponent("btn3", layout, c);
    13. //添加的组件是本行最后一个组件
    14. c.gridwidth = GridBagConstraints.REMAINDER;
    15. this.addComponent("btn4", layout, c);
    16. c.weightx = 0; //设置横向权重为 0
    17. c.weighty = 0; //设置纵向权重为 0
    18. this.addComponent("bun5", layout, c);
    19. c.gridwidth = 1; //设置组件跨一个网格(默认值)
    20. this.addComponent("bun6", layout, c);
    21. //添加的组件是本行的最后一个组件
    22. c.gridwidth = GridBagConstraints.REMAINDER;
    23. this.addComponent("bun7", layout, c);
    24. c.gridheight = 2; //设置组件纵向跨两个网格
    25. c.gridwidth = 1; //设置组件横向跨一个网格
    26. c.weightx = 2; //设置横向权重为 2
    27. c.weighty = 2; //设置纵向权重为 2
    28. this.addComponent("btn8", layout, c);
    29. //添加的组件是本行的最后一个组件
    30. c.gridwidth = GridBagConstraints.REMAINDER;
    31. c.gridheight = 1;
    32. this.addComponent("bun9", layout, c);
    33. this.addComponent("bun10", layout, c);
    34. this.setTitle(title);
    35. this.pack();
    36. this.setVisible(true);
    37. }
    38. //创建 addComponent()方法
    39. private void addComponent(String name, GridBagLayout layout, GridBagConstraints constraints) {
    40. Button button = new Button(name); //创建一个名为 name 的按钮
    41. layout.setConstraints(button, constraints); //设置 GridBagConstraints 和按钮的关联
    42. this.add(button); //添加按钮
    43. }
    44. }
    45. public class example05 {
    46. public static void main(String[] args) {
    47. new Layout("GridBagLayout");
    48. }
    49. }

    运行程序,生成的窗口如下所示。
    QQ截图20200618095727.png

    上述代码块中,向 GirdBagLayout 布局管理器中添加 10 个按钮。由于每次添加组件的时候都需要调用该布局的 setConstraints()方法,将 GridBagConstraints 对象与按钮组件相关联,依次,可以将这段关联的代码抽取到 addComponent()方法当中,简化书写。

    在添加 button1 button10按钮时,都将权重 weightx 和 weighty 的值设置为大于 0,因此在拉伸窗口时,这些按钮都会随着窗口增大。而在添加 button5 ~ button7 按钮时,将权重值设置为 0,这样它们的高度在拉伸时没有变化,但长度**受上下组件**的影响,还是会随窗口变大。