AWT03-LayoutManager布局管理器
阅读原文时间:2023年07月11日阅读:3

  在之前的学习中,我们使用setBounds()方法设置容器的位置大小,但我们不得不明白一件事--如果我们手动为容器设置位置大小的话,就会造成程序通用性的下降。 

1 import java.awt.*;
2
3 public class LabelDemo {
4 public static void main(String[] args) {
5 Label label = new Label("Hello world");
6 }
7 }

  在该代码中,我们定义了一个Label。在很多情况下,我们需要让label的宽高和"Hello world"这个字符串自身的宽高一样,这个宽高被称为“最佳大小”。

  在Windows上,我们需要将宽高设置为100px,20px。但在Linux上,为了达到相同的效果,我们需要将宽高设置为120px,24px。

  一个拥有上千个组件的大型程序中,为了达到各平台相同的视觉效果,其手动调整工作无疑是一场灾难。为了解决这一个问题,LayoutManager诞生了。

(接口)LayoutManager

  -GridLayout(网格布局)

  -FlowLayout(流式布局)

  -(接口)LayoutManager2

    -CardLayout(卡片布局)

    -GridBagLayout(网格包布局)

    -BorderLayout(边框布局)

3.1 FlowLayout 流式布局

3.1.1 简介

  FlowLayout布局管理器中,组件像是流水一般向某方向流动(排列),遇到障碍(边界)就折回,另起一行重新开始。一般情况下,FlowLayout的排列方向是从左向右。

方法名

说明

FlowLayout()

使用默认的对齐方式、默认的垂直间距和默认的水平间距创建LayoutManager布局管理器。

FlowLayout(int align)

使用指定的对齐方式、默认的垂直间距和默认的水平间距创建LayoutManager布局管理器。

FlowLayout(int align,int hgap,int vgap)

使用指定的对齐方式、指定的垂直间距和指定的水平间距创建LayoutManager布局管理器。

  FlowLayout布局管理器的排列方向,从左向右、从右向左、从中间向两边,该参数使用FlowLayout类的静态常量:FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER。

  水平和垂直间距的单位是px,默认是5px。

3.1.2 代码演示

1.添加一个窗口

2.设置布局管理器

3.添加组件

4.设置大小、pack方法

1 import java.awt.*;
2
3 public class setFlowLayoutDemo {
4 public static void main(String[] args) {
5 Frame f = new Frame("FlowLayoutDemo");
6 f.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));
7
8 for (int i = 0;i<10;i++){
9 f.add(new Button("按钮"+i));
10 }
11 f.pack();
12 f.setVisible(true);
13 }
14 }

3.2 BorderLayout 边框布局

3.2.1 简介

  BorderLayout边框布局将容器分为North、South、West、East、Center五个区域,普通的组件可以放在这五个区域中任意一个。

  当改变BorderLayout的大小时,North、South、Center水平调整,而West、East、Center垂直调整(竖着的横着调,横着的竖着调,中间的全部调)。

  注意:

    1.当向使用BorderLayout布局的容器中添加组件时,需要指定组件的区域,如果没有指定默认添加到Center。

    2.当向一个区域添加多个组件时,后放入的组件会覆盖先放入的组件。

方法名

说明

Borderlayout()

使用默认的垂直与水平间距创建BorderLayout布局

BorderLayout(int hgap,int vgap)

使用指定的垂直与水平间距创建BorderLayout布局

3.2.2 代码演示

1 import java.awt.*;
2
3 public class setBorderLayoutDemo {
4 public static void main(String[] args) {
5 Frame f = new Frame("BorderLayoutDemo");
6
7 f.setLayout(new BorderLayout(30,5));
8
9 f.add(new Button("北按钮"),BorderLayout.NORTH);
10 f.add(new Button("南按钮"),BorderLayout.SOUTH);
11 f.add(new Button("东按钮"),BorderLayout.EAST);
12 f.add(new Button("西按钮"),BorderLayout.WEST);
13 f.add(new Button("中按钮"),BorderLayout.CENTER);
14
15 f.pack();
16
17 f.setVisible(true);
18
19 }
20 }

1 import java.awt.*;
2
3 public class setBorderLayoutDemo {
4 public static void main(String[] args) {
5 Frame f = new Frame("BorderLayoutDemo");
6
7 f.setLayout(new BorderLayout(30, 5));
8
9 f.add(new Button("北按钮"), BorderLayout.NORTH);
10 f.add(new Button("南按钮"), BorderLayout.SOUTH);
11 // f.add(new Button("东按钮"),BorderLayout.EAST);
12 // f.add(new Button("西按钮"),BorderLayout.WEST);
13 // f.add(new Button("中按钮"),BorderLayout.CENTER);
14 Panel p = new Panel();
15 p.add(new TextField(20));
16 p.add(new Button("中间按钮"));
17
18 f.add(p);
19
20 f.pack();
21
22 f.setVisible(true);
23
24 }
25 }

3.3 GridLayout 网格布局

3.3.1 简介

  GridLayout布局管理器将容器分割成纵横线分割的网格,每个网格所占的区域大小相同。当向使用GridLayout布局的容器中添加组件时,默认从左向右、从上向下,依次添加到每个网格中。与FlowLayout不同的是,放置在GridLayout布局管理器中的组件大小由组件所处的区域决定(每个组件将占满整个区域)。

方法名

说明

GridLayout(int rows,int cols)

使用指定的行数、列数以及默认的垂直间距和默认的水平间距创建GridLayout布局管理器。

GridLayout(int rows,int cols,int hgap,int vgap)

使用指定的行数、列数以及指定的垂直间距和指定的水平间距创建GridLayout布局管理器。

3.3.2 代码演示

1 import java.awt.*;
2
3 public class setGridLayout {
4 public static void main(String[] args) {
5 Frame f = new Frame("计算器");
6 Panel pp = new Panel();
7 pp.add(new TextField(30));
8
9 f.add(pp,BorderLayout.NORTH);
10
11 Panel p = new Panel();
12 p.setLayout(new GridLayout(3,5,4,4));
13 p.add(new Button("1"));
14 p.add(new Button("2"));
15 p.add(new Button("3"));
16 p.add(new Button("4"));
17 p.add(new Button("5"));
18 p.add(new Button("6"));
19 p.add(new Button("7"));
20 p.add(new Button("8"));
21 p.add(new Button("9"));
22 p.add(new Button("0"));
23 p.add(new Button("+"));
24 p.add(new Button("-"));
25 p.add(new Button("*"));
26 p.add(new Button("/"));
27 p.add(new Button("%"));
28
29 f.add(p);
30
31 f.pack();
32
33 f.setVisible(true);
34 }
35 }

3.4 GridBagLayout 网格包布局

  GridBagLayout布局是功能最强大也最复杂,与GridLayout不同,在GridBagLayout中组件可以跨过一个或多个网格且可以设置各个网格大小不同,从而增加了网格布局的灵活性。当窗口的大小发生变化时,GridBagLayout也可以准确的控制窗口各部分的拉伸。

  由于在GridBagLayout中组件可以跨越网格,所以在往容器内添加组件时,需要具体的控制每个组件占用多少个网格,Java提供GridBagConstraints,与特定的组件绑定,可以完成具体大小和跨越性的设置。

3.5 CardLayout 卡片布局

  CardLayout布局管理器以时间而非空间来管理其中的组件,它将加入容器中的组件看成一叠卡片(每一张卡片其实就是一个组件),每次只有最上面的Component可见。

方法名

说明

CardLayout()

创建默认的CardLayout布局

CardLayout(int hgap,int vgap)

使用指定的水平间距、垂直间距创建CardLayout

first(Container target)

显示target容器中的第一张卡片

last(Container target)

显示target容器中的最后一张卡片

previous(Container target)

显示target容器中的前一张卡片

next(Container target)

显示target容器中的后一张卡片

show(Container target,String name)

显示target容器中指定名字的那一张卡片

1 import java.awt.*;
2 import java.awt.event.ActionEvent;
3 import java.awt.event.ActionListener;
4
5 public class setCardLayout {
6 public static void main(String[] args) {
7 Frame f = new Frame("CardLayout");
8
9 Panel p1 = new Panel();
10 CardLayout cl = new CardLayout();
11 p1.setLayout(cl);
12
13 String[] names = {"第一张","第二张","第三张","第四张","第五张"};
14 for (int i = 0;i< names.length;i++){
15 p1.add(names[i],new Button(names[i]));
16 }
17
18 f.add(p1);
19
20 Panel p2 = new Panel();
21
22 Button b1 = new Button("第一张");
23 Button b2 = new Button("上一张");
24 Button b3 = new Button("第三张");
25 Button b4 = new Button("下一张");
26 Button b5 = new Button("最后一张");
27
28 ActionListener al = new ActionListener() {
29 @Override
30 public void actionPerformed(ActionEvent e) {
31 String command = e.getActionCommand();
32 switch (command){
33 case "第一张":
34 cl.first(p1);
35 break;
36 case "上一张":
37 cl.previous(p1);
38 break;
39 case "第三张":
40 cl.show(p1,"第三张");
41 break;
42 case "下一张":
43 cl.next(p1);
44 break;
45 case "最后一张":
46 cl.last(p1);
47 break;
48 }
49 }
50 };
51
52 b1.addActionListener(al);
53 b2.addActionListener(al);
54 b3.addActionListener(al);
55 b4.addActionListener(al);
56 b5.addActionListener(al);
57
58 p2.add(b1);
59 p2.add(b2);
60 p2.add(b3);
61 p2.add(b4);
62 p2.add(b5);
63
64 f.add(p2,BorderLayout.SOUTH);
65
66 f.pack();
67
68 f.setVisible(true);
69 }
70 }

3.6 BoxLayout 盒布局

  BoxLayout是为了简化开发由Swing引入的,可以在垂直和水平两个方向上摆放组件。

方法名

说明

BoxLayout(Container target,int axis)

指定创建基于target容器的BoxLayout布局管理器,该布局管理器里的组件会按照axis方向排列。其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)。

1 import javax.swing.*;
2 import java.awt.*;
3
4 public class setBoxLayout {
5 public static void main(String[] args) {
6 Frame frame = new Frame("BoxLayout");
7
8 BoxLayout box = new BoxLayout(frame, BoxLayout.X_AXIS);
9
10 frame.setLayout(box);
11
12 frame.add(new Button("按钮1"));
13 frame.add(new Button("按钮2"));
14
15 frame.pack();
16 frame.setVisible(true);
17 }
18 }

  在Swing中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout。大多数情况下,使用Box容器去容纳多个组件,然后再把Box容器最为一个组件添加到其他容器中形成完整的窗口布局。

方法名

说明

static Box createHorizontalBox()

创建一个水平排列组件的容器

static Box createVerticalBox()

创建一个垂直排列组件的容器

1 import javax.swing.*;
2 import java.awt.*;
3
4 public class BoxLayout {
5 public static void main(String[] args) {
6 Frame frame = new Frame("BoxLayOut");
7
8 Box hbox = Box.createHorizontalBox();
9 Box vbox = Box.createVerticalBox();
10
11 hbox.add(new Button("1"));
12 hbox.add(new Button("2"));
13
14 vbox.add(new Button("3"));
15 vbox.add(new Button("4"));
16
17 frame.add(hbox,BorderLayout.NORTH);
18 frame.add(vbox,BorderLayout.SOUTH);
19
20 frame.pack();
21
22 frame.setVisible(true);
23 }
24 }

  我们发现,在这时生成的界面没有任何间隔,不是特别美观,因此可以在需要间隔的地方添加间隔组件。

方法名

说明

static Component createHorizontalGlue()

创建一条水平Glue(可在两个方向上同时拉伸的间距)

static Component createVerticalGlue()

创建一条垂直Glue(可在两个方向上同时拉伸的间距)

static Component createHorizontalStrut(int width)

创建一条指定宽度的水平Strut(可以在垂直方向上拉伸的间距)

static Component createVerticalStrut(int height)

创建一条指定高度的水平Strut(可以在水平方向上拉伸的间距)

1 import javax.swing.*;
2 import java.awt.*;
3
4 public class BoxLayout {
5 public static void main(String[] args) {
6 Frame frame = new Frame("BoxLayOut");
7
8 Box hbox = Box.createHorizontalBox();
9 Box vbox = Box.createVerticalBox();
10
11 hbox.add(new Button("水平1"));
12 hbox.add(Box.createHorizontalGlue());
13 hbox.add(new Button("水平2"));
14
15 vbox.add(new Button("垂直1"));
16 vbox.add(Box.createVerticalGlue());
17 vbox.add(new Button("垂直2"));
18
19 frame.add(hbox,BorderLayout.NORTH);
20 frame.add(vbox,BorderLayout.SOUTH);
21
22 frame.pack();
23
24 frame.setVisible(true);
25 }
26 }