5 事件处理
前面介绍了如何放置各种组件,从而得到了丰富多彩的图形界面,但这些界面不能响应用户的任何操作,比如单击前面所有窗口右上角的“X”按钮,但窗口并不会关闭,因为在AWT编程中,所有用户的操作,都必须要经过一套事件处理机制来完成,而Frame和组件本身没有事件处理能力。
5.1 GUI事件处理机制
定义:当在某个组件上发生某些操作的时候,会自动的触发一段代码的执行。
在GUI事件处理机制中,需要我们理解以下4个重要概念:
事件源(Event Source):操作发生的场所,通常指某个组件,例如按钮,窗口等;
事件(Event):在事件源上发生的操作可以叫事件,GUI会把事件都封装到一个Event对象中,如果需要知道该事件的详细信息,就可以通过Event对象来获取;
事件监听器(Event Listener):当在某个事件源上发生了某个事件,事件监听器就可以对这个事件进行处理;
注册监听:把某个事件监听器(A)通过某个事件(B)绑定到某个事件源(C)上,当在事件源C上发生了事件B之后,那么事件监听器A的代码就会自动执行。
其流程图如下:
下面举一个具体的例子:
使用步骤:
1.创建事件源组件对象;
2.自定义类,实现XxxListener接口,重写方法;
3.创建事件监听器对象(自定义类对象)
4.调用事件源组件对象的addXxxListener方法完成注册监听
案例演示:
完成下图效果,点击确定按钮,在单行文本域内显示hello world;
代码如下:
-
public
class EventDemo
1 {
-
Frame frame
= new Frame(
"这里测试事件处理");
-
-
TextField tf
= new TextField(
30);
-
/
/事件源
-
Button ok
= new Button(
"确定");
-
-
public void init(){
/
/组装视图
-
-
/
/监听器
-
/
/MyListener myListener
= new MyListener();
-
/
/ok.addActionListener(myListener);
-
/
*private
class MyListener implements ActionListener{
-
@
Override
-
public void actionPerformed(ActionEvent e) {
-
tf.setText(
"Hello World");
-
}
-
}
*
/
-
/
/注册监听
-
ok.addActionListener(new ActionListener() {
-
@
Override
-
public void actionPerformed(ActionEvent e) {
-
System.out.println(
"ok按钮被点击了...");
-
tf.setText(
"Hello World");
-
}
-
});
-
-
/
/把tf和ok放入到Frame中
-
frame.
add(tf,BorderLayout.NORTH);
-
frame.
add(ok);
-
-
frame.pack();
-
frame.setVisible(
true);
-
-
}
-
-
-
public static void main(
String[] args) {
-
new EventDemo
1().init();
-
}
-
}
5.2 GUI中常见事件和事件监听器
事件监听器必须实现事件监听接口,AWT提供了大量的事件监听器接口用于实现不同类型的事件监听器,用于监听不同类型的事件。AWT中提供了丰富的事件类,用于封装不同组件上所发生的特定操作,AWT的事件类都是AWTEvent类的子类,AWTEvent是EventObject的子类。
5.2.1 事件
AWT把事件分为了两大类:
1.低级事件:这类事件是基于某个特定动作的事件。比如进入、点击、拖放等动作的鼠标事件,再比如得到焦点和失去焦点等焦点事件。
事件 | 触发时机 |
ComponentEvent | 组件事件,当组件尺寸发生变化,位置发生移动,显示/隐藏状态发生改变时触发该事件 |
ContainerEvent | 容器事件,当容器里发生添加组件,删除组件时触发该事件 |
WindowEvent | 窗口事件,当窗口状态发生改变(如打开,关闭,最大化,最小化)时触发事件 |
FocusEvent | 焦点事件,当组件得到焦点或者失去焦点时触发该事件 |
KeyEvent | 键盘事件,当按键被按下,松开,单击时触发该事件 |
MouseEvent | 鼠标事件,当进行单击,按下,松开,鼠标移动等动作时触发该事件 |
PaintEvent | 组件绘制事件,该事件是一个特殊的事件类型,当GUI组件调用update/paint方法来呈现自身时触发该事件,该事件并非专用于事件处理模型 |
2.高级事件:这类事件并不会基于某个特定动作,而是根据功能含义定义的事件。
事件 | 触发时机 |
ActionEvent | 动作时间,当按钮,菜单项被单击,在TextField中按Enter键触发 |
AjustmentEvent | 调节事件,在滑动条上移动滑块以调节数值时触发该事件 |
ItemEvent | 选项事件,当用户选中某项,或取消某项时触发该事件 |
TextEvent | 文本事件,当文本框,文本域里的文本发生改变时触发该事件 |
5.2.2 事件监听器
不同的事件需要使用不同的监听器监听,不同的监听器需要实现不同的监听器接口,当指定事件发生后,事件监听器就会调用所包含的事件处理器(实例方法)来处理事件。
事件类别 | 描述信息 | 监听器接口名 |
ActionEvent | 激活组件 | ActionListener |
ItemEvent | 选择了某些项目 | ItemListener |
MouseEvent | 鼠标移动 | MouseMotionListener |
MouseEvent | 鼠标点击等 | MouseListener |
KeyEvent | 键盘输入 | KeyListener |
FocusEvent | 组件收到或者失去焦点 | FocusListener |
AdjustmentEvent | 移动了滚动条等组件 | AdjustmentListener |
ComponentEvent | 对象移动缩放显示隐藏等 | ComponentListener |
WindowEvent | 窗口收到窗口级事件 | WindowListener |
ContainerEvent | 容器中增加删除了组件 | ContainerListener |
TextEvent | 文本字段或文本区发生改变 | TextListener |
下面进行案例演示:
案例1:通过ContainerListener监听Frame容器添加组件;
通过TextListener监听TextFiled内容变化;
通过ItemListener监听Choice条目选中状态变化。
演示代码:
-
public
class
ListenerDemo1 {
-
public
static
void
main(
String[] args) {
-
Frame frame =
new
Frame(
"这里测试监听器");
-
-
//创建组件(事件源)
-
TextField tf =
new
TextField(
30);
-
Choice names =
new
Choice();
-
names.
add(
"Java");
-
names.
add(
"C++");
-
names.
add(
"python");
-
-
//给文本域添加TextListener,监听内容的变化
-
tf.
addTextListener(
new
TextListener() {
-
@Override
-
public
void
textValueChanged(
TextEvent e) {
-
String text = tf.
getText();
-
System.
out.
println(
"当前文本框中的内容为:"+text);
-
}
-
});
-
-
-
//给下拉选择框添加ItemListener,监听条目选项的变化
-
names.
addItemListener(
new
ItemListener() {
-
@Override
-
public
void
itemStateChanged(
ItemEvent e) {
-
Object item = e.
getItem();
-
System.
out.
println(
"当前选中的条目为:"+item);
-
}
-
});
-
//给frame注册ContainerListener监听器,监听容器中组件的添加
-
frame.
addContainerListener(
new
ContainerListener() {
-
@Override
-
public
void
componentAdded(
ContainerEvent e) {
-
Component child = e.
getChild();
-
System.
out.
println(
"frame中添加了:"+child);
-
}
-
-
@Override
-
public
void
componentRemoved(
ContainerEvent e) {
-
-
}
-
});
-
//添加到frame中
-
Box hBox =
Box.
createHorizontalBox();
-
hBox.
add(names);
-
hBox.
add(tf);
-
frame.
add(hBox);
-
-
//设置frame最佳大小并可见
-
frame.
pack();
-
frame.
setVisible(
true);
-
}
-
}
案例2:
给Frame设置WindowListener,监听用户点击X的动作,如果用户点击X,则关闭当前窗口
代码演示:
-
public
class
ListenerDemo2 {
-
public
static
void
main(
String[] args) {
-
Frame frame =
new
Frame(
"这里测试WindowListener");
-
frame.
setBounds(
200,
200,
500,
300);
-
-
//设置WindowListener,监听用户点击X的动作,如果点击X,则关闭窗口
-
frame.
addWindowListener(
new
WindowAdapter() {
-
@Override
-
public
void
windowClosing(
WindowEvent e) {
-
//停止当前程序
-
System.
exit(
0);
-
}
-
});
-
frame.
setVisible(
true);
-
}
-
}