Java Swing 学习笔记(1)-- 布局管理器
第一章:AWT布局管理器
文章目录
前言
如果要让我们的程序在不同的操作系统下,都有相同的使用体验,那么手动设置组件的位置和大小,无疑是一种灾难,因为有太多的组件,需要分别设置不同操作系统下的大小和位置。为了解决这个问题,java提供了LayoutManager布局管理器,可以根据运行平台来自动调整组件大小,程序员不用再手动设置组件的大小和位置了,只需要为容器选择合适的布局管理器即可。
一、FlowLayout
在FlowLayout布局管理器下,组件像流水一样向某方向流动(排列)遇到障碍(边界)就折回,重头开始排列。在默认情况下,FlowLayout布局管理器从左向右排列所有组件,遇到边界就会折回下一行重新开始。
构造方法 | 方法功能 |
---|---|
FlowLayout() | 使用默认的对其方式及默认的垂直间距、水平间距创建FlowLayout布局管理器。 |
FlowLayout(int align) | 使用指定的对齐方式及默认的垂直间距、水平间距创建FlowLayout布局管理器。 |
FlowLayout(int align, int hgap, int vgap) | 使用指定的对齐方式及指定的垂直间距、水平间距创建FlowLayout布局管理器。 |
FlowLayout中组件的排列方向(从左向右、从右向左、从中间向两边等),该参数应该使用FlowLayout类的静态常量: FlowLayout.LEFT、FlowLayout.CENTER、FlowLayout.RIGHT,默认是左对齐。
FlowLayout中组件中间间距通过整数设置,单位是像素,默认是5个像素。
1.FlowLayout 用法及示例
代码如下(示例):
public static void main(String[] args) {
Frame frame = new Frame("这里测试FlowLayout");
//1. 通过setLayout方法设置容器的布局管理器
frame.setLayout(new FlowLayout(FlowLayout(FlowLayout.LEFT,20,20));
//2. 添加多个按钮到frame中
for(int i = 1; i <= 100; i++){
frame.add(new Button("按钮"+i));
}
//3. 设置最佳大小,pack方法
frame.pack();
frame.setVisible(true);
}
二、BorderLayout
BorderLayout将容器分为EAST、SOUTH、WEST、NORTH、CENTER五个区域,普通组件可以被放置这5个区域任意一个中。BorderLayout布局管理器的布局示意图如图所示。
当改变使用BorderLayout的容器大小时, NORTH、SOUTH和CENTER区域水平调整,而EAST、WEST、和CENTER区域垂直调整。使用BorderLayout有如下两个注意点:
- 当向使用BorderLayout布局管理器的容器中添加组件时,需要指定要添加到哪个区域中。如果没有指定添加到哪个区域中,则默认添加到中间区域中。
- 如果向同一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件。
1.BorderLayout 用法及示例
代码如下(示例):
public static void main(String[] args) {
Frame frame = new Frame("这里测试BorderLayout");
//1. 通过setLayout方法设置容器的布局管理器
frame.setLayout(new BorderLayout(30, 10));
//2. 添加多个按钮到frame中
frame.add(new Button("北侧按钮"), BorderLayout.NORTH);
frame.add(new Button("南侧按钮"), BorderLayout.SOUTH);
frame.add(new Button("东侧按钮"), BorderLayout.EAST);
frame.add(new Button("西侧按钮"), BorderLayout.WEST);
frame.add(new Button("中间按钮"), BorderLayout.CENTER);
//3. 设置最佳大小,pack方法
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
效果图如下:
2.BorderLayout 不设置某个区域
代码如下(示例):
public static void main(String[] args) {
Frame frame = new Frame("这里测试BorderLayout");
//1. 通过setLayout方法设置容器的布局管理器
frame.setLayout(new BorderLayout(30, 10));
//2. 添加多个按钮到frame中
frame.add(new Button("北侧按钮"), BorderLayout.NORTH);
frame.add(new Button("南侧按钮"), BorderLayout.SOUTH);
Panel p = new Panel();
p.add(new Button("中间按钮"));
p.add(new TextField("测试文本框"));
frame.add(p);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//3. 设置最佳大小,pack方法
frame.pack();
frame.setVisible(true);
}
效果图如下:
小细节: 如果不往某个区域放入组件,那么该区域不会空白出来,而是会被其他区域占用。
三、GridLayout
GridLayout布局管理器将容器分割成纵横分割的网格,每个网格所占的区域大小相同。当向使用GridLayout布局管理器的容器中添加组件时,默认从左向右,从上向下依次添加到每个网格中。与FlowLayout不同的是,放置在GridLayout布局管理器中的各组件的大小由组件所处的区域决定(每个组件将自动占满整个区域)。
构造方法 | 方法功能 |
---|---|
GridLayout(int rows, int cols) | 采用指定的行数、列数,及默认的横向间距、纵向间距将容器分割成多个网格 |
GridLayout(int rows, int cols, int hgap, int vgap) | 采用指定的行数、列数,以及指定的横向间距、纵向间距将容器分割成多个网格。 |
案例:
使用Frame+Panel, 配合FlowLayout和GridLayout完成一个计算器效果。
1.GridLayout 用法及示例
代码如下(示例):
public static void main(String[] args) {
Frame frame = new Frame("这里测试GridLayout ");
//1. 通过setLayout方法设置容器的布局管理器
frame.setLayout(new BorderLayout(30, 10));
frame.add(new TextField(), BorderLayout.NORTH);
Panel panel = new Panel();
panel.setLayout(new GridLayout(3, 5, 5, 5));
for(int i = 0; i < 10; i++) {
panel.add(new Button(i+""));
}
panel.add(new Button("+"));
panel.add(new Button("-"));
panel.add(new Button("*"));
panel.add(new Button("/"));
panel.add(new Button("."));
frame.add(panel);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
四、GridBagLayout
GridBagLayout 布局管理器的功能最强大,但也最复杂,与GridLayout布局管理器不同的是,在GridBagLayout布局管理器中,一个组件可以跨越一个或多个网格,并可以设置各网格的大小互不相同,从而增加了布局的灵活性。当窗口的大小发生变化时,GridBagLayout布局管理器也可以准确地控制窗口各部分的拉伸。
由于在GridBagLayout布局中,每个组件可以占用多个网格,此时,我们往容器中添加组件的时候,就需要具体的控制每个组件占用多少个网格,java提供的GridBagConstants类,与特定的组件绑定,可以完成具体大小和跨越性的设置。
GridBagLayout不推荐使用,因为Swing 有更强大的布局管理器来完成相同的事情。
五、CardLayout
CardLayout布局管理器以时间而非空间来管理它里面的组件,它将加入容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的那个Component才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌才可见。
方法名称 | 方法功能 |
---|---|
CardLayout() | 创建默认的CardLayout布局管理器 |
CardLayout(int hgap, int vgap) | 通过指定卡片与容器左右边界的间距(hgap)、上下边界(vgap)的间距来创建CardLayout布局管理器 |
first(Container target) | 显示target容器中的第一张卡片 |
last(Container targe) | 显示target容器中的最后一张卡片 |
previous(Container target) | 显示target容器中的前一张卡片 |
next(Container target) | 显示target容器中后一张卡片 |
show(Container target, String name) | 显示target容器中指定名字的卡片 |
案例:
使用Frame和Panel以及CardLayout完成下图中的效果,点击底部的按钮,切换卡片
1.CardLayout 用法及示例
代码如下(示例):
public static void main(String[] args) {
frame = new Frame("这里测试CardLayout");
frame.setLayout(new BorderLayout(30, 10));
Panel p1 = new Panel();
p1.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
Panel p2 = new Panel();
CardLayout cardLayout = new CardLayout();
p2.setLayout(cardLayout);
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
switch (actionCommand) {
case "上一张":
cardLayout.previous(p2);
break;
case "下一张":
cardLayout.next(p2);
break;
case "第一张":
cardLayout.first(p2);
break;
case "最后一张":
cardLayout.last(p2);
break;
case "第三张":
cardLayout.show(p2,"第三张");
break;
}
}
};
Button b1 = new Button("上一张");
Button b2 = new Button("下一张");
Button b3 = new Button("第一张");
Button b4 = new Button("最后一张");
Button b5 = new Button("第三张");
b1.addActionListener(listener);
b2.addActionListener(listener);
b3.addActionListener(listener);
b4.addActionListener(listener);
b5.addActionListener(listener);
p1.add(b1);
p1.add(b2);
p1.add(b3);
p1.add(b4);
p1.add(b5);
frame.add(p1, BorderLayout.SOUTH);
String[] names = {"第一张", "第二张", "第三张", "第四张", "第五张"};
for(int i = 0; i < names.length; i++) {
p2.add(names[i], new Button(names[i]));
}
frame.add(p2);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
效果图如下:
六、BoxLayout
为了简化开发,Swing引入了一个新的布局管理器:BoxLayout。BoxLayout可以在垂直和水平两个方向上摆放GUI组件,BoxLayout提供了如下一个简单的构造器:
方法名称 | 方法功能 |
---|---|
BoxLayout(Container target, int axis) | 指定创建基于target容器的BoxLayout布局管理器,该布局管理器李的组件按axis方向排列。其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)两个方向。 |
案例1:
使用Frame和BoxLayout完成下图效果:
1.BoxLayout 用法及示例
代码如下(示例):
public static void main(String[] args) {
frame = new Frame("这里测试BoxLayout");
Panel p1 = new Panel();
Button b1 = new Button("按钮1");
Button b2 = new Button("按钮1");
p1.add(b1);
p1.add(b2);
BoxLayout boxLayout = new BoxLayout(p1, BoxLayout.Y_AXIS);
p1.setLayout(boxLayout);
frame.add(p1);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
2.Box 容器的介绍
在java.swing包中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数情况下,使用Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成整体窗口布局。
方法名称 | 方法功能 |
---|---|
static Box createHorizontalBox() | 创建一个水平排列组件的Box容器。 |
static Box createVerticalBox() | 创建一个垂直排列组件的Box容器。 |
案例2:
使用Frame和Box,完成下图效果:
3.Box 用法及示例
代码如下(示例):
public static void main(String[] args) {
frame = new Frame("这里测试Box容器");
frame.setBounds(800, 400, 0, 0);
Box hbox = Box.createHorizontalBox();
hbox.add(new Button("水平按钮1"));
hbox.add(new Button("水平按钮2"));
Box vbox = Box.createVerticalBox();
vbox.add(new Button("垂直按钮1"));
vbox.add(new Button("垂直按钮2"));
frame.add(hbox, BorderLayout.NORTH);
frame.add(vbox);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
4.Box 间隔的介绍
通过之前的两个BoxLayout演示,我们会发现,被它管理的容器中的组件之间是没有间隔的,不是特别美观,但之前学习的几种布局,组件之间都会有一些间距,那使用BoxLayout如何给组件设置间距呢?
其实很简单,我们只需要在原有的组件需要间隔的地方,添加间隔即可,而每个间隔可以使一个组件,只不过该组件没有内容,仅仅起到一种分割的作用。
Box类中,提供了5个方便的静态方法来生成这些间隔组件:
方法名称 | 方法功能 |
---|---|
static Component createHorizontalGlue() | 创建一条水平Glue(可在两个方向上同时拉伸的间距) |
static Component createVerticalGlue() | 创建一条垂直Glue(可在两个方向上同时拉伸的间距) |
static Component createHorizontalStruct(int width) | 创建一条指定宽度(宽度固定了,不能拉伸)的水平Struct(可在垂直方向拉伸的间距) |
static Component createVerticalStrut(int height) | 创建一条指定高度(高度固定了,不能拉伸)的垂直Strut(可在水平方向拉伸的间距) |
5.Box 间隔用法及示例
代码如下(示例):
public static void main(String[] args) {
frame = new Frame("这里测试Box容器");
frame.setBounds(800, 400, 0, 0);
Box hbox = Box.createHorizontalBox();
hbox.add(new Button("水平按钮1"));
hbox.add(Box.createHorizontalGlue());
hbox.add(new Button("水平按钮2"));
hbox.add(Box.createHorizontalStrut(30));
hbox.add(new Button("水平按钮3"));
Box vbox = Box.createVerticalBox();
vbox.add(new Button("垂直按钮1"));
vbox.add(Box.createVerticalGlue());
vbox.add(new Button("垂直按钮2"));
vbox.add(Box.createVerticalStrut(30));
vbox.add(new Button("垂直按钮2"));
frame.add(hbox, BorderLayout.NORTH);
frame.add(vbox);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
总结
使用布局管理器能使程序在多个操作系统下体验一样,可以根据运行平台来自动调整组件大小,程序员不用再手动设置组件的大小和位置了,只需要为容器选择合适的布局管理器即可。