友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
Java编程思想第4版[中文版](PDF格式)-第73部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
getAppletContext()。showStatus(〃Button 1〃);
}
}
class B2 implements ActionListener {
public void actionPerformed(ActionEvent e) {
getAppletContext()。showStatus(〃Button 2〃);
}
}
/* The old way:
public boolean action(Event evt; Object arg) {
if(evt。target。equals(b1))
getAppletContext()。showStatus(〃Button 1〃);
else if(evt。target。equals(b2))
getAppletContext()。showStatus(〃Button 2〃);
// Let the base class handle it:
else
409
…………………………………………………………Page 411……………………………………………………………
return super。action(evt; arg);
return true; // We've handled it here
}
*/
} ///:~
我们可比较两种方法,老的代码在左面作为注解。在 init()方法里,只有一个改变就是增加了下面的两行:
b1。addActionListener(new B1());
b2。addActionListener(new B2());
按钮按下时,addActionListener()通知按钮对象被激活。B1 和B2 类都是执行接口ActionListener 的内部
类。这个接口包括一个单一的方法 actionPerformed() (这意味着当事件激活时,这个动作将被执行)。注
意actionPreformed()方法不是一个普通事件,说得更恰当些是一个特殊类型的事件,ActionEvent。如果我
们想提取特殊ActionEvent 的信息,因此我们不需要故意去测试和下溯造型自变量。
对编程者来说一个最好的事便是actionPerformed()十分的简单易用。它是一个可以调用的方法。同老的
action()方法比较,老的方法我们必须指出发生了什么和适当的动作,同样,我们会担心调用基础类
action()的版本并且返回一个值去指明是否被处理。在新的事件模型中,我们知道所有事件测试推理自动进
行,因此我们不必指出发生了什么;我们刚刚表示发生了什么,它就自动地完成了。如果我们还没有提出用
新的方法覆盖老的方法,我们会很快提出。
13。16。2 事件和接收者类型
所有AWT 组件都被改变成包含addXXXListener()和removeXXXListener()方法,因此特定的接收器类型可从
每个组件中增加和删除。我们会注意到“XXX”在每个场合中同样表示自变量的方法,例如,
addFooListener(FooListener fl)。下面这张表格总结了通过提供addXXXListener()和 removeXXXListener()
方法,从而支持那些特定事件的相关事件、接收器、方法以及组件。
事件,接收器接口及添加和删除方法 支持这个事件的组件
Event; listener interface and C o m p o n e n t s s u p p o r t i n g t h i s e v e n t
add a n d r e m o v e m e t h o d s
A c t i o n E v e n t B u t t o n ; L i s t ; T e x t F i e l d ; M e n u I t e m ; and its derivatives
A c t i o n L i s t e n e r including C h e c k b o x M e n u I t e m ; M e n u ; and P o p u p M e n u
a d d A c t i o n L i s t e n e r ( )
r e m o v e A c t i o n L i s t e n e r ( )
A d j u s t m e n t E v e n t S c r o l l b a r
A d j u s t m e n t L i s t e n e r Anything you create that implements the Adjustable interface
a d d A d j u s t m e n t L i s t e n e r ( )
removeAdjustmentListener( )
C o m p o n e n t E v e n t C o m p o n e n t and its derivatives; including Button; Canvas;
C o m p o n e n t L i s t e n e r Checkbox ; Choice; Container ; Panel ; Applet ; ScrollPane;
a d d C o m p o n e n t L i s t e n e r ( ) Window ; Dialog ; FileDialog; Frame ; Label; List ; Scrollbar;
removeponentListener( ) T e x t A r e a ; and T e x t F i e l d
C o n t a i n e r E v e n t C o n t a i n e r and its derivatives; including Panel ; Applet ;
C o n t a i n e r L i s t e n e r S c r o l l P a n e ; W i n d o w ; D i a l o g ; F i l e D i a l o g ; and Frame
a d d C o n t a i n e r L i s t e n e r ( )
removeContainerListener( )
F o c u s E v e n t C o m p o n e n t and its derivatives; including Button; Canvas;
F o c u s L i s t e n e r Checkbox ; Choice; Container ; Panel ; Applet ; ScrollPane;
a d d F o c u s L i s t e n e r ( ) Window ; Dialog ; FileDialog; Frame Label; List ; Scrollbar;
r e m o v e F o c u s L i s t e n e r ( ) T e x t A r e a ; and T e x t F i e l d
K e y E v e n t C o m p o n e n t and its derivatives; including Button; Canvas;
410
…………………………………………………………Page 412……………………………………………………………
K e y L i s t e n e r Checkbox ; Choice; Container ; Panel ; Applet ; ScrollPane;
a d d K e y L i s t e n e r ( ) Window ; Dialog ; FileDialog; Frame ; Label; List ; Scrollbar;
r e m o v e K e y L i s t e n e r ( ) T e x t A r e a ; and T e x t F i e l d
M o u s e E v e n t (for both clicks and C o m p o n e n t and its derivatives; including Button; Canvas;
motion) Checkbox ; Choice; Container ; Panel ; Applet ; ScrollPane;
M o u s e L i s t e n e r Window ; Dialog ; FileDialog; Frame ; Label; List ; Scrollbar;
a d d M o u s e L i s t e n e r ( ) T e x t A r e a ; and T e x t F i e l d
r e m o v e M o u s e L i s t e n e r ( )
M o u s e E v e n t '55' (for both clicks C o m p o n e n t and its derivatives; including Button; Canvas;
and motion) Checkbox ; Choice; Co ntainer ; Panel ; Applet ; ScrollPane;
M o u s e M o t i o n L i s t e n e r Window ; Dialog ; FileDialog; Frame ; Label; List ; Scrollbar;
addMouseMotionListener( ) T e x t A r e a ; and T e x t F i e l d
removeMouseMotionListener( )
W i n d o w E v e n t Window and its derivatives; including Dialog; FileDialog; and
W i n d o w L i s t e n e r F r ame
a d d W i n d o w L i s t e n e r ( )
r e m o v e W i n d o w L i s t e n e r ( )
I t e m E v e n t Checkbox ; CheckboxMenuItem ; Choice ; List; and anything that
I t e m L i s t e n e r implements the I t e m S e l e c t a b l e interface
a d d I t e m L i s t e n e r ( )
r e m o v e I t e m L i s t e n e r ( )
T e x t E v e n t Anything derived from Textponent ; including TextArea and
T e x t L i s t e n e r T e x t F i e l d
a d d T e x t L i s t e n e r ( )
r e m o v e T e x t L i s t e n e r ( )
⑤:即使表面上如此,但实际上并没有MouseMotiionEvent (鼠标运动事件)。单击和运动都合成到
MouseEvent 里,所以 MouseEvent 在表格中的这种另类行为并非一个错误。
可以看到,每种类型的组件只为特定类型的事件提供了支持。这有助于我们发现由每种组件支持的事件,如
下表所示:
组件类型 支持的事件
C o m p o n e n t t y p e E v e n t s s u p p o r t e d b y t h i s c o m p o n e n t
A d j u s t a b l e A d j u s t m e n t E v e n t
A p p l e t Conta inerEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
B u t t o n ActionEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
C a n v a s F o c u s E v e n t ; K e y E v e n t ; M o u s e E v e n t ; C o m p o n e n t E v e n t
C h e c k b o x ItemEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
CheckboxMenuItem A c t i o n E v e n t ; I t e m E v e n t
C h o i c e ItemEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
C o m p o n e n t F o c u s E v e n t ; K e y E v e n t ; M o u s e E v e n t ; C o m p o n e n t E v e n t
C o n t a i n e r ContainerEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
411
…………………………………………………………Page 413……………………………………………………………
D i a l o g Co ntainerEvent; WindowEvent; FocusEvent; KeyEvent; MouseEvent;
C o m p o n e n t E v e n t
F i l e D i a l o g ContainerEvent; WindowEvent; FocusEvent; KeyEvent; MouseEvent;
C o m p o n e n t E v e n t
F r a m e ContainerEvent; WindowEvent; FocusEvent; KeyEvent; MouseEvent;
C o m p o n e n t E v e n t
L a b e l F o c u s E v e n t ; K e y E v e n t ; M o u s e E v e n t ; C o m p o n e n t E v e n t
L i s t ActionEvent; FocusEvent; KeyEvent; MouseEvent; ItemEvent; ponentEvent
M e n u A c t i o n E v e n t
M e n u I t e m A c t i o n E v e n t
P a n e l ContainerEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
P o p u p M e n u Act i o n E v e n t
S c r o l l b a r AdjustmentEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
S c r o l l P a n e ContainerEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
T e x t A r e a TextEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
T e x t C o m p o n e n t T e x t E v e n t; FocusEvent; KeyEvent; MouseEvent; ponentEvent
T e x t F i e l d ActionEvent; TextEvent; FocusEvent; KeyEvent; MouseEvent; ponentEvent
W i n d o w ContainerEvent; WindowEvent; FocusEvent; KeyEvent; MouseEvent;
C o m p o n e n t E v e n t
一旦知道了一个特定的组件支持哪些事件,就不必再去寻找任何东西来响应那个事件。只需简单地:
(1) 取得事件类的名字,并删掉其中的“Event”字样。在剩下的部分加入“Listener ”字样。这就是在我们
的内部类里需要实现的接收器接口。
(2) 实现上面的接口,针对想要捕获的事件编写方法代码。例如,假设我们想捕获鼠标的移动,所以需要为
MouseMotiionListener 接口的 mouseMoved()方法编写代(当然还必须实现其他一些方法,但这里有捷径可
循,马上就会讲到这个问题)。
(3) 为步骤 2 中的接收器类创建一个对象。随自己的组件和方法完成对它的注册,方法是在接收器的名字里
加入一个前缀“add”。比如addMouseMotionListener()。
下表是对接收器接口的一个总结:
接收器接口 接口中的方法
Listener interface M e t h o d s i n i n t e r f a c e
w / a d a p t e r
A c t i o n L i s t e n e r actionPerformed(ActionEvent)
AdjustmentListener a d j u s t m e n t V a l u e C h a n g e d (
A d j u s t m e n t E v e n t )
ponentListener ponentHidden(ponentEvent)
ponentAdapter ponentShown(ponentEvent)
ponentMoved(ponentEvent)
ponentResized(ponentEvent)
ContainerListener ponentAdded(ContainerEvent)
ContainerAdapter ponentRemoved(ContainerEvent)
F o c u s L i s t e n e r f o c u s G a i n e d ( F o c u s E v e n t )
412
…………………………………………………………Page 414……………………………………………………………
F o c u s A d a p t e r f o c u s L o s t ( F o c u s E v e n t )
K e y L i s t e n e r k e y P r e s s e d ( K e y E v e n t )
K e y A d a p t e r k e y R e l e a s e d ( K e y E v e n t )
k e y T y p e d ( K e y E v e n t )
M o u s e L i s t e n e r m o u s e C l i c k e d ( M o u s e E v e n t )
M o u s e A d a p t e r m o u s e E n t e r e d ( M o u s e E v e n t )
m o u s e E x i t e d ( M o u s e E v e n t )
m o u s e P r e s s e d ( M o u s e E v e n t )
m o u s e R e l e a s e d ( M o u s e E v e n t )
MouseMotionListener m o u s e D r a g g e d ( M o u s e E v e n t )
MouseMotionAdapter m o u s e M o v e d ( M o u s e E v e n t )
W i n d o w L i s t e n e r w i n d o w O p e n e d ( W i n d o w E v e n t )
W i n d o w A d a p t e r windowClosing(WindowEvent)
w i n d o w C l o sed(WindowEvent)
windowActivated(WindowEvent)
windowDeactivated(WindowEvent)
windowIconified(WindowEvent)
windowDeiconified(WindowEvent)
I t e m L i s t e n e r itemStateChanged(ItemEvent)
T e x t L i s t e n e r textValueChanged(TextEvent)
1。 用接收器适配器简化操作
在上面的表格中,我们可以注意到一些接收器接口只有唯一的一个方法。它们的执行是无轻重的,因为我们
仅当需要书写特殊方法时才会执行它们。然而,接收器接口拥有多个方法,使用起来却不太友好。例如,我
们必须一直运行某些事物,当我们创建一个应用程序时对帧提供一个WindowListener,以便当我们得到
windowClosing()事件时可以调用 System。exit(0)以退出应用程序。但因为WindowListener 是一个接口,我
们必须执行其它所有的方法即使它们不运行任何事件。这真令人讨厌。
为了解决这个问题,每个拥有超过一个方法的接收器接口都可拥有适配器,它们的名我们可以在上面的表格
中看到。每个适配器为每个接口方法提供默认的方法。(WindowAdapter 的默认方法不是windowClosing(),
而是System。exit(0)方法。)此外我们所要做的就是从适配器处继承并过载唯一的需要变更的方法。例如,
典型的WindowListener 我们会像下面这样的使用。
class MyWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System。exit(0);
}
}
适配器的全部宗旨就是使接收器的创建变得更加简便。
但所谓的“适配器”也有一个缺点,而且较难发觉。假定我们象上面那样写一个 WindowAdapter :
class MyWindowListener extends WindowAdapter {
public void WindowClosing(WindowEvent e) {
System。exit(0);
}
}
表面上一切正常,但实际没有任何效果。每个事件的编译和运行都很正常——只是关闭窗口不会退出程序。
您注意到问题在哪里吗?在方法的名字里:是 WindowClosing(),而不是windowClosing()。大小写的一个简
单失误就会造成一个崭新的方法。但是,这并非我们关闭窗口时调用的方法,所以当然没有任何效果。
413
…………………………………………………………Page 415……………………………………………………………
13。16。3 用 Java 1。1 AWT 制作窗口和程序片
我们经常都需要创建一个类,使其既可作为一个窗口调用,亦可作为一个程序片调用。为做到这一点,只需
为程序片简单地加入一个main()即可,令其在一个 Frame (帧)里构建程序片的一个实例。作为一个简单的
示例,下面让我们来看看如何对Button2New。java 作一番修改,使其能同时作为应用程序和程序片使用:
//: Button2NewB。java
// An application and an applet
import java。awt。*;
import java。awt。event。*; // Must add this
import java。applet。*;
public class Button2NewB extends Applet {
Button
b1 = new Button(〃Button 1〃);
b2 = new Button(〃Button 2〃);
TextField t = new TextField(20);
public void init() {
b1。addActionListener(new B1());
b2。addActionListener(new B2());
add(b1);
add(b2);
add(t);
}
class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
t。setText(〃Butto
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!