1、JavaBeans
一种软件组件结构,扩展了Java语言的功能,能够构造可重用的软件组件。
2、Bean属性
属性是相互分离的,它们以影响Javabean外观或行为的特性命名,通常是Bean的数据域。私有数据域通常用来对用户隐藏实现的细节,防止用户意外破坏。Get/set方法用来保证用户能读写该属性。
属性的命名方式:
一般来说,get方法命名为get<PropertyName>(),不带参数,返回一个与属性类型一致的基本数据类型值或对象。例如:
public String getMessage(){}
public int getXCoordinate(){}
对于一个boolean类型的属性,get方法命名为is<PropertyName>(),返回一个boolean类型的值,例如:
public boolean isCentered(){}
set方法应该命名为set<PropertyName>(dataType p),带一个与属性类型相同的参数,返回值是void,例如:
public void setMessage(String s){}
public void setXCoordinate(int x){}
属性表述Bean的状态,数据域用于存储属性,但Bean属性不一定必须是一个数据域。例如:
public int getMessageLength(){
return message.length();
}
3、Java事件模型由事件对象、源对象和事件监听器对象组成。
事件是程序发生某些事情的信号。事件对象包含描述事件的信息。源对象表示事件初始发生时的位置。一个关注事件的对象接受事件,这样的对象称为监听器。一个对象要能接受事件,必须对该对象注册监听器。Java事件模型称为事件委托模型,因为源对象将事件处理任务委托给了监听器。
4、事件对象是使用事件类来创建的,如ActionEvent,所有事件类都是EventObject的子类,包含与具体事件类型相关的数据值和方法。每个事件类与一个事件监听器接口相关联,这种接口定义为一个或多个处理器的方法。事件监听器接口都是EventListener的子接口。处理器由监听器组件实现。当检测到事件发生时,源组件调用监听器的处理器。事件类和与它的监听器接口是相互依存的,所以称其为时间组或事件对。时间XEvent的监听器必须命名为XListener。
5、源组件
源组件包含检测代码,用于检测引发事件的外部或内部动作,当检测到动作时,源组件调用监听器所定义的事件处理器向监听器触发事件。源组件包含注册和注销监听器的方法。
6、监听器组件
对于一个事件,监听器组件必须实现事件监听器接口,如果一个监听器组件的对象未注册为源对象的监听器,则它就不能接受来自源组件的事件通知。一个监听器可以实现任意多个监听器接口,以便监听多种类型的事件。例如下面代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class TestSourceListener {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame frame = new JFrame("TestSourceListener");
JButton jbt = new JButton("OK");
frame.add(jbt);
frame.setSize(200, 200);
frame.setVisible(true);
MyListener listener = new MyListener();
jbt.addActionListener(listener);
}
}
class MyListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("I will process it");
}
}
JButton jbt = new Jbutton("OK");是创建一个源对象。
MyListener listener = new MyListener();是创建一个监听器对象
jbt.addActionListener(listener);用源对象对监听器进行注册
7、创建自定义源组件
源组件必须有适当的注册与注销方法,用来添加和删除监听器。事件可以被单点传送,也可以被多点传送。添加一个单点传送监听器的命名方式为
public void add<Event>Listener(<Event>Listener l) throws TooMangListenersException;
添加多点传送监听器方法为:
public void add<Event>Listener(<Event>Listener l)
删除一个监听器的命名方式为:
public void remove<Event>Listener(<Event>Listener l);
源组件包含特定的代码,可以创建事件对象,并且可以调用事件监听器接口中的方法将事件对象传递给监听器组件。可以调用标准的的Java事件类来创建事件对象,也可以自定义事件类。
例如代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class StudentsWithActionEvent {
private ArrayList<String> students = new ArrayList<String>();
private int enrollmentCap = 10;
private ArrayList<ActionListener> actionListenerList;
public StudentsWithActionEvent(){
}
public void addStudent(String name) {
students.add(name);
if (students.size() > enrollmentCap){
processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null));
}
}
public String[] getStudents() {
return (String[])students.toArray();
}
public int getNumberofStudents() {
return students.size();
}
public int getEnrollmentCap() {
return enrollmentCap;
}
public void setEnrollmentCap(int enrollmentCap) {
this.enrollmentCap = enrollmentCap;
}
public synchronized void addActionListener(ActionListener listener){
if (actionListenerList == null){
actionListenerList = new ArrayList<ActionListener>(2);
}
if (!actionListenerList.contains(listener)){
actionListenerList.add(listener);
}
}
public synchronized void removeActionListener(ActionListener listener){
if (actionListenerList != null && actionListenerList.contains(listener)){
actionListenerList.remove(listener);
}
}
private void processEvent(ActionEvent e){
ArrayList list;
synchronized (this) {
if (actionListenerList == null)
return ;
list = (ArrayList)actionListenerList.clone();
}
for (int i = 0; i < list.size();i++){
ActionListener listener = (ActionListener)list.get(i);
listener.actionPerformed(e);
}
}
}
StudentsWithActionEvent类负责存储班级学生姓名,当学生数目超过限制时, StudentsWithActionEvent对象激发ActionEvent事件,并调用监听器的 actionPerformed方法通知监听器。源组件负责注册监听器、创建事件、调用在监听器接口中定义的方法。
测试代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestStudentsWithActionEvent {
StudentsWithActionEvent studentsWithActionEvent = new StudentsWithActionEvent();
public TestStudentsWithActionEvent() {
// TODO Auto-generated constructor stu
studentsWithActionEvent.setEnrollmentCap(2);
ActionListener listener = new Listener();
studentsWithActionEvent.addActionListener(listener);
studentsWithActionEvent.addStudent("John");
studentsWithActionEvent.addStudent("Jim");
studentsWithActionEvent.addStudent("Tim");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestStudentsWithActionEvent();
}
}
class Listener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("EnrollmentCap cap exceeded");
}
}
程序运行显示nrollmentCap cap exceeded
8、创建自定义事件组
自定义事件类必须扩展EventObject类或其子类,应提供创建事件的构造方法以及描述事件的数据成员和方法。
import java.util.EventObject;
public class EnrollmentEvent extends EventObject {
private int numberOfStudents;
private int enrollmentCap;
public EnrollmentEvent(Object source, int numberOfStudents,
int enrollmentCap) {
super(source);
this.numberOfStudents = numberOfStudents;
this.enrollmentCap = enrollmentCap;
}
public int getNumberOfStudents() {
return numberOfStudents;
}
public int getEnrollmentCap() {
return enrollmentCap;
}
}
自定义事件监听器接口必须扩展EventListener接口或子接口,并且定义事件的处理器的签名
import java.util.EventListener;
public interface EnrollmentListener extends EventListener {
public void enrollmentExceed(EnrollmentEvent e);
}
运用自定义的事件类和事件监听器接口的程序:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class StudentsWithEnrollmentEvent {
private ArrayList<String> students = new ArrayList<String>();
private int enrollmentCap = 10;
private ArrayList<EnrollmentListener> enrollmentListenerList;
public StudentsWithEnrollmentEvent(){
}
public void addStudent(String name) {
students.add(name);
if (students.size() > enrollmentCap){
processEvent(new EnrollmentEvent(this, getNumberofStudents(), getEnrollmentCap()));
}
}
public String[] getStudents() {
return (String[])students.toArray();
}
public int getNumberofStudents() {
return students.size();
}
public int getEnrollmentCap() {
return enrollmentCap;
}
public void setEnrollmentCap(int enrollmentCap) {
this.enrollmentCap = enrollmentCap;
}
public synchronized void addEnrollmentListener(EnrollmentListener listener){
if (enrollmentListenerList == null){
enrollmentListenerList = new ArrayList<EnrollmentListener>(2);
}
if (!enrollmentListenerList.contains(listener)){
enrollmentListenerList.add(listener);
}
}
public synchronized void removeEnrollmentListener(EnrollmentListener listener){
if (enrollmentListenerList != null && enrollmentListenerList.contains(listener)){
enrollmentListenerList.remove(listener);
}
}
private void processEvent(EnrollmentEvent e){
ArrayList list;
synchronized (this) {
if (enrollmentListenerList == null)
return ;
list = (ArrayList)enrollmentListenerList.clone();
}
for (int i = 0; i < list.size();i++){
EnrollmentListener listener = (EnrollmentListener)list.get(i);
listener.enrollmentExceed(e);
}
}
}
测试代码:
public class TestStudentsEnrollmentEvent {
StudentsWithEnrollmentEvent studentsWithEnrollmentEvent = new StudentsWithEnrollmentEvent();
public TestStudentsEnrollmentEvent() {
studentsWithEnrollmentEvent.setEnrollmentCap(2);
EnrollmentListener listener = new NewListener();
studentsWithEnrollmentEvent.addEnrollmentListener(listener);
studentsWithEnrollmentEvent.addStudent("John");
studentsWithEnrollmentEvent.addStudent("Jim");
studentsWithEnrollmentEvent.addStudent("Tim");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestStudentsEnrollmentEvent();
}
}
class NewListener implements EnrollmentListener {
@Override
public void enrollmentExceed(EnrollmentEvent e) {
// TODO Auto-generated method stub
System.out.println(e.getNumberOfStudents() + " enrolled" + "and the enrollmentcap is " + e.getEnrollmentCap());
}
}
输出:3 enrolledand the enrollmentcap is 2