现在很多JAVA书籍,在介绍SWING的事件模型时,为了使JAVA初学者容易理解和上手,通常是在主类(自己的JFrame子类或JPanel)中做所有事情:要么由主类作为监听器,在接口的方法中通过判定事件源来决定具体做何事;要么在主类中使用内隐类来实现监听器,(因为内隐类可以方便的访问主类中的成员变量)。而很多JAVA初学者在往后的编程中也采用这种模式(至少我以前是这样的)。其实,这种做法虽然简单,却缺乏可读性、可扩展性和可维护性。之前我看到了一篇关于这个问题的文章(来自于《JavaPro》),现整理出来与大家分享。
下面我将用一个简单的例子来说明如何使用模式来解决这个问题。
现在,假设我们要编写一个使用几个单选按钮从一个长列表中选择不同分组的程序,就象下图中看到的。单击Female单选按钮时,只有女孩的名字被显示;当你点击Male按钮时,程序显示男孩的名字。

这个程序最简单的版本是在主类中做每件事情,主类包含一些持有孩子姓名的数组和向量(Vector),一个另一个最简单的方法是为每个孩子创建一个对象,每个对象有一个象isFemal()这样的方法来帮助我们确定要显示的是男的还是女的。在程序中我们把每个孩子的类称为Swimmer:
private String name;
private int age;
private String club;
private boolean female;
public Swimmer(String name,int age,String club,boolean female){
this.name=name;
this.age=age;
this.club=club;
this.female=female;
}
public boolean isFemale(){
return female;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String getClub(){
return club;
}
}
public Vector getList(boolean female){
Vector v=new Vector();
for(int i=0;i Swimmer swm=(Swimmer)kids.elementAt(i);
if(swm.isFemal()==female) v.add(swm);
}
return v;
}
现在让我们进入程序中的第一个重要的部分,为了显示这些孩子的姓名,我们需要为三个单选按钮都添加一个事件监听器,使得每个都能显示出正确的孩子们:
//listen for button clicks and do the right thing
Object obj=e.getSource();
if(obj==female) loadFemales();
if(obj==male) loadMales();
if(obj==both) loadBoth();
}
private void loadFemales(){
//display female swimmers
Vector v=swimmers.getList(true);
loadList(v);
}
private void loadMales(){
//display male swimmers
Vector v=swimmers.getList(false);
loadList(v);
}
做到这点的一个途径是使用Command模式。当我们使用这个模式的时候,需要我们创立一个Command接口:
public interface Command{
public void execute();
}
public abstract class SexButton
extends JRadioButton implements Command{
protected Swimmers simmers;
//JawList is a subclass of JScrollPane contained a JList;
protected JawList kidList;
public SexButton(String title,Swimmers sw,
JawList klist,ActionListener al){
super(title);
swimmers=sw;
kidList=klist;
addActionListener(al);
}
//abstract execute method
public abstract void execute();
}
public class FemaleButton extends SexButton{
public execute(){
Vector v=swimmers.getList(true);
loadList(v);
}
private void loadList(Vector v){
kidList.clear();
for(int i=0;i Swimmer swm=(Swimmer)v.elementAt(i);
kidList.add(swm.getName());
}
}
}
Command cmd=(Command)e.getSource();
cmd.execute();
}
[1] [2]
本文通过实例演示如何利用Command模式改进Swing事件处理机制,提高程序的可读性、可扩展性和可维护性。

被折叠的 条评论
为什么被折叠?



