一、前言
记录时间 [2024-05-31]
前置文章
GUI 01:GUI 编程概述,AWT 相关知识,Frame 窗口,Panel 面板,及监听事件的应用
本文讲述了 GUI 编程种布局管理器的相关知识,以及 AWT 的 3 种布局管理器——流式布局、边界布局(东西南北中)、网格布局。搭配面板使用,可以实现布局嵌套功能。
二、布局管理器
1. 相关概念
布局管理器,是 GUI 编程中的一个重要概念,它负责安排容器中组件的大小和位置。使用布局管理器可以使得 GUI 在不同的窗口大小、屏幕分辨率以及国际化的文本长度变化时,能够自适应地调整其布局,保持界面的整洁和一致性。
Java 提供了多种内置的布局管理器来满足不同场景的需求。下面是一些常用的布局管理器:
- FlowLayout(流式布局):组件按照添加顺序从左到右排列,行满后换行。适合简单的菜单或按钮排列。
- BorderLayout(边界布局):将容器划分为五个区域:北、南、东、西和中心。每个区域只能放置一个组件,常用于主窗口的基本布局。
- GridLayout(网格布局):将容器分割成一个矩形网格,每个网格中放置一个组件。所有网格大小相等,适用于需要均匀分布组件的场景,如棋盘界面。
- GridBagLayout(网格包布局):提供更复杂的网格布局功能,允许每个组件跨越多行或多列,以及设置组件的权重来控制空间分配。非常灵活,但配置也相对复杂。
- BoxLayout(盒式布局):是 Swing 中提供的,它可以沿容器的一个轴(水平或垂直)排列组件,类似于流式布局,但提供了更精细的对齐和填充控制。
- CardLayout(卡片布局):允许在同一个空间内堆叠多个组件(像卡片一样),但每次只有一个组件可见。常用于实现选项卡或向导式的界面。
2. 使用步骤
使用布局管理器的一般步骤包括:
- 创建一个容器(如 Frame、Panel 等);
- 为这个容器选择并设置一个合适的布局管理器;
- 向容器中添加组件,并根据需要调整组件的约束条件(某些布局管理器需要);
- 调整容器的大小或使用
pack()
方法让容器自动调整到最适合其内容的大小。
三、流式布局
1. 相关概念
在 Java 的 AWT(Abstract Window Toolkit,抽象窗口工具包)中,流式布局(FlowLayout)是一种布局管理器,它按照组件添加到容器的顺序从左到右排列组件。当一行排满时,后续的组件会自动换行到下一行继续排列。流式布局非常适合于创建菜单、按钮栏等简单界面元素的布局。
流式布局的主要特点包括:
- 组件顺序:组件按照添加到容器的顺序依次排列。
- 对齐方式:默认情况下,组件在每一行中居左对齐,但可以通过构造函数指定居中对齐
FlowLayout.CENTER
或居右对齐FlowLayout.RIGHT
。 - 水平和垂直间隙:可以设置组件之间的水平和垂直间隙,以调整布局的紧凑度或宽松度。
- 自动换行:一行排满后自动换到下一行显示,无需手动处理换行逻辑。
2. 案例分析
编写代码
例如,将 3 个按钮按照流式布局添加到窗口中。
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame("TestFlowLayout");
// 组件 - 按钮
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
// 设置为流式布局
frame.setLayout(new FlowLayout());
frame.setSize(400, 400);
// 把按钮添加上去
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setVisible(true);
}
}
效果查看
三个按钮在窗口中的位置如图所示,流式布局默认是居中的。
居左居右
流式布局默认是居中的,当然也可以实现居左居右。
// 流式布局默认居中
frame.setLayout(new FlowLayout());
// 设置靠左
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
// 设置靠右
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
四、边界布局
1. 相关概念
边界布局(BorderLayout)将容器划分为五个区域:北(North)、南(South)、东(East)、西(West)和中心(Center)。每个区域可以放置一个组件,这样的设计非常适合创建具有标准框架结构的窗口,比如带有菜单栏、工具栏、状态栏和主要内容区域的窗口布局。
边界布局的特点包括:
- 五个区域:每个区域都有特定的含义和默认的行为。中心区域通常占据最大的空间,而北、南、东、西区域则作为边缘区域,通常放置辅助性的控件如按钮、标签等。
- North:位于容器顶部,通常用于放置标题栏、菜单栏等。
- South:位于容器底部,常用于放置状态栏、确认/取消按钮等。
- East:位于容器右侧,适合放置侧边栏或较小的控制面板。
- West:位于容器左侧,用途与东区相似,也是放置辅助控件的好位置。
- Center:占据容器剩余的所有空间,主要用于放置主要的内容或控件。
- 组件大小:除了中心区域会填充剩余空间外,其他区域的大小默认为所包含组件的最佳大小,但也可以通过设置组件的首选大小来影响它们的尺寸。
- 单一组件:边界布局的每个区域只能放置一个组件。如果需要在同一区域内放置多个组件,应该先将这些组件放入一个容器(如Panel),再将该容器添加到相应的区域。
2. 案例分析
编写代码
例如,在东西南北中 5 个位置分别添加一个按钮。
public class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame("TestBorderLayout");
Button east = new Button("East");
Button west = new Button("West");
Button south = new Button("South");
Button north = new Button("North");
Button center = new Button("Center");
// 添加到布局中
frame.add(east, BorderLayout.EAST);
frame.add(west, BorderLayout.WEST);
frame.add(south, BorderLayout.SOUTH);
frame.add(north, BorderLayout.NORTH);
frame.add(center, BorderLayout.CENTER);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
效果查看
窗口效果如图所示,呈现出东西南北中的架构。
五、网格布局
1. 相关概念
网格布局(GridLayout)将容器划分为一个二维的网格结构,每个网格中可以放置一个组件。组件在网格中均匀分布,每个网格的大小相同,由其中最大的组件决定。
网格布局适用于需要将界面元素组织成规则矩阵的情况,如计算器、棋盘或表格布局等。
使用网格布局的特点包括:
- 行列数量:在创建 GridLayout 时,可以指定行数和列数,或者只指定一个参数。
- 如
new GridLayout(3, 2)
表示 3 行 2 列; - 而
new GridLayout(2)
表示 2 行,每行的列数由添加的组件自动决定。
- 如
- 组件大小:所有网格的大小一致,自动调整以适应容器的大小,且所有组件在网格中大小相等。这意味着较大的组件可能会挤压其他组件的空间。
- 填充顺序:组件按照添加到容器的顺序填充网格,从左到右,从上到下。
- 空白空间:网格布局不考虑组件间的空白空间,所有组件紧密相邻。
2. 案例分析
编写代码
例如,设置一个 3 行 2 列的网格,分别在每个网格中放置一个按钮。
使用 pack()
方法让容器自动调整到最适合其内容的大小。
public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame("TestGridLayout");
Button btn1 = new Button("btn1");
Button btn2 = new Button("btn2");
Button btn3 = new Button("btn3");
Button btn4 = new Button("btn4");
Button btn5 = new Button("btn5");
Button btn6 = new Button("btn6");
frame.setLayout(new GridLayout(3, 2));
frame.add(btn1);
frame.add(btn2);
frame.add(btn3);
frame.add(btn4);
frame.add(btn5);
frame.add(btn6);
// java 函数,网格自适应窗口布局
frame.pack();
frame.setVisible(true);
}
}
效果查看
窗口效果如图所示,六个按钮按从左到右,从上到下的次序添加到窗口中。
六、综合案例
1. 案例要求
接下来完成嵌套布局案例,具体要求如下:
- 将按钮摆放成如图所示模样;
- 设置关闭按钮监听事件。
2. 案例分析
- 对上述布局进行大致划分,首先可以上下结构——2 行 1 列的网格布局(p1 和 p3);
- p1 设置为边界布局(东西南北中)布局,中间嵌入 p2,p2 为 2 行 1 列的网格布局;
- p3 设置为边界布局(东西南北中)布局,中间嵌入 p4,p4 为 2 行 2 列的网格布局。
3. 代码实现
设置顶层窗口
设置顶层 Frame 窗口的一系列参数:可见性、宽高、初始位置、背景颜色,以及布局。
// 总 Frame
Frame frame = new Frame("布局嵌套");
frame.setSize(400, 300); // 设置宽高
frame.setLocation(300, 400); // 设置初始位置
frame.setBackground(Color.blue); // 设置背景颜色
frame.setVisible(true); // 设置可见
frame.setLayout(new GridLayout(2, 1)); // 设置网格布局
设置 4 个面板
设置 4 个面板 Panel,以完成布局的嵌套。
// 4 个面板
Panel p1 = new Panel(new BorderLayout()); // 边界布局(东西南北中)布局
Panel p2 = new Panel(new GridLayout(2, 1));
Panel p3 = new Panel(new BorderLayout());
Panel p4 = new Panel(new GridLayout(2, 2));
// p1 p3 添加到主窗口
frame.add(p1);
frame.add(p3);
完成上半部分
上半部分 p1 设置为边界布局(东西南北中)布局,中间嵌入 p2,p2 为 2 行 1 列的网格布局。
把 p2 添加到 p1 中。
// 上半部分
p1.add(new Button("East-1"), BorderLayout.EAST);
p1.add(new Button("West-1"), BorderLayout.WEST);
p2.add(new Button("p2-btn-1"));
p2.add(new Button("p2-btn-2"));
p1.add(p2, BorderLayout.CENTER); // 把 p2 添加到 p1 中
完成下半部分
下半部分 p3 设置为边界布局(东西南北中)布局,中间嵌入 p4,p2 为 2 行 2 列的网格布局。
把 p4 添加到 p3 中。
// 下半部分
p3.add(new Button("East-2"), BorderLayout.EAST);
p3.add(new Button("West-2"), BorderLayout.WEST);
for (int i = 0; i < 4; i++) {
p4.add(new Button("for" + i));
}
p3.add(p4, BorderLayout.CENTER); // 把 p4 添加到 p3 中
设置按钮监听
设置关闭按钮监听——点击关闭按钮时,关闭窗口。
// 设置按钮监听
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
七、总结
本文讲述了 GUI 编程种布局管理器的相关知识,以及 AWT 的 3 种布局管理器——流式布局、边界布局(东西南北中)、网格布局。搭配面板使用,可以实现布局嵌套功能。
要点整理
- Frame 是顶层窗口;
- Panel 无法单独显示,必须添加到某个容器中;
- 3 种布局管理器:流式布局、边界布局(东西南北中)、网格布局;
- 参数:大小、定位、布局、背景颜色、可见性、监听。
一些参考资料
狂神说 GUI 编程:https://www.bilibili.com/video/BV1DJ411B75F
IDEA 官网:https://www.jetbrains.com.cn/idea/
Java 开发手册:https://developer.aliyun.com/ebook/394
Java 8 帮助文档:https://docs.oracle.com/javase/8/docs/api/