目前面向对象是软件系统建模的主流技术使用面向对象技术建模的主要指标之一是可复用性为了更好地解决软件复用性和扩展性问题设计模式得到了越来越多的关注与应用
结合command设计模式和Java语言的反射技术本文设计实现了一个可复用的事件处理框架
在面向对象的系统设计中有些方面的可复用性经常被忽略了用户界面(User Interface 下文简称UI)及其事件处理就是其中之一一个完整的UI设计应该包括两部分UI及其相应的事件处理机制没有事件处理机制的UI是没有用的对于事件处理也应该考虑可复用设计虽然看上去有些奇怪但是这种设计是有实用价值的——提高了代码的可复用性健壮性和可维护性
command设计模式的主要设计思想是把对某一对象的请求封装为一个对象从而把发出命令的责任和执行任务的责任分开委派给不同的对象请求的一方不必知道接收请求一方的接口这种引入第三方类的做法是设计模式所惯用的引入的第三方类解耦了紧耦合对象command设计模式中第三方类解耦了调用操作的对象与知道如何实现该操作的对象提高了软件的可复用性
JDK 及其以后的版本引入了反射(reflection)技术反射是Java中非常突出的动态特征利用它可以加载一个运行时才得知名字的class获取其完整结构这一切是通过反射API完成的
//UIDemo
import javaawt*;
import javaawtevent*;
import javaxswing*;
public class UIDemo implements ActionListener{
private JFrame frame;
private JButton button;
private JTextArea area;
private int index = ;
private String [] params;
private UIDemo(String args[]){
params = args;
area = new JTextArea();
button = new JButton(Click here!);
buttonaddActionListener(this);
frame = new JFrame(getClass()getName());
frameaddWindowListener(new ReusableWindowAdapter());
Container cont = framegetContentPane();
JScrollPane scrollPane = new JScrollPane(area);
contadd(scrollPaneBorderLayoutNORTH);
contadd(buttonBorderLayoutSOUTH);
framepack();
framesetVisible(true);
}
public void actionPerformed(ActionEvent ae){
//provide equality check to see if source was the
//button defined above useful only if we register
//this ActionListener with multiple sources
if(aegetSource()equals(button)){
index = ++index % paramslength;
areasetText(params[index]);
}
}
public static void main(String args[]){
if(argslength > ){
UIDemo one = new UIDemo(args);
}else{
usage();
}
}
private static void usage(){
Systemerrprintln(You may excute this program as below:);
Systemerrprintln(java UIDemo params params );
Systemexit();
}
}
//UIDemo
import javaawt*;
import javaawtevent*;
import javaxswing*;
public class UIDemo{
private JFrame frame;
private JButton button;
private JTextArea area;
private int index = ;
private String [] params;
private UIDemo(String args[]){
params = args;
area = new JTextArea();
button = new JButton(Click Here!);
buttonaddActionListener(new SemiReusableActionListener(this));
frame = new JFrame(getClass()getName());
frameaddWindowListener(new ReusableWindowAdapter());
Container cont = framegetContentPane();
JScrollPane scrollPane = new JScrollPane(area);
contadd(scrollPaneBorderLayoutNORTH);
contadd(buttonBorderLayoutSOUTH);
framepack();
framesetVisible(true);
}
void setMessage(Object source){
if(sourceequals(button)){
index = ++index % paramslength;
areasetText(params[index]);
}
}
public static void main(String args[]){
if(argslength > ){
UIDemo two = new UIDemo(args);
}else{
usage();
}
}
private static void usage(){
Systemerrprintln(You may excute this program as below:);
Systemerrprintln(java UIDemo params params );
Systemexit();
}
}
//SemiReusableActionListener
import javaawtevent*;
public class SemiReusableActionListener implements ActionListener{
private UIDemo demo;
SemiReusableActionListener(UIDemo uiDemo){
demo = uiDemo;
}
public void actionPerformed(ActionEvent ae){
demosetMessage(aegetSource());
}
}
//UIDemo
import javaawt*;
import javaawtevent*;
import javaxswing*;
import javalangreflect*;
public class UIDemo{
private JFrame frame;
private JButton button;
private JTextArea area;
private int index = ;
private String [] params;
private UIDemo(String args[]){
params = args;
area = new JTextArea();
button = new JButton(Click here!);
//setup required information to use GenericActionListener
String methodName = setMessage;
Class [] paramTypes = {javalangObjectclass};
Object [] methodArgs = { button };
Class clazz = thisgetClass();
try{
Method method = clazzgetMethod(methodName paramTypes);
buttonaddActionListener(new
ReusableActionListener(method this methodArgs));
}
catch(Exception e){
Systemoutprintln(Could not find the method: +methodName+\nNow Exiting);
Systemexit();
}
frame = new JFrame(getClass()getName());
frameaddWindowListener(new ReusableWindowAdapter());
Container cont = framegetContentPane();
JScrollPane scrollPane = new JScrollPane(area);
contadd(scrollPaneBorderLayoutNORTH);
contadd(buttonBorderLayoutSOUTH);
framepack();
framesetVisible(true);
}
public void setMessage(Object source){
if(sourceequals(button)){
index = ++index % paramslength;
areasetText(params[index]);
}
}
public static void main(String args[]){
if(argslength > ){
UIDemo three = new UIDemo(args);
}else{
usage();
}
}
private static void usage(){
Systemerrprintln(You may excute this program as below:);
Systemerrprintln(java UIDemo params params );
Systemexit();
}
}
//ReusableWindowAdapter
import javaawt*;
import javaawtevent*;
public class ReusableWindowAdapter extends WindowAdapter{
public void windowClosing(WindowEvent we){
Object source = wegetSource();
if(source instanceof Frame){
((Frame)source)setVisible(false);
((Frame)source)dispose();
Systemexit();
}
}
}