学习要点
- 关于AWT
- AWT容器
- 布局管理器
- AWT组件
- 事件处理
关于AWT
java.awt包与子包
|
AWT软件包 |
说明 |
|
import java.awt.*; |
基本组件使用工具 |
|
import java.awt.color.*; |
颜色空间 |
|
import java.awt.datatransfer.*; |
剪贴板和数据传输 |
|
import java.awt.dnd.*; |
拖放 |
|
import java.awt.event.*; |
事件类型和监听器 |
|
import java.awt.font.*; |
2D字体软件包 |
|
import java.awt.geom.*; |
2D API几何软件包 |
|
import java.awt.im.*; |
引入方法 |
|
import java.awt.image.*; |
图像处理工具包 |
|
import java.awt.print.*; |
支持打印工具包 |
java.awt包中的类体系结构

容器
容器的特点
- 用来承载其他组件,包含其他界面元素
- 按照一定的规则排列内含元素的位置
- 可以设定一个背景
- 有一定的位置
- 有一定的范围
AWT容器继承关系
- Container类是Component类的子类,继承了Component类的所有方法。
- Component类常用方法:
|
方法 |
方法说明 |
|
void setLocation(int x, int y) |
设置组件的位置 |
|
void setSize(int width, int height) |
设置组件的大小 |
|
void setBounds(int x, int y, int width, int height) |
移动组件并调整其大小 |
|
void setVisible(boolean b) |
设置组件的可见性 |
|
Dimension getSize() |
以 Dimension 对象的形式返回组件的大小 |
|
void add(PopupMenu popup) |
向组件添加指定的弹出菜单 |
|
Container getParent() |
获取组件的父级组件 |
- Container类常用方法:
|
方法 |
方法说明 |
|
void setLocation(int x, int y) |
设置组件的位置 |
|
void setSize(int width, int height) |
设置组件的大小 |
|
void setBounds(int x, int y, int width, int height) |
移动组件并调整其大小 |
|
void setVisible(boolean b) |
设置组件的可见性 |
|
Component add(Component comp) |
向容器中添加其他组件或者容器,返回被添加的组件 |
|
Component[] getComponents() |
返回该容器内的所有组件 |
- 主要容器类型:
- Panel:没有具体的图形表示,存放在其他容器中。
- Window:可独立存在的顶级窗口。
Window类
- Window类的继承关系

- Window类常用方法
|
方法 |
方法说明 |
|
void show() |
设置窗口可见 |
|
void dispose() |
关闭窗口释放资源 |
|
boolean isShowing() |
判断窗口是否是显示状态 |
|
void toFront() |
将窗口放置在其他窗口之前 |
Frame类
- Frame类的继承关系

- Frame类常用构造方法
|
方法 |
方法说明 |
|
Frame() |
创建一个不含标题的标准窗口 |
|
Frame(String title) |
创建一个包含标题的标准窗口 |
注:Frame默认使用BorderLayout布局管理器。
- 示例代码
package com.etc.container;
import java.awt.Frame;
public class FrameTest {
public static void main(String[] args) {
Frame frame = new Frame("Hello AWT");
frame.setBounds(50, 50, 300, 250);// 设置位置
frame.setVisible(true);// 设置窗口的显示状体
}
}
运行结果:
Windows7风格的窗体。
(在控制台面板中停止程序运行。)

Panel类
- Panel特点
- 作为其他组件的容器,为放置组件提供控件。
- 不能单独存在,必须放置到其他容器中。
- 默认使用FlowLayout作为其布局管理器。
- 示例代码
package com.etc.container;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextField;
public class PanelTest {
public static void main(String[] args) {
Frame frame = new Frame("Panel测试窗口");
Panel panel = new Panel();// 创建一个面板容器
// 向面板容器添加两个组件
panel.add(new TextField(20));
panel.add(new Button("click me"));
// 将面板容器添加到Frame窗口中
frame.add(panel);
// 设置窗口的大小和位置
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);// 设置窗口居中
// 设置窗口的可见性
frame.setVisible(true);
}
}
运行结果:

ScrollPane类
- ScrollPane特点
- 作为其他组件的容器,当组件过大时,ScrollPane会自动产生滚动条。
- 不能单独存在,必须放在其他容器中。
- 默认使用BorderLayout作为布局管理器。
- 不允许修改ScrollPane的布局管理器。
- 示例代码
package com.etc.container;
import java.awt.Button;
import java.awt.Frame;
import java.awt.ScrollPane;
import java.awt.TextField;
public class ScrollPaneTest {
public static void main(String[] args) {
Frame frame = new Frame("ScrollPane测试窗口");
//创建一个总是具有滚动条的滚动面板容器
ScrollPane sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
// 向滚动条面板容器添加两个组件
sp.add(new TextField(20));
sp.add(new Button("click me"));
// 将滚动条面板容器添加到Frame窗口中
frame.add(sp);
// 设置窗口的大小和位置
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);// 设置窗口居中
// 设置窗口的可见性
frame.setVisible(true);
}
}
运行效果如图所示:

说明:只显示按钮未显示标签,主要原因是使用了BorderLayout布局管理器导致,该布局管理器导致只有一个组件被显示出来。
布局管理器
概念
- 为了使生成的图形用户界面具有良好的平台无关性,Java提供了布局管理器来管理组件在容器中的布局,而不是直接设置组件的位置和大小。
- 所有AWT容器都有默认的布局管理器。通过容器对象的setLayout(LayoutManager layoutManager)方法来设置。
- AWT提供了五个常用布局管理器:FlowLayout、BorderLayout、GridLayout、GridBagLayout、CardLayout。
- Swing另外提供了一个布局管理器:BoxLayout
FlowLayout布局管理器
- 定义
默认情况下,FlowLayout布局管理器从左到右排列所有组件,遇到障碍(边界)就会折回到下一行重新开始。
- 常用构造方法
|
构造方法 |
说明 |
|
FlowLayout() |
使用默认对齐方式和默认的垂直间距、水平间距创建FlowLayout布局管理器。 |
|
FlowLayout(int align) |
使用指定对齐方式和默认的垂直间距、水平间距创建FlowLayout布局管理器。 |
|
FlowLayout(int align, int hgap,int vgap) |
使用指定对齐方式和指定的垂直间距、水平间距创建FlowLayout布局管理器。 |
- 备注:hgap表示水平间距;vgap表示垂直间距。参数值为整数。
- 备注:align表示组件在容器中的对齐方式,其参数值为FlowLayout类的静态常量——FlowLayout.LEFT,FlowLayout.CENTER,FlowLayout.RIGHT。
- 备注:Panel默认使用FlowLayout布局管理器。
- 示例代码
package com.etc.layout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
/** 流式布局管理器 */
public class FlowLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("FlowLayout Test");
// 设置Frame容器为FlowLay布局(Frame默认的布局管理器为BorderLayout)
frame.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 5));
//向窗口添加10个按钮
for(int i=0;i<10;i++){
frame.add(new Button("按钮"+i));
}
//设置Frame窗口为最佳大小(自动调整)
//frame.pack();
//手动设置窗口大小
frame.setSize(300, 150);
frame.setLocationRelativeTo(null);//居中
//显示窗口
frame.setVisible(true);
}
}
运行结果:

BorderLayout布局管理器
- 定义
BorderLayout将容器分为EAST、SOUTH、WEST、NORTH、CENTER五个区域。如下图所示:

可以把组件放在这五个位置的任意一个,如果未指定位置,则缺省的位置是CENTER。
NORTH、SOUTH位置控件各占据一行,控件宽度将自动布满整行。EAST、WEST和CENTER三个位置一起占据一行。
若EAST、WEST、SOUTH、NORTH位置无控件,则中间控件将自动布满整个容器;若EAST、WEST、SOUTH、NORTH位置中无论哪个位置没有控件,则CENTER位置控件将自动占据没有控件的位置。
它是Frame、Dialog、ScrollPane的缺省布局。
- 常用构造方法
|
构造方法 |
说明 |
|
BorderLayout() |
使用默认水平和垂直间距创建布局管理器。 |
|
BorderLayout(int hgap,int vgap) |
使用指定水平和垂直间距创建布局管理器。 |
- 备注:设置组件位置,使用BorderLayout的静态常量——EAST、SOUTH、WEST、NORTH、CENTER。
- 备注:BorderLayout最多只能放置5个组件,但是可以通过在相应位置添加Panel组件的方式添加多于5个组件。
- 示例代码
package com.etc.layout;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
/**边界布局管理器测试*/
public class BorderLayoutTest {
public static void main(String[] args) {
Frame frame = new Frame("BorderLayout Test");
// 设置Frame容器使用BorderLayout布局管理器
frame.setLayout(new BorderLayout(30, 5));
frame.add(new Button("SOUTH"), BorderLayout.SOUTH);
frame.add(new Button("NORTH"), BorderLayout.NORTH);
frame.add(new Button("CENTER"));//自动添加到CENTER
//中间位置田间panel
// Panel panel = new Panel();
// panel.add(new Button("click me"));
// panel.add(new TextField(15));
// frame.add(panel);
frame.add(new Button("EAST"), BorderLayout.EAST);
frame.add(new Button("WEST"), BorderLayout.WEST);
// 自动设置窗口大小
frame.pack();
// 显示窗口
frame.setVisible(true);
}
}
运行结果:

GridLayout布局管理器
- 定义
GridLayout布局管理器将容器分割成纵横线分隔的网格,每个网格所占的区域大小相同。当向其中添加组件时,默认从左到右、从上到下依次添加到每个单元格中。
和FlowLayout布局不同的地方:GridLayout布局管理器中的组件的大小由组件所处的区域来决定,每个组件自动占满整个区域。
- 常用构造方法
|
构造方法 |
说明 |
|
GridLayout(int rows,int cols) |
指定行数和列数,网格间距默认。 |
|
GridLayout(int rows,int cols,int hgap,int vgap) |
指定行数列数,并指定网格间距。 |
- 示例代码
/**计算器窗口开发*/
package com.etc.layout;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.TextField;
/** 计算器 */
public class GridLayoutTest {
public static void main(String[] args) {
Frame f = new Frame("计算器");
Panel p1 = new Panel();
// Panel默认采用流式布局
p1.add(new TextField(30));
// 计算器文本框放在窗体上面
f.add(p1, BorderLayout.NORTH);
// 按钮面板设置
Panel p2 = new Panel();
// 设置Panel使用GridLayout网格布局
p2.setLayout(new GridLayout(3, 5, 4, 4));
String[] name = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"+", "-", "*", "/", "=" };
// 向p2中添加15个按钮
for (int i = 0; i < name.length; i++) {
p2.add(new Button(name[i]));
}
// 默认将p2添加到窗口f的中间
// f.add(p2, BorderLayout.CENTER);
f.add(p2);
// 自动设置窗体大小
f.pack();
// 显示窗口
f.setVisible(true);
}
}
运行结果:

GridBagLayout布局管理器
- 定义
GridBagLayout也是网格布局管理器,和GridLayout不同的是,GridBagLayout可以设置一个组件跨越多个网格,并可以设置各个网格大小互不相同。
通过GridBagConstraints对象与特定的GUI组件关联,控制该组件的大小和跨越性。
- GridBagLayout使用步骤
1.创建GridBagLayout布局管理器,并指定容器使用该布局管理器。
GridBagLayout gb=new GridBagLayout(); container.setLayout(gb);
2.创建GridBagConstraints对象,并设置该对象相关属性(用于设置受该对象控制的GUI组件的大小和跨越性等)。
GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx=2;//受控于gbc组件的网格横向索引 gbc.gridy=1;//纵向索引 gbc.gridwidth=2;//跨越网格2列 gbc.gridheight=1;//跨越网格1行
3.调用GridBagLayout对象的方法来建立建GridBagConstraints对象和受控组件之间的关联。
gb.setConstraints(c,gbc);//设置组件c受gbc对象控制
4.添加组件,和普通布局管理器添加组件方法一样。
container.add(c);
5.如果要向一个容器中添加多个GUI组件,则重复2-4步骤。其中GridBagConstraints可以重复使用,每次添加只要改变其属性即可。
- GridBagConstraints类常用属性
|
属性 |
说明 |
|
gridx |
指定包含组件的显示区域的边开始的单元格,其中行的第一个单元格为 gridx=0。 |
|
gridy |
指定位于组件显示区域的顶部的单元格,其中最上边的单元格为 gridy=0。 |
|
gridwidth |
组件横向跨越单元个数和纵向跨越单元格数。 |
|
gridheight |
|
|
fill |
当组件的显示区域大于它所请求的显示区域的大小时使用此字段。它可以确定是否调整组件大小,以及在需要的时候如何进行调整。 NONE:不调整组件大小。 HORIZONTAL:加宽组件,使它在水平方向上填满其显示区域,但是不改变高度。 VERTICAL:加高组件,使它在垂直方向上填满其显示区域,但是不改变宽度。 BOTH:使组件完全填满其显示区域。 默认值为 NONE。 |
|
ipadx |
此字段指定组件的内部填充,即给组件的最小宽度添加多大的空间。组件的宽度至少为其最小宽度加上 ipadx *2像素。 |
|
ipady |
此字段指定组件的内部填充,即给组件的最小高度添加多大的空间。组件的高度至少为其最小高度加上 ipady *2像素。 |
|
insets |
此字段指定组件的外部填充,即组件与其显示区域边缘之间间距的最小量。 默认值为 new Insets(0, 0, 0, 0)。 |
|
anchor |
当组件小于其显示区域时使用此字段。它可以确定在显示区域中放置组件的位置。 |
|
weightx |
设置受控对象控制的GUI组件占据多余控件的水平、垂直增加比例(也称为权重),默认值都为0。例如:某个容器水平线上有三个GUI组件,他们的水平增加比例分别是1、2、3,当容器宽度增加60像素时,则第一个组件宽度增加10像素,第二个组件增加20个像素,第三个组件宽度增加30像素。 |
|
weighty |
备注:如果希望某个组件随着容器的增大而增大,则需要同时设置控制该组件GridBagConstraints对象的fill属性和weightx、weighty属性。
- 示例代码
package com.etc.layout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
/** 网格包布局管理器 */
public class GridBagLayoutTest {
private Frame f = new Frame("网格包布局管理器");
private GridBagLayout gb = new GridBagLayout();
private GridBagConstraints gbc = new GridBagConstraints();
private Button[] bs = new Button[10];
/** 初始化组件 */
public void init() {
f.setLayout(gb);
// 初始化按钮数组
for (int i = 0; i < bs.length; i++) {
bs[i] = new Button("按钮" + i);
}
// 设置所有组件都可以在横向和纵向上扩大
gbc.fill = GridBagConstraints.BOTH;
/** 第一行:4个按钮。按钮可以在横向上扩大 */
gbc.weightx = 1;
addButton(bs[0]);
addButton(bs[1]);
addButton(bs[2]);
// 设置第四个按钮为横向最后一个组件
gbc.gridwidth = GridBagConstraints.REMAINDER;
addButton(bs[3]);
/** 第二行:一个按钮。横向上禁止扩大(实际受第一行影响会扩大) */
gbc.weightx = 0;
addButton(bs[4]);
/**第三行:两个按钮。按钮跨列。*/
gbc.gridwidth=2;
addButton(bs[5]);
gbc.gridwidth = GridBagConstraints.REMAINDER;
addButton(bs[6]);
/**第四行:三个按钮,第一个跨2行*/
gbc.gridwidth=1;
gbc.gridheight=2;
gbc.weighty=1;//纵向扩大
addButton(bs[7]);
gbc.weighty=0;
gbc.gridheight=1;
gbc.gridwidth=GridBagConstraints.REMAINDER;
addButton(bs[8]);
addButton(bs[9]);
// 窗体属性设置
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
/** 添加按钮方法 */
private void addButton(Button button) {
gb.setConstraints(button, gbc);
f.add(button);
}
/** 测试方法 */
public static void main(String[] args) {
new GridBagLayoutTest().init();
}
}
CardLayout布局管理器
- 定义
CardLayout布局管理器以时间来管理容器中的组件,每次只有最上面一层的组件是可见的。
- 常用构造方法
|
构造方法 |
说明 |
|
CardLayout() |
创建默认CardLayout布局管理器。 |
|
CardLayout(int hgap,int vgap) |
指定卡片与容器的左右边界的间距(hgap),上下边界(vgap)来创建CardLayout布局管理器。 |
- 常用方法
|
构造方法 |
说 明 |
|
void first(Container) |
显示第一个加入到CardLayout的卡片。 |
|
void last(Container) |
显示最后一个加入到CardLayout的卡片。 |
|
void next(Container) |
显示当前组件的下一个卡片。 |
|
void previous(Container) |
显示当前组件的前一个卡片。 |
|
show(Container,String) |
在卡片父级容器中显示指定名字的卡片。 |
- 示例代码
package com.etc.layout;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** 卡片布局管理器 */
public class CardLayoutTest {
private Frame f = new Frame("卡片布局管理器");
String[] names = { "第一张", "第二张", "第三张", "第四张", "第五张" };
Panel pCard = new Panel();//卡片面板
public void init() {
final CardLayout c = new CardLayout();
pCard.setLayout(c);
for (int i = 0; i < names.length; i++) {
//面板容器中放了五张卡片,每张卡片上一个按钮
pCard.add(names[i], new Button(names[i]));// 按钮名称
}
// java8支持lambda表达式ActionListener listener=e->{}
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case "上一张":
c.previous(pCard);
break;
case "下一张":
c.next(pCard);
break;
case "第一张":
c.first(pCard);
break;
case "最后一张":
c.last(pCard);
break;
case "第三张":
c.show(pCard, "第三张");
break;
}
}
};
/**按钮面板处理*/
Panel pBtn= new Panel();
Button previous=new Button("上一张");
previous.addActionListener(listener);
Button next=new Button("下一张");
next.addActionListener(listener);
Button first=new Button("第一张");
first.addActionListener(listener);
Button last = new Button("最后一张");
last.addActionListener(listener);
Button third=new Button("第三张");
third.addActionListener(listener);
pBtn.add(previous);
pBtn.add(next);
pBtn.add(first);
pBtn.add(last);
pBtn.add(third);
f.add(pCard,BorderLayout.CENTER);//卡片面板
f.add(pBtn,BorderLayout.SOUTH);//按钮面板
//f.pack();
f.setSize(500, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new CardLayoutTest().init();
}
}
运行结果:

绝对定位布局管理器
- 定义
可以在容器中随意设置组件的位置。
- 使用步骤
- 将容器布局管理器设置为null:setLayout(null)。
- 设置组件的大小,位置。
- 向容器中添加组件。
- 示例代码
package com.etc.layout;
import java.awt.Button;
import java.awt.Frame;
/** 绝对定位 */
public class AbsLayoutTest {
Frame f = new Frame("绝对定位");
Button btn1 = new Button("第一个按钮");
Button btn2 = new Button("第二个按钮");
public void init() {
f.setLayout(null);
btn1.setBounds(20, 30, 90, 28);
btn2.setBounds(50, 45, 120, 35);
f.add(btn1);
f.add(btn2);
f.setBounds(50, 50, 200, 100);
f.setVisible(true);
}
public static void main(String[] args) {
new AbsLayoutTest().init();
}
}
运行效果:

BoxLayout布局管理器
- 定义
GridBagLayout布局管理器功能强大,但是太复杂,所以swing引入了一个新的布局管理器BoxLayout。BoxLayout保留了GridBagLayout的优点,并且应用变得简单。
BoxLayout可以在垂直和水平方向上摆放GUI组件。
- 常用构造方法
|
构造方法 |
说明 |
|
BoxLayout(Container c,int axis) |
指定c容器为BoxLayout布局管理器,该布局管理器中的组件按axis方向排列。 其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)两个方向。 |
- 示例代码
package com.etc.layout;
import java.awt.Button;
import java.awt.Frame;
import javax.swing.BoxLayout;
/** 盒式布局管理器 */
public class BoxLayoutTest {
private Frame f = new Frame("盒式布局管理器 ");
public void init() {
// 垂直排列
f.setLayout(new BoxLayout(f, BoxLayout.Y_AXIS));
f.add(new Button("按钮1"));
f.add(new Button("按钮2"));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new BoxLayoutTest().init();
}
}
运行效果:

Box容器
概念
BoxLayout通常和Box容器结合使用,Box是一种特殊容器,默认使用BoxLayout布局管理器。
Box类提供了两个静态方法来创建Box对象。
|
方法 |
说明 |
|
createHorizontalBox() |
创建一个水平排列组件的Box容器。 |
|
createVerticalBox() |
创建一个垂直排列组件的Box容器。 |
Box布局:把GUI组件添加到Box容器中,Box容器再添加到其他容器中。
示例代码
package com.etc.container;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import javax.swing.Box;
/** Box容器和BoxLayout布局管理器 */
public class BoxTest {
private Frame f = new Frame("Box测试");
// 定义水平摆放组件的Box
private Box horizontal = Box.createHorizontalBox();
// 定义垂直摆放组件的Box
private Box vertical = Box.createVerticalBox();
public void init() {
horizontal.add(new Button("水平按钮1"));
horizontal.add(new Button("水平按钮2"));
vertical.add(new Button("垂直按钮1"));
vertical.add(new Button("垂直按钮2"));
f.add(horizontal, BorderLayout.NORTH);
f.add(vertical, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new BoxTest().init();
}
}
运行效果:

组件间距的设定
BoxLayout没有提供设置间距的构造方法或方法,它采用Glue、Strut和RigidArea来控制组件建的距离。
Glue(橡胶):可以在横向、纵向两个方向上同时拉伸的空白组件(间距)。
Strut(支架):可以在横向、纵向任意一个方向上拉伸的空白组件。
RigidArea(刚性区域):不可拉伸的空白组件。
Box创建组件间距对象方法
|
方法 |
说明 |
|
createHorizontalGlue() |
创建一条水平Glue |
|
createVerticalGlue() |
创建一条垂直Glue |
|
createHorizontalStrut(int width) |
创建一条指定宽度的水平Strut |
|
createVerticalStrut(int height) |
创建一条指定高度的垂直Strut |
|
createRigidArea(Demension d) |
创建指定高度、宽度的RigidArea |
示例代码
package com.etc.layout;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import javax.swing.Box;
/** Box容器中组件间距设定 */
public class BoxSpaceTest {
private Frame f = new Frame(" Box容器中组件间距设定");
// 定义水平摆放组件的Box
private Box horizontal = Box.createHorizontalBox();
// 定义垂直摆放组件的Box
private Box vertical = Box.createVerticalBox();
public void init() {
horizontal.add(new Button("水平按钮1"));
horizontal.add(Box.createHorizontalGlue());
horizontal.add(new Button("水平按钮2"));
// 水平方向不可拉伸间距,其宽度为10px
horizontal.add(Box.createHorizontalStrut(10));
horizontal.add(new Button("水平按钮3"));
vertical.add(new Button("垂直按钮1"));
vertical.add(Box.createVerticalGlue());
vertical.add(new Button("垂直按钮2"));
// 垂直方向不可拉伸间距,其高度为10px
vertical.add(Box.createVerticalStrut(10));
vertical.add(new Button("垂直按钮3"));
f.add(horizontal, BorderLayout.NORTH);
f.add(vertical);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new BoxSpaceTest().init();
}
}
运行效果:

AWT基本组件
- Button:按钮,可接受单击操作。
- Canvas:用于绘图的画布。
- Checkbox:复选框组件(也可变成单选框组件)。
- CheckboxGroup:用于将多个Checkbox组件组合成一组,一组Checkbox组件将只有一个可以被选中,即全部变成单选框组件。
- Choice:下拉式选择框组件。
- Frame:窗口,在GUI程序里通过该类创建窗口。
- Label:标签类,用于放置提示性文本。
- List:列表框组件,可以添加多项条目。
- Panel:不能单独存在基本容器类,必须放到其他容器中。.
- Scrollbar:滑动条组件。如果需要用户输入位于某个范围的值,就可以使用滑动条组件。如调色板中设置RGB的三个值所用的滑动条。当创建一个滑动条时,必须指定它的方向、初始值、滑块的大小、最小值和最大值。
- ScrollPane:带水平及垂直滚动条的容器组件。
- TextArea:多行文本域。
- TextField:单行文本框。
这些AWT组件的用法比较简单,可以查API文档来获取它们各自的构造器、方法等详细信息,下面例子程序示范了它们的基本用法。
对话框
对话框
- 特点
对话框通常依赖于其他窗口,即通常有一个Parent窗口。
对话框有非模式(non-modal)和模式(modal)两种。
主程序需要从对话框接收参数,建议对话框设成模式对话框,这样可以阻塞主程序运行。
- 对话框构造函数参数
owner:指定该对话框所依赖的窗口,可以是窗口,也可以是对话框。
title:指定该对话框的窗口标题。
modal:指定该对话框是否是模式的,可以是true或者false。
- 示例代码
package com.etc.container;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** 对话框 */
public class DialogTest {
private Frame f = new Frame("对话框");
Dialog dl1 = new Dialog(f, "模式对话框", true);
Dialog dl2 = new Dialog(f, "非模式对话框", false);
Button btn1 = new Button("打开模式对话框");
Button btn2 = new Button("打开非模式对话框");
public void init() {
dl1.setBounds(20, 30, 300, 400);
dl2.setBounds(20, 30, 300, 400);
btn1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dl1.setVisible(true);
}
});
btn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dl2.setVisible(true);
}
});
f.add(btn1);
f.add(btn2, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new DialogTest().init();
}
}
文件对话框
- 特点
不能指定是模式对话框或者非模式对话框,因为FlieDialog依赖于运行平台的实现,如果平台是模式对话框,则FileDialog也是模式的,否则就是非模式的。
- 构造参数
parent:文件对话框所属父窗口。
title:对话框标题。
mode:指定该窗口用于打开文件或保存文件,参数值:FileDialog.LOAD,FileDialog.SAVE。
- 常用方法
|
方法 |
说明 |
|
getDirectory() |
获取被打开(保存)的文件路径。 |
|
getFile() |
获取被打开(保存)的文件名。 |
- 示例代码
package com.etc.container;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** 文件对话框 */
public class FileDialogTest {
Frame f = new Frame("文件对话框");
FileDialog fdl1 = new FileDialog(f, "选择需要打开文件", FileDialog.LOAD);
FileDialog fdl2 = new FileDialog(f, "选择保存的文件路径", FileDialog.SAVE);
Button btn1 = new Button("打开文件");
Button btn2 = new Button("保存文件");
public void init() {
btn1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fdl1.setVisible(true);
//输出打开文件的路径和文件名
System.out.println(fdl1.getDirectory()+fdl1.getFile());
}
});
btn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fdl2.setVisible(true);
//输出保存文件的路径和文件名
System.out.println(fdl2.getDirectory()+fdl2.getFile());
}
});
f.add(btn1);
f.add(btn2,BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new FileDialogTest().init();
}
}
事件处理
事件模型和流程
- 事件处理主要涉及三个对象
EventSource(事件源):事件发生的场所,通常指各个组件。
Event(事件):封装了组件上发生的用户操作,封装成Event对象。
Event Listener(事件监听器):负责监听事件源所发生的事件,并对各种事件做出响应处理。
Event Handler(事件处理器):事件监听器中的方法。
- 事件处理流程
- 示例代码
package com.etc.event;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** 事件处理模型 */
public class EventTest {
Frame f = new Frame("事件模型测试");
Button btn = new Button("点击我");
TextField tf = new TextField(30);
/** 定义事件监听器类 */
class btnListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("用户点击了按钮");
tf.setText("Hello AWT");
}
}
/**初始化*/
public void init() {
//注册事件监听器
btn.addActionListener(new btnListener());
f.add(tf);
f.add(btn, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
new EventTest().init();
}
}
- 事件处理步骤
- 实现事件监听器类,实现XxxListener接口。
- 创建组件,创建时间监听器对象。
- 调用addXxxListener()方法将事件监听器对象注册给组件。
AWT事件类的继承结构图

可以通过对AWTEvent或者AWTEvent子类直接继承编写程序中自定义事件类。
AWT事件类型
- 语义事件
事件指明用户正在做什么。有4个语义事件:
- ActionEvent:按下按钮、双击列表项或选中一个菜单项时会生成此事件。
- AdjustmentEvent:操纵滚动条时会生成此事件。
- ItemEvent:单击复选框或列表项,或者一个选择框或可选菜单选择或取消时会生成此事件。
- TextEvent:文本改变时会生成此事件。
- 低级事件
语义事件的基础。有6个低级事件:
- ComponentEvent:当一个组件移动、隐藏、调整大小或成为可见时会生成此事件。
- KeyEvent:接收到键盘输入时会生成此事件。
- MouseEvent:移动、拖动、单击、按下或释放鼠标,或者当鼠标进入或退出一个组件时会生成此事件。
- FocusEvent:组件获取或失去焦点时会生成此事件。
- WindowEvent:当一个窗口激活、关闭、正在关闭、恢复、最小化、打开或退出时会生成此事件。
- ContainerEvent:将组件添加到容器或从容器中移除时会生成此事件。
监听器接口
常用Java事件类、处理该事件的接口及接口中的方法:
|
事件类 |
监听器接口 |
处理器 |
触发时机 |
|
ActionEvent
|
ActionListener |
actionPerformed(ActionEvent e) |
单击按钮、选择菜单项或在文本框中按回车时 |
|
AdjustmentEvent |
AdjustmentListener |
adjustmentValueChanged(AdjustmentEvent e) |
当改变滚动条滑块位置时 |
|
ComponentEvent
|
ComponentListener |
componentMoved(ComponentEvent e) |
组件移动时 |
|
componentHidden(ComponentEvent e) |
组件隐藏时 |
||
|
componentResized(ComponentEvent e) |
组件缩放时 |
||
|
componentShown(ComponentEvent e) |
组件显示时 |
||
|
ContainerEvent
|
ContainerListener |
componentAdded(ContainerEvent e) |
添加组件时 |
|
componentRemoved(ContainerEvent e) |
移除组件时 |
||
|
FocusEvent
|
FocusListener |
focusGained(FocusEvent e) |
组件获得焦点时 |
|
focusLost(FocusEvent e) |
组件失去焦点时 |
||
|
ItemEvent
|
ItemListener |
itemStateChanged(ItemEvent e)
|
选择复选框、选项框、单击列表框、选中带复选框菜单时 |
|
KeyEvent
|
KeyListener |
keyPressed(KeyEvent e) |
键按下时 |
|
keyReleased(KeyEvent e) |
键释放时 |
||
|
keyTyped(KeyEvent e) |
击键时 |
||
|
MouseEvent |
MouseListener |
mouseClicked(MouseEvent e) |
单击鼠标时 |
|
mouseEntered(MouseEvent e) |
鼠标进入时 |
||
|
mouseExited(MouseEvent e) |
鼠标离开时 |
||
|
mousePressed(MouseEvent e) |
鼠标键按下时 |
||
|
mouseReleased(MouseEvent e) |
鼠标键释放时 |
||
|
MouseMotionListener |
mouseDragged(MouseEvent e) |
鼠标拖放时 |
|
|
mouseMoved(MouseEvent e) |
鼠标移动时 |
||
|
TextEvent |
TextListener |
textValueChanged(TextEvent e) |
文本框、多行文本框内容修改时 |
|
WindowEvent
|
WindowListener |
windowOpened(WindowEvent e) |
窗口打开后 |
|
windowClosed(WindowEvent e) |
窗口关闭后 |
||
|
windowClosing(WindowEvent e) |
窗口关闭时 |
||
|
windowActivated(WindowEvent e) |
窗口激活时 |
||
|
windowDeactivated(WindowEvent e) |
窗口失去焦点时 |
||
|
windowIconified(WindowEvent e) |
窗口最小化时 |
||
|
windowDeiconified(WindowEvent e) |
最小化窗口还原时 |
每个事件类都提供下面常用的方法:
① public int getID(),返回事件的类型;
② public Object getSource(),返回事件源的引用。
当多个事件源触发的事件由一个共同的监听器处理时,我们可以通过getSource方法判断当前的事件源是哪一个组件。
适配器
Java为具有多个方法的监听器接口提供适配器类。
| 适配器类 | 事件监听器接口 |
| ComponentAdapter | ComponentListener |
| ContainerAdapter | ContainerListener |
| FocusAdapter | FocusListener |
| KeyAdapter | KeyListener |
| MouseAdapter | MouseListener |
| MouseMotionAdapter | MouseMotionListener |
| WindowAdapter | WindowListener |
适配器的实质是为事件监听接口提供一种更加机动灵活的语法实现形式,方便我们有选择性、有针对性地实现感兴趣的方法,而不必将所有方法全部重写。
适配器中的方法都是对应监听器接口方法的空方法实现。
示例代码
- 未使用适配器的窗口操作
package com.etc.event;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class WindowListenerTest {
private Frame f = new Frame("窗口监听器");
private TextArea ta = new TextArea(6, 40);
public void init() {
//为窗口添加事件监听器
f.addWindowListener(new MyListener());
f.add(ta);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
class MyListener implements WindowListener {
@Override
public void windowOpened(WindowEvent e) {
ta.append("窗口被初次打开!
");
}
@Override
public void windowClosing(WindowEvent e) {
ta.append("用户关闭窗口!
");
}
@Override
public void windowClosed(WindowEvent e) {
ta.append("窗口成功被关闭!
");
}
@Override
public void windowIconified(WindowEvent e) {
ta.append("窗口被最小化!
");
}
@Override
public void windowDeiconified(WindowEvent e) {
ta.append("窗口被恢复!
");
}
@Override
public void windowActivated(WindowEvent e) {
ta.append("窗口被激活!
");
}
@Override
public void windowDeactivated(WindowEvent e) {
ta.append("窗口失去焦点!
");
}
}
public static void main(String[] args) {
new WindowListenerTest().init();
}
}
- 使用适配器关闭窗口
package com.etc.event;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class WindowListenerTest {
private Frame f = new Frame("窗口监听器");
private TextArea ta = new TextArea(6, 40);
public void init() {
//为窗口添加事件监听器
f.addWindowListener(new MyListener());
f.add(ta);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
/**继承适配器类,选择合适方法重写*/
class MyListener extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
System.out.println("用户关闭窗口!
");
System.exit(0);
}
}
public static void main(String[] args) {
new WindowListenerTest().init();
}
}
课后练习
问题1:AWT布局管理器有几种以及各自的特点?
问题2:什么是AWT事件、事件源、事件监听器?
上机练习:
实现一个java AWT程序,要求
- 窗口的名称为“AWT事件”
- 加入窗口监听器,要求当窗口关闭、打开、最小化时打印出相关信息到控制台。
