JavaBeans和Beans事件

JavaBeans是一种软件组织结构,在诸如NetBeans、JBuilder或Eclipse等一些纯Java开发工具中,它能够在设计中可视化地使用机构良好的对象。这些结构良好的对象就叫做JavaBeans,简称Beans。定义Beans的类称为JavaBeans组件Bean组件,或者简称为组建。这些类通过下列条件组织为JavaBeans组建模型:

1. Beans必须是public类。

2. 尽管Bean可能有其他构造方法,但是必须有一个公用的无参构造方法。

3. Bean必须实现接口java.io.Serializeable,并确保其持续性。

4. Bean的属性通常带有构造恰当的共用访问器方法(get 方法)和修改器方法(set 方法),可以使开发工具能够看到并使用Bean属性。

5. Bean事件可能带有构造恰当的,共用的注册方法和注销方法,使用这些方法可以添加或删除监听器。如果Bean是事件源,它必须提供注册监听器的注册方法。例如,可以使用 JButton Bean的 addActionListener 方法给 ActionEvent 事件注册一个监听器。


Bean必须满足前三个条件,因此,这三个条件称为JavanBeans组件的最低要求。是否满足后两个条件依赖于具体实现,可能编写的Bean没有 get/set 方法或者没有事件注册/注销方法。


JavaBeans组件是一种特殊的Java类。每个图形用户界面(GUI)都是一个JavaBeans组件。


Java事件模型

Java时间模型由下列三种元素组成:
1. 事件对象
2. 源对象
3. 事件监听器对象

事件是表示程序发生某些事情的信号,可以由外部用户操作,如移动鼠标、单击鼠标和按下键盘等触发,也可以由操作系统,如计时器触发。事件对象包含描述时间的信息,源对象表示事件初始发生的位置。当源对象上发生一个事件时,就会创建一个事件对象。一个关注事件的对象接收事件,这样的对象称为监听器。并不是所有的对象都可以接收事件。一个对象要想成为监听器,必须由源对象对其进行注册。源对象保存一个监听器列表,通过监听器对象上事件的事件处理方法通知所有注册的监听器。定义处理器的类称为事件监听器接口。事件对象的每个类都有相应的事件监听器接口。Java事件模型称为事件委托模型,因为源对象将事件处理任务委托个了监听器。


事件类和事件监听器接口

事件对象是使用事件类来创建的,事件类如ActionEvent,MouseEvent和ItemEvent等,所有的事件类都是扩展 java.util.EventObject 而来的,它们包含与具体事件类型相关的所有数据值和方法。例如,KeyEvent类描述与键盘事件相关的数据值,包含如getKeyChar()之类的与键盘事件相关的方法。

每个事件类与一个事件监听器接口相关联,这种接口定义一个或多个称为处理器(handler)的方法。事件监听器接口是java.util.EventListener的子接口。处理器是由监听器实现的。当检测到事件发生时,源组件调用监听器的处理器。

由于事件类与它的监听器接口是相互依存的,所以称为事件组(event set )事件对(event pair) 事件XEvent的监听器接口必须命名为XListener。例如,ActinEvent的监听器接口是ActionListener。处理器的参数表一定包含一个类型为事件类型的参数。


源组件

产生事件的组件称为事件源。每个Java GUI 组件是一个或多个事件的事件源。例如,JButton是ActionEvent的事件源。当按钮被点击时,JButton对象触发一个java.awt.event.ActionEvent事件。JComboBox是ActionEvent事件和ItemEvent的事件源。当组合框选定一个新项目时,JComboBox对象触发一个java.awt.event.ActionEvent事件和一个java.awt.event.ItemEvent事件。
源组件包含检测代码,用于检测引发实际那的外部或内部动作。当检测到动作时,源组件调用监听器所定义的事件处理器向监听器触发事件。源组件也包含注册和注销监听器的方法。

监听器组件

对于一个事件来说,监听器组件必须实现事件监听器接口。如果一个监听器组建的对象未注册为源对象的监听器,则它就不能接受来自源组件的事件通知。

一个监听器可以实现任意多个监听器接口,以便监听多种类型的事件。一个源组件可以注册多个监听器,也可以将其本身这侧为监听器。


创建自定义源组件

我们可以创建自定义的源组件。源组件必须有适当的注册和注销方法,用来添加和删除监听器。事件可以被单点传送(事件只能通知一个监听器对象),也可以被多点传送(事件通知监听器列表中的每一个对象)。添加一个单点传送的监听器的命名方式为:

public void add<Event>Listener(<Event>Listener l) throws TooManyListenersException;

添加多点传送监听器的命名方式同上面一样,但是不需要抛出TooManyListenersException异常。

public void add<Event>Listener(<Event>Listener l)

删除一个监听器(不管是单点传送还是多点传送)的命名方式为:

public void remove<Event>Listener(<Event>Listener l)

源组件包含特定的代码,可以创建事件对象,并且可以通过调用事件监听器接口中的方法将事件对象传递给监听器组件。我们可以调用标准的Java事件类(如ActionEvent)创建事件对象,必要时可以定义自己的事件类。
如下所示例子,源组件负责注册监听器,创建事件、调用在监听器接口中定义的方法通知监听器。CourseWithActionEvent 组件可以注册多重监听器,当生源超出限制时,产生ActionEvent对象,并调用监听器的actionPerformed方法通知监听器。
import java.util.*;
import java.awt.event.*;

public class CourseWithActionEvent
{
	private String name = "default name";
	private ArrayList<String> students = new ArrayList<String>();
	private int enrollmentCap = 10;
	
	private ArrayList<ActionListener> actionListenerList;
	
	public CourseWithActionEvent()
	{
	}
	
	public CourseWithActionEvent(String name)
	{
		this.name = name;
	}
	
	public void addStudent(String student)
	{
		students.add(student);
		
		if(students.size() > enrollmentCap)
		{
			// Fire ActionEvent
			processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null))
		}
	}
	
	public String[] getStudent()
	{
		return (String[])students.toArray();
	}
	
	public int getNumberOfStudents()
	{
		return enrollmentCap;
	}
	
	public void setEnrollmentCap(int enrollmentCap)
	{
		this.enrollemtnCap = enrollmentCap;
	}
	
	/** Register an action event listener */
	public synchronized void addActionListener(ActionListener listener)
	{
		if(actionListenerList == null)
		{
			ationListenerList = new ArrayList<ActionListener>(2);
		}
		
		if(!actionListenerList.contains(listener))
		{
			actionListenerList.add(listener);
		}
	}
	
	/** Remove an action event listener */
	public synchronized void remvoeActionListener(ActionListener listener)
	{
		if(actionListenerList != null && actionListenerList.contains(listener))
		{
			actionListenerList.remove(listener);
		}
	}
	
	/** Fire ActionEvent */
	private void processEvet(ActionEvent e)
	{
		ArrayList list;
		
		synchronized(this)
		{
			if(actionListenerList == null)
				return;
			list = (ArrayList)actionListener.clone();
		}
		
		for(int i = 0; i < list.size(); i++)
		{
			ActionListener listener = (ActionListener)list.get(i);
			listener.actionPerformed(e);
		}
	}
}

这里源组件是按照多重监听器而设计的,我们采用java.util.ArrayList的实例actionListenerList保存源组件拥有所有的监听器。我们可以编写一个测试程序来进行测试:
import java.awt.event.*;

public class TestCourseWithActionEvent
{
	CourseWithActionEvent course = new CourseWithActionEvent("Java Programing");
	
	public TestCourseWithActionEvent()
	{
		course.setEnrollmentCap(2);
		ActionListener listener = new Listener();
		course.addActionListener(listener);
		course.addStudent("John");
		course.addStudent("Jim");
		course.addStudent("Tim");
	}
	
	public static void main(String[] args)
	{
		public void actionPerformed(ActionEvent e)
		{
			System.out.println("Enrollment cap exceeded");
		}
	}
}

当然,我们还可以创建自定义事件组,这个有机会我们以后再讨论。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值