`

AWT事件总结【“Swing总结”后续文章】

    博客分类:
  • java
阅读更多
AWT事件模型【重点】:

1、事件:描述发生了什么的对象。
2、事件源:事件的产生器。
3、事件处理器:接收事件、解释事件并处理用户交互的方法(归根结底是一个方法)。

---如果用户在用户界面层执行了一个动作(鼠标点击和按键),这将导致一个事件的发生。事件是描述发生了什么的对象。存在各种不同类型的事件类用来描述各种类型的用户交互。



事件源:
事件源是一个事件的产生者。例如,在Button组件上点击鼠标会产生以这个Button为源的一个ActionEvent。这个ActionEvent实例是一个对象,它包含关于刚才所发生的那个时间的信息的对象,这些信息包括:
getActionCommand----返回与动作相关联的命令名称。
getWhen----返回事件发生的时间。


事件处理器:
事件处理器就是一个接收事件、解释事件并处理用户交互的方法。

•-事件-描述发生了什么的对象
•-事件源-事件的产生器
•-事件处理器-接收事件、解释事件并处理用户交互的方法


JDK1.1的事件模型:委托模型
事件监听器:实现了监听器接口的类。一个鉴定器对象是一个实现了专门的监听器接口的类的实例。




一个事件监听器的简单例子:
package com.shengshiyuan.awt;

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();

		Button button = new Button("Press Me!");

		// 为组件添加事件监听器
		button.addActionListener(new ButtonHandler());

		frame.add(button, BorderLayout.CENTER);
		frame.pack();
		frame.setVisible(true);
	}

}

/**
 * 事件监听器
 * 类: ButtonHandler <br>
 * 描述: TODO <br>
 * 作者: 
 * 时间: Nov 4, 2013 9:32:31 PM
 */
class ButtonHandler implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		String label = e.getActionCommand();
		System.out.println(label);
	}
}



---在Button对象上用鼠标进行点击时,将发送一个ActionEvent事件。这个ActionEvent事件会被使用addActionListener()方法进行注册的所有ActionListener的actionPerformed()方法接收。
---ActionEvent类的getActionCommand()方法返回与动作相关联的命令名称。
---以按钮的点击动作为例,将返回Button的标签。


当单击一个按钮时就会产生一个事件(ActionEvent),然后检查是否有与该按钮关联的事件处理器(实际上就是一个方法),如果没有,那么什么都不执行;如果有,就会将该事件传递给与该按钮关联的事件处理器方法,作为该方法的参数,之后该事件处理器方法就会自动得到调用,并且该方法可以使用传递过来的ActionEvent对象,进而获得事件发生时与该事件及事件源相关联的那些信息。


委托模型优点:
---事件不会被意外地处理。
---有可能创建并使用适配器(adater)类对事件动作进行分类。
---委托模型有利于把工作分布到各个类中。




AWT事件处理机制:
几类具有典型代表意义的事件:
MouseEvent:“鼠标事件”,鼠标按下,鼠标释放,鼠标点击等。
WindowEvent:“窗口事件”,点击关闭按钮,窗口得到与失去焦点,窗口最小化等。
ActionEvent:“动作事件”,不代表具体的动作,是一种语义,如按钮或菜单被鼠标点击,单行文本框中按下回车键等都可以看做是ActionEvent事件,可以这么理解,如果用户的一个动作导致了某个组件本身最基本的动作发生了,这就是ActionEvent事件。



事件类型:
---事件类的层次结果图如下所示。许多事件类在java.awt.event包中,也有一些事件类在API的其他地方。
---对于每类事件,都有一个接口,这个接口必须由想接收这个事件的类的对象实现。这个接口还要求定义一个或多个方法。当发生特定的事件时,就会调用这些方法(例如ButtonHandler实现了ActionListener接口)。



两个事件监听器的实例,重点查看:
package com.shengshiyuan.awt;

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();

		Button button = new Button("click me");

		// 添加事件监听器
		button.addActionListener(new MyListener());

		frame.add(button);
		frame.setSize(500, 500);

		// 添加窗口监听器
		frame.addWindowListener(new MyWindowListener());

		frame.setVisible(true);
	}
}

class MyListener implements ActionListener {

	@SuppressWarnings("deprecation")
	public void actionPerformed(ActionEvent e) {
		long time = e.getWhen();
		Date date = new Date(time);
		// new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
		System.out.println(date.toLocaleString());
	}
}

// 窗口监听器,7个方法必须都实现
class MyWindowListener implements WindowListener {

	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	/**
	 * 窗口关闭的时候此方法被调用
	 * 方法: windowClosed <br>
	 * 描述: TODO
	 * @param e 
	 * @see java.awt.event.WindowListener#windowClosed(java.awt.event.WindowEvent)
	 */
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
	}

	public void windowClosing(WindowEvent e) {
		System.out.println("关闭窗口!");
		System.exit(0);
	}

	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub

	}

}

package com.shengshiyuan.awt;

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;

/**
 * MouseMotionListener为鼠标移动监听器
 * MouseListener为鼠标监听器
 * 类: TwoListener <br>
 * 描述: TODO <br>
 * 作者: 
 * 时间: Nov 4, 2013 10:38:07 PM
 */
public class TwoListener implements MouseMotionListener, MouseListener {

	private Frame frame;

	private TextField textfield;

	public void go() {
		Frame frame = new Frame("Two Listeners Example");

		frame.add(new Label("click"), BorderLayout.NORTH);

		textfield = new TextField(30);
		frame.add(textfield, BorderLayout.SOUTH);

		// 为frame添加鼠标移动监听
		frame.addMouseMotionListener(this);
		// 为frame添加鼠标监听
		frame.addMouseListener(this);

		// 为frame添加第二个鼠标监听(得出的结论:同一个事件源可以注册多个监听器,并且同时起作用)
		frame.addMouseListener(new MyMouseListener());

		frame.setSize(300, 200);

		frame.setVisible(true);
	}

	public static void main(String[] args) {
		TwoListener two = new TwoListener();

		two.go();
	}

	// 鼠标拖拽触发此方法
	public void mouseDragged(MouseEvent e) {
		String str = "x:" + e.getX() + ", y:" + e.getY();
		this.textfield.setText(str);
	}

	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	// 鼠标离开当前frame时触发此方法
	public void mouseExited(MouseEvent e) {
		String str = "The mouse has left the Frame";
		this.textfield.setText(str);
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub

	}

}

class MyMouseListener implements MouseListener {

	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	// 鼠标进入到Frame里面的时候触发此方法
	public void mouseEntered(MouseEvent e) {
		String str = "The mouse has entered the Frame";
		System.out.println(str);
	}

	// 鼠标离开当前frame时触发此方法
	public void mouseExited(MouseEvent e) {
		String str = "The mouse has exited the Frame";
		System.out.println(str);
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub

	}
}




重点:同一个事件源可以注册多个监听器,并且同时起作用

一个小的总结:事件,AWT的事件模型是一种委托模型,可以注册一个监听器,监听器里面每一个方法就对应于某一个特定的事件,当事件发生的时候监听器里面对应的方法就会被调用。


-----多监听者可以使一个程序的不想关部分执行同样的动作。
-----事件发生时,所有被注册的监听者的处理器都会被调用。


在以上定义的监听器类中,比如实现了MouseListener接口的监听器类MyLouseListener,由于语法要求我们必须要实现接口里面定义的所有(5个)方法,但是一般我们需要处理的特定的事件也就一两个,能用到的方法也就一两个,所以实现出来的其他方法都是用不到的,无用的代码,但是我们又不得不实现它们,因为这是语法要求,这样就产生了矛盾。在这种矛盾的背景下就产生了适配器Adapter这种概念。

Java中的组件若想添加事件处理器,都会使用形如addXxxListener的方法来添加。

事件(Adapters)适配器
-----你定义的Listener可以继承Adapter类,而且只需重写你所需要的方法。
-----为了方便起见,Java语言提供了Adapters类,用来实现含有多个方法的类。这些Adapters类中的方法是空的
-----你可以继承Adapters类,而且只需要重写你所需要的方法


适配器jdk已经为我们提供好了的,而且适配器这个类已经实现好了对应的接口,比如说包含了5个方法的那个监听器接口MouseListener,已经有一个对应的适配器类实现好了它,我们自己的处理器只需要继承这个适配器类,这样也可以表明我实现了MouseListener这个接口,我们从这个适配器类里面把5个方法全都继承下来了。但是假如我们只对其中一个方法感兴趣(我们需要处理的特定的事件就一个),那么我们只需要在我们处理器里面把这一个方法重写即可,其他四个方法我们用不到,就不需要重写了。

比如说:
MouseAdapter类实现了MouseMotionListener接口
MouseAdapter类实现了MouseListener接口


适配器把实现接口里面的所有方法都空实现了,什么都没有做。

下面是TwoListener使用适配器改版之后的代码
package com.shengshiyuan.awt;

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;

/**
 * 利用适配器实现事件监听
 * MouseAdapter实现了MouseMotionListener接口
 * MouseAdapter实现了MouseListener接口
 * 这里间接的实现了以上两个接口
 * 类: TwoListenerAdapter <br>
 * 描述: TODO <br>
 * 作者: 
 * 时间: Nov 5, 2013 11:34:23 AM
 */
public class TwoListenerAdapter extends MouseAdapter {
	private Frame frame;

	private TextField textfield;

	public void go() {
		Frame frame = new Frame("Two Listeners Example");

		frame.add(new Label("click"), BorderLayout.NORTH);

		textfield = new TextField(30);
		frame.add(textfield, BorderLayout.SOUTH);

		// 为frame添加鼠标移动监听
		frame.addMouseMotionListener(this);
		// 为frame添加鼠标监听
		frame.addMouseListener(this);

		// 为frame添加第二个鼠标监听(得出的结论:同一个事件源可以注册多个监听器,并且同时起作用)
		frame.addMouseListener(new MyMouseListener());

		frame.setSize(300, 200);

		frame.setVisible(true);
	}

	public static void main(String[] args) {
		TwoListenerAdapter two = new TwoListenerAdapter();

		two.go();
	}

	// 对应鼠标移动事件(MouseAdapter实现MouseMotionListener接口里面的方法,然后这里又重写MouseAdapter类里的这个方法)
	@Override
	public void mouseDragged(MouseEvent e) {
		String str = "x:" + e.getX() + ", y:" + e.getY();
		this.textfield.setText(str);
	}

	// 对应鼠标离开当前frame事件(MouseAdapter实现MouseListener接口里面的方法,然后这里又重写MouseAdapter类里的这个方法)
	@Override
	public void mouseExited(MouseEvent e) {
		String str = "The mouse has left the Frame";
		this.textfield.setText(str);
	}

	// 对应鼠标进入Frame事件(MouseAdapter实现MouseListener接口里面的方法,然后这里又重写MouseAdapter类里的这个方法)
	@Override
	public void mouseEntered(MouseEvent e) {
		String str = "The mouse has entered the Frame";
		System.out.println(str);
	}
}




适配器只是简化我们的工作而已,并不会完成实际的功能。是我们自己的监听处理类和真正的监听器接口之间的桥梁,起到一个适配的作用。

为简化编程,JDK针对大多数事件监听器接口定义了相应的实现类,我们称之为事件适配器(Adapter)类。
在适配器类中,实现类相应监听器接口所有方法,但不做任何事情,只要继承适配器类,就等于实现了相应的监听器接口。
如果要对某类事件的某种情况进行处理,只要覆盖相应的方法就可以,其他的方法再也不用“简单实现”了。
如果想用作事件监听器的类已经继承了别的类,就不能再继承适配器类了,只能去实现事件监听器接口了

重点:针对监听器接口ActionListener没有提供相应的适配器,因为它里面只有一个方法,有没有适配器我们要想用它都得把里面的那一个方法实现或重写了,因此没必要提供适配器了。要想使用ActionListener监听,就只能实现ActionListener这个接口了,没有其他方法。除了这一个Listener,其他的Listener都有对应的适配器。
  • 大小: 28 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics