友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

Java编程思想第4版[中文版](PDF格式)-第104部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


        public void windowClosing(WindowEvent e){  

          System。exit(0);  

        }  

      });  

    f。setSize(300;200);  

    f。show();  

  }  

} ///:~  

  

这个例子采取的新手法包括:  

(1) 在每个按钮上附着不少于一个的接收器。通常,组件把事件作为多造型处理,这意味着我们可以为单个 

事件注册许多接收器。当在特殊的组件中一个事件作为单一造型被处理时,我们会得到 

TooManyListenersException (即太多接收器异常)。  



                                                                                          432 


…………………………………………………………Page 434……………………………………………………………

(2) 程序执行期间,接收器动态地被从按钮B2 中增加和删除。增加用我们前面见到过的方法完成,但每个组 

件同样有一个removeXXXListener() (删除XXX 接收器)方法来删除各种类型的接收器。  

  

这种灵活性为我们的编程提供了更强大的能力。  

我们注意到事件接收器不能保证在命令他们被增加时可被调用(虽然事实上大部分的执行工作都是用这种方 

法完成的)。  



13。16。6 将事务逻辑与 UI 逻辑区分开  



一般而言,我们需要设计我们的类如此以至于每一类做“一件事”。当涉及用户接口代码时就更显得尤为重 

要,因为它很容易地封装“您要做什么”和“怎样显示它”。这种有效的配合防止了代码的重复使用。更不 

用说它令人满意的从GUI 中区分出我们的“事物逻辑”。使用这种方法,我们可以不仅仅更容易地重复使用 

事物逻辑,它同样可以更容易地重复使用 GUI。  

其它的争议是“动作对象”存在的完成分离机器的多层次系统。动作主要的定位规则允许所有新事件修改后 

立刻生效,并且这是如此一个引人注目的设置系统的方法。但是这些动作对象可以被在一些不同的应用程序 

使用并且因此不会被一些特殊的显示模式所约束。它们会合理地执行动作操作并且没有多余的事件。  

下面的例子演示了从GUI 代码中多么地轻松的区分事物逻辑:  

  

//: Separation。java  

// Separating GUI logic and business objects  

import java。awt。*;  

import java。awt。event。*;  

import java。applet。*;  

  

class BusinessLogic {  

  private int modifier;  

  BusinessLogic(int mod) {  

    modifier = mod;  

  }  

  public void setModifier(int mod) {  

    modifier = mod;  

  }  

  public int getModifier() {  

    return modifier;  

  }  

  // Some business operations:  

  public int calculation1(int arg) {  

    return arg * modifier;  

  }  

  public int calculation2(int arg) {  

    return arg + modifier;  

  }  

}  

  

public class Separation extends Applet {  

  TextField   

    t = new TextField(20);  

    mod = new TextField(20);  

  BusinessLogic bl = new BusinessLogic(2);  

  Button  

    calc1 = new Button(〃Calculation 1〃);  

    calc2 = new Button(〃Calculation 2〃);  

  public void init() {  



                                                                                           433 


…………………………………………………………Page 435……………………………………………………………

    add(t);  

    calc1。addActionListener(new Calc1L());  

    calc2。addActionListener(new Calc2L());  

    add(calc1); add(ca lc2);  

    mod。addTextListener(new ModL());  

    add(new Label(〃Modifier:〃));  

    add(mod);  

  }  

  static int getValue(TextField tf) {  

    try {  

      return Integer。parseInt(tf。getText());  

    } catch(NumberFormatException e) {  

      return 0;  

    }  

  }  

  class Calc1L implements ActionListener {  

    public void actionPerformed(ActionEvent e) {  

      t。setText(Integer。toString(  

        bl。calculation1(getValue(t))));  

    }  

  }  

  class Calc2L implements ActionListener {  

    public void actionPerformed(ActionEvent e) {  

      t。setText(Integer。toString(  

        bl。calculation2(getValue(t))));  

    }  

  }  

  class ModL implements TextListener {  

    public void textValueChanged(TextEvent e) {  

      bl。setModifier(getValue(mod));  

    }  

  }  

  public static void main(String'' args) {  

    Separation applet = new Separation();  

    Frame aFrame = new Frame(〃Separation〃);  

    aFrame。addWindowListener(  

      new WindowAdapter() {  

        public void windowClosing(WindowEvent e) {  

          System。exit(0);  

        }  

      });  

    aFrame。add(applet; BorderLayout。CENTER);  

    aFrame。setSize(200;200);  

    applet。init();  

    applet。start();  

    aFrame。setVisible(true);  

  }  

} ///:~  

  

可以看到,事物逻辑是一个直接完成它的操作而不需要提示并且可以在GUI 环境下使用的类。它正适合它的 

工作。区分动作记录了所有UI 的详细资料,并且它只通过它的公共接口与事物逻辑交流。所有的操作围绕中 

心通过UI 和事物逻辑对象来回获取信息。因此区分,轮流做它的工作。因为区分中只知道它同事物逻辑对象 



                                                                                          434 


…………………………………………………………Page 436……………………………………………………………

对话(也就是说,它没有高度的结合),它可以被强迫同其它类型的对象对话而没有更多的烦恼。  

思考从事物逻辑中区分 UI 的条件,同样思考当我们调整传统的Java 代码使它运行时,怎样使它更易存活。  



13。16。7 推荐编码方法  



内部类是新的事件模型,并且事实上旧的事件模型连同新库的特征都被它好的支持,依赖老式的编程方法无 

疑增加了一个新的混乱的因素。现在有更多不同的方法为我们编写讨厌的代码。凑巧的是,这种代码显现在 

本书中和程序样本中,并且甚至在文件和程序样本中同SUN 公司区别开来。在这一节中,我们将看到一些关 

于我们会和不会运行新 AWT 的争执,并由向我们展示除了可以原谅的情况,我们可以随时使用接收器类去解 

决我们的事件处理需要来结束。因为这种方法同样是最简单和最清晰的方法,它将会对我们学习它构成有效 

的帮助。  

在看到任何事以前,我们知道尽管 Java 1。1 向后兼容Java 1。0 (也就是说,我们可以在1。1 中编译和运行 

1。0 的程序),但我们并不能在同一个程序里混合事件模型。换言之,当我们试图集成老的代码到一个新的 

程序中时,我们不能使用老式的action()方法在同一个程序中,因此我们必须决定是否对新程序使用老的, 

难以维护的方法或者升级老的代码。这不会有太多的竞争因为新的方法对老的方法而言是如此的优秀。  

  

1。 准则:运行它的好方法  

为了给我们一些事物来进行比较,这儿有一个程序例子演示向我们推荐的方法。到现在它会变得相当的熟悉 

和舒适。  

  

//: GoodIdea。java  

// The best way to design classes using the new  

// Java 1。1 event model: use an inner class for  

// each different event。 This maximizes   

// flexibility and modularity。  

import java。awt。*;  

import java。awt。event。*;  

import java。util。*;  

  

public class GoodIdea extends Frame {  

  Button   

    b1 = new Button(〃Button 1〃);   

    b2 = new Button(〃Button 2〃);  

  public GoodIdea() {  

    setLayout(new FlowLayout());  

    b1。addActionListener(new B1L());  

    b2。addActionListener(new B2L());  

    add(b1);  

    add (b2);  

  }  

  public class B1L implements ActionListener {  

    public void actionPerformed(ActionEvent e) {  

      System。out。println(〃Button 1 pressed〃);  

    }  

  }  

  public class B2L implements ActionListener {  

    public void actionPerformed(ActionEvent e) {  

      System。out。println(〃Button 2 pressed〃);  

    }  

  }  

  public static void main(String'' args) {  

    Frame f = new GoodIdea();  

    f。addWindowListener(  



                                                                                          435 


…………………………………………………………Page 437……………………………………………………………

      new WindowAdapter() {  

        public void windowClosing(WindowEvent e){  

          System。out。println(〃Window Closing〃);  

          System。exit(0);  

        }  

      });  

    f。setSize(300;200);  

    f。setVisible(true);  

  }  

} ///:~  

  

这是颇有点微不足道的:每个按钮有它自己的印出一些事物到控制台的接收器。但请注意在整个程序中这不 

是一个条件语句,或者是一些表示“我想要知道怎样使事件发生”的语句。每块代码都与运行有关,而不是 

类型检验。也就是说,这是最好的编写我们的代码的方法;不仅仅是它更易使我们理解概念,至少是使我们 

更易阅读和维护。剪切和粘贴到新的程序是同样如此的容易。  

  

  

2。 将主类作为接收器实现  

第一个坏主意是一个通常的和推荐的方法。这使得主类(有代表性的是程序片或帧,但它能变成一些类)执 

行各种不同的接收器。下面是一个例子:  

  

//: BadIdea1。java  

// Some literature remends this approach;  

// but it's missing the point of the new event  

// model in Java 1。1  

import java。awt。*;  

import java。awt。event。*;  

import java。util。*;  

  

public class BadIdea1 extends Frame   

    implements ActionListener; WindowListener {  

  Button   

    b1 = new Button(〃Button 1〃);   

    b2 = new Button(〃Button 2〃);  

  public BadIdea1() {  

    setLayout(new FlowLayout());  

    addWindowListener(this);  

    b1。addActionListener(this);  

    b2。addActionListener(this);  

    add(b1);  

    add(b2);  

  }  

  public void actionPerformed(ActionEvent e) {  

    Object source = e。getSource();  

    if(source == b1)  

      System。out。println(〃Button 1 pressed〃);  

    else if(source == b2)  

      System。out。println(〃Button 2 pressed〃);  

    else  

      System。out。println(〃Something else〃);  

  }      

  public void windowClosing(WindowEvent e) {  



                                                                                          436 


…………………………………………………………Page 438……………………………………………………………

    System。out。println(〃Window Closing〃);  

    System。exit(0);  

  }  

  public void windowClosed(WindowEvent e) {}  

  public void windowDeiconified(WindowEvent e) {}  

  public void windowIconified(WindowEvent e) {}  

  public void windowActivated(WindowEvent e) {}  

  public void windowDeactivated (WindowEvent e) {}  

  public void windowOpened(WindowEvent e) {}    

  

  public static void main(String'' args) {  

    Frame f = new BadIdea1();  

    f。setSize(300;200);  

    f。setVisible(true);  

  }  

} ///:~  

  

这样做的用途显示在下述三行里:  

addWindowListener(this);  

b1。addActionListener(this);  

b2。addActionListener(this);  

因为Badidea1 执行动作接收器和窗中接收器,这些程序行当然可以接受,并且如果我们一直坚持设法使少量 

的类去减少服务器检索期间的程序片载入的作法,它看起来变成一个不错的主意。但是:  

(1) Java 1。1版支持 JAR 文件,因此所有我们的文件可以被放置到一个单一的压缩的JAR 文件中,只需要一 

次服务器检索。我们不再需要为Internet 效率而减少类的数量。  

(2) 上面的代码的组件更加的少,因此它难以抓住和粘贴。注意我们必须不仅要执行各种各样的接口为我们 

的主类,但在actionPerformed()方法中,我们利用一串条件语句测试哪个动作被完成了。不仅仅是这个状 

态倒退,远离接收器模型,除此之外,我们不能简单地重复使用actionPerformed()方法因为它是指定为这 

个特殊的应用程序使用的。将这个程序例子与 GoodIdea。java 进行比较,我们可以正好捕捉一个接收器类并 

粘贴它和最小的焦急到任何地方。另外我们可以为一个单独的事件注册多个接收器类,允许甚至更多的模块 

在每个接收器类在每个接收器中运行。  

  

3。 方法的混合  

第二个bad idea 混合了两种方法:使用内嵌接收器类,但同样执行一个或更多的接收器接口以作为主类的一 

部分。这种方法无需在书中和文件中进行解释,而且我可以臆测到Java 开发者认为他们必须为不同的目的而 

采取不同的方法。但我们却不必——在我们编程时,我们或许可能会倾向于使用内嵌接收器类。  

  

//: BadIdea2。java  

// An improvement over BadIdea1。java
返回目录 上一页 下一页 回到顶部 1 1
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!