事件——描述发生了什么的对象; 事件源——事件的产生器; 事件处理器——接收事件、解释事件并处理用户交互的方法; 如果用户在用户界面层执行了一个动作(鼠标点击和按键),这将导致一个事件的发生。事件是描述发生了什么的对象。存在各种不同类型的事件类用来描述各种类型的用户交互。
事件源——是一个事件的产生者。例如在Button组件上点击鼠标会产生以这个Button为源的一个ActionEvent。这个ActionEvent实例是一个对象,它包含关于刚才所发生的那个事件的信息的对象,这些信息包括:getActionCommand——返回与动作相关联的命令名称;getWhen——返回事件发生的事件。
JDK1.0的事件模型:层次模型
1、JDK1.1的事件模型:委托模型
事件监听器:实现了监听器接口的类。一个监听器对象是一个实现了专门的监听器接口的类的实例。
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestButton
{
public static void main(String[] args)
{
Frame frame = new Frame("Test");
Button button = new Button("press me");
//增加事件处理器
button.addActionListener(new ButtonHandler());
frame.add(button,BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.out.println("button is press!");
}
}
2、关于ActionEvent类,该类的对象就是一个事件,封装了事件的所有信息,这个对象是系统生成的
当单击一个按钮时就会产生一个事件(ActionEvent),然后检查是否有与该按钮关联的事件处理器(实际上就是一个方法),如果没有,那么什么都不执行;如果有,就会将该事件传递给与该按钮关联的事件处理器方法,作为该方法的参数,之后该事件处理器方法就会自动得到调用,并且该方法可以使用传递过来的ActionEvent对象,进而获得事件发生时与该事件及事件源相关联的那些信息。
java中的组件若想添加事件处理器,都会使用形如addXxxListener的方法来添加。
3、在Button对象上用鼠标进行点击时,将发送一个ActionEvent事件。这个ActionEvent事件会被使用addActionListener()方法进行注册的所有ActionListener的actionPerformed()方法接收;ActionEvent类的getActionCommand()方法返回与动作相关联的命令名称;以按钮的点击动作为例,将返回Button的标签。
4、委托模型的优点:事件不会被意外的处理;有可能创建并使用适配器(adapter)类对事件动作进行分类;委托模型有利于把工作分布到各个类中。
5、几类具有典型代表意义的事件:
类 | 对应事件 | 说明 |
MouseEvent | 鼠标事件 | 鼠标按下、释放、点击等 |
WindowEvent | 窗口事件 | 点击关闭按钮,窗口得到与失去焦点,窗口最小化等 |
ActionEvent | 动作事件 | 不代表具体的动作,是一种语义,如按钮或菜单被鼠标单击,单行文本框中按下回车键等都可以看做是ActionEvent事件。可以这么理解,如果用户的一个动作导致了某个组件本身最基本的动作发生了,这就是ActionEvent事件 |
6、事件类型,许多事件类在java.awt.event包中,也有一些事件类在API的其他地方;对于每类事件,都有一个接口,这个接口必须由想接收这个事件的类的对象实现。这个接口还要求定义一个或多个方法。当发生特定的事件时,就会调用这些方法。
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Date;
public class MyFrame2
{
public static void main(String[] args)
{
Frame frame = new Frame("frame2");
Button button = new Button("press");
button.addActionListener(new MyListener());
frame.addWindowListener(new MyWindowsListener());
frame.add(button);
frame.setSize(500,500);
frame.setVisible(true);
}
}
class MyListener implements ActionListener
{
@Override
@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e)
{
long milliSeconds = e.getWhen();
Date date = new Date(milliSeconds);
System.out.println(date.toLocaleString());
}
}
class MyWindowsListener implements WindowListener
{
@Override
public void windowActivated(WindowEvent e)
{
}
@Override
public void windowClosed(WindowEvent e)
{
}
@Override
public void windowClosing(WindowEvent e)
{
System.out.println("关闭");
System.exit(0);
}
@Override
public void windowDeactivated(WindowEvent e)
{
}
@Override
public void windowDeiconified(WindowEvent e)
{
}
@Override
public void windowIconified(WindowEvent e)
{
}
@Override
public void windowOpened(WindowEvent e)
{
}
}
7、一个事件源对应多个监听器
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class TwoListener implements MouseMotionListener,MouseListener
{
private Frame frame;
private TextField textField;
public void go()
{
frame = new Frame("asdfas");
frame.add(new Label("click"),BorderLayout.NORTH);
textField = new TextField(30);
frame.add(textField,BorderLayout.SOUTH);
frame.addMouseMotionListener(this);
frame.addMouseListener(this);
frame.addMouseListener(new MyMouseListener());
frame.setSize(300,200);
frame.setVisible(true);
}
public static void main(String[] args)
{
TwoListener win = new TwoListener();
win.go();
}
@Override
public void mouseClicked(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
String str = "mouse exit";
this.textField.setText(str);
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseDragged(MouseEvent e)
{
}
@Override
public void mouseMoved(MouseEvent e)
{
String str = "x:" + e.getX() + ",y:" +e.getY();
this.textField.setText(str);
}
}
class MyMouseListener implements MouseListener
{
@Override
public void mouseClicked(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
String str = "the mouse has enter";
System.out.println(str);
}
@Override
public void mouseExited(MouseEvent e)
{
String str = "has exite";
System.out.println(str);
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
}
多监听者可以使一个程序的不相关部分执行同样的动作;事件发生时,所有被注册的监听者的处理器都会被调用。
8、事件Adapter(适配器):定义的Listener可以继承Adapter类,而且只需重写所需要的方法;为了方便起见,Java语言提供了Adapters类,用来实现含有多个方法的类。这些Adapters类中的方法是空的;你可以继承Adapters类,而且只需要重写需要的方法。
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class TwoListenerAdapter
{
private Frame frame;
private TextField textField;
public void go()
{
frame = new Frame("asdfas");
frame.add(new Label("click"),BorderLayout.NORTH);
textField = new TextField(30);
frame.add(textField,BorderLayout.SOUTH);
frame.addMouseListener(new MyAdapter());
frame.setSize(300,200);
frame.setVisible(true);
}
}
class MyAdapter extends MouseAdapter
{
@Override
public void mouseEntered(MouseEvent e)
{
String str = "mouse exit";
System.out.println(str);
}
@Override
public void mouseExited(MouseEvent e)
{
String str = "has exite";
System.out.println(str);
}
}
为了简化编程,JDK针对大多数事件监听器接口定义了相应的实现类,我们称之为事件适配器(Adapter)类;在适配器中,实现了相应监听器接口所有方法,但不做任何事情,只要继承适配器类,就等于实现了相应的监听器接口;如果要对某类事件的某种情况进行处理,只要覆盖相应的方法就可以,其他的方法再也不用“简单实现”了;如果想用作事件监听器的类已经继承了别的类,就不能再继承适配器类了,只能去实现事件监听器接口了。