事件——描述发生了什么的对象; 事件源——事件的产生器; 事件处理器——接收事件、解释事件并处理用户交互的方法; 如果用户在用户界面层执行了一个动作(鼠标点击和按键),这将导致一个事件的发生。事件是描述发生了什么的对象。存在各种不同类型的事件类用来描述各种类型的用户交互。
事件源——是一个事件的产生者。例如在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)类;在适配器中,实现了相应监听器接口所有方法,但不做任何事情,只要继承适配器类,就等于实现了相应的监听器接口;如果要对某类事件的某种情况进行处理,只要覆盖相应的方法就可以,其他的方法再也不用“简单实现”了;如果想用作事件监听器的类已经继承了别的类,就不能再继承适配器类了,只能去实现事件监听器接口了。