Java编程思想第4版[中文版](PDF格式)-第115部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
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; since it
// uses the WindowAdapter as an inner class
// instead of implementing all the methods of
// WindowListener; but still misses the
// valuable modularity of inner classes
import java。awt。*;
import java。awt。event。*;
import java。util。*;
public class BadIdea2 extends Frame
implements ActionListener {
Button
b1 = new Button(〃Button 1〃);
b2 = new Button(〃Button 2〃);
437
…………………………………………………………Page 439……………………………………………………………
public BadIdea2() {
setLayout(new FlowLayout());
addWindowListener(new WL());
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〃);
}
class WL extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System。out。println(〃Window Closing〃);
System。exit(0);
}
}
public static void main(String'' args) {
Frame f = new BadIdea2();
f。setSize(300;200);
f。setVisible(true);
}
} ///:~
因为actionPerformed()动作完成方法同主类紧密地结合,所以难以复用代码。它的代码读起来同样是凌乱
和令人厌烦的,远远超过了内部类方法。不合理的是,我们不得不在 Java 1。1 版中为事件使用那些老的思
路。
4。 继承一个组件
创建一个新类型的组件时,在运行事件的老方法中,我们会经常看到不同的地方发生了变化。这里有一个程
序例子来演示这种新的工作方法:
//: GoodTechnique。java
// Your first choice when overriding ponents
// should be to install listeners。 The code is
// much safer; more modular and maintainable。
import java。awt。*;
import java。awt。event。*;
class Display {
public static final int
EVENT = 0; PONENT = 1;
MOUSE = 2; MOUSE_MOVE = 3;
FOCUS = 4; KEY = 5; ACTION = 6;
LAST = 7;
public String'' evnt;
438
…………………………………………………………Page 440……………………………………………………………
Display() {
evnt = new String'LAST';
for(int i = 0; i 《 LAST; i++)
evnt'i' = new String();
}
public void show(Graphics g) {
for(int i = 0; i 《 LAST; i++)
g。drawString(evnt'i'; 0; 10 * i + 10);
}
}
class EnabledPanel extends Panel {
Color c;
int id;
Display display = new Display();
public EnabledPanel(int i; Color mc) {
id = i;
c = mc;
setLayout(new BorderLayout());
add(new MyButton(); BorderLayout。SOUTH);
addponentListener(new CL());
addFocusListener(new FL());
addKeyListener(new KL());
addMouseListener(new ML());
addMouseMotionListener(new MML());
}
// To eliminate flicker:
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g。setColor(c);
Dimension s = getSize();
g。fillRect(0; 0; s。width; s。height);
g。setColor(Color。black);
display。show(g);
}
// Don't need to enable anything for this:
public void processEvent(AWTEvent e) {
display。evnt'Display。EVENT'= e。toString();
repaint();
super。processEvent(e);
}
class CL implements ponentListener {
public void ponentMoved(ponentEvent e){
display。evnt'Display。PONENT' =
〃ponent moved〃;
repaint();
}
public void
ponentResized(ponentEvent e) {
display。evnt'Display。PONENT' =
439
…………………………………………………………Page 441……………………………………………………………
〃ponent resized〃;
repaint();
}
public void
ponentHidden(ponentEvent e) {
display。evnt'Display。PONENT' =
〃ponent hidden〃;
repaint();
}
public void ponentShown(ponentEvent e){
display。evnt'Display。PONENT' =
〃ponent shown〃;
repaint();
}
}
class FL implements FocusListener {
public void focusGained(FocusEvent e) {
display。evnt'Display。FOCUS' =
〃FOCUS gained〃;
repaint();
}
public void focusLost(FocusEvent e) {
display。evnt'Display。FOCUS' =
〃FOCUS lost〃;
repaint();
}
}
class KL implements KeyListener {
public void keyPressed(KeyEvent e) {
display。evnt'Display。KEY' =
〃KEY pressed: 〃;
showCode(e);
}
public void keyReleased (KeyEvent e) {
display。evnt'Display。KEY' =
〃KEY released: 〃;
showCode(e);
}
public void keyTyped(KeyEvent e) {
display。evnt'Display。KEY' =
〃KEY typed: 〃;
showCode(e);
}
void showCode(KeyEvent e) {
int code = e。getKeyCode();
display。evnt'Display。KEY' +=
KeyEvent。getKeyText(code);
repaint();
}
}
class ML implements MouseListener {
public void mouseClicked(MouseEvent e) {
440
…………………………………………………………Page 442……………………………………………………………
requestFocus(); // Get FOCUS on click
display。evnt'Display。MOUSE' =
〃MOUSE clicked〃;
showMouse(e);
}
public void mo