Java编程思想第4版[中文版](PDF格式)-第116部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
〃MOUSE clicked〃;
showMouse(e);
}
public void mousePressed(MouseEvent e) {
display。evnt'Display。MOUSE' =
〃MOUSE pressed〃;
showMouse(e);
}
public void mouseReleased(MouseEvent e) {
display。evnt'Display。MOUSE' =
〃MOUSE released〃;
showMouse(e);
}
public void mouseEntered(MouseEvent e) {
display。evnt'Display。MOUSE' =
〃MOUSE entered〃;
showMouse(e);
}
public void mouseExited(MouseEvent e) {
display。evnt'Display。MOUSE' =
〃MOUSE exited〃;
showMouse(e);
}
void showMouse(MouseEvent e) {
display。evnt'Display。MOUSE' +=
〃; x = 〃 + e。getX() +
〃; y = 〃 + e。getY();
repaint();
}
}
class MML implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
display。evnt'Display。MOUSE_MOVE' =
〃MOUSE dragged〃;
showMouse(e);
}
public void mouseMoved(MouseEvent e) {
display。evnt'Display。MOUSE_MOVE' =
〃MOUSE moved〃;
showMouse(e);
}
void showMouse(MouseEvent e) {
display。evnt'Display。MOUSE_MOVE' +=
〃; x = 〃 + e。getX() +
〃; y = 〃 + e。getY();
repaint();
}
}
}
441
…………………………………………………………Page 443……………………………………………………………
class MyButton extends Button {
int clickCounter;
String label = 〃〃;
public MyButton() {
addActionListener(new AL());
}
public void paint(Graphics g) {
g。setColor(Color。green);
Dimension s = getSize();
g。fillRect(0; 0; s。width; s。height);
g。setColor(Color。black);
g。drawRect(0; 0; s。width 1; s。height 1);
drawLabel(g);
}
private void drawLabel(Graphics g) {
FontMetrics fm = g。getFontMetrics();
int width = fm。stringWidth(label);
int height = fm。getHeight();
int ascent = fm。getAscent();
int leading = fm。getLeading();
int horizMargin =
(getSize()。width width)/2;
int verMargin =
(getSize()。height height)/2;
g。setColor(Color。red);
g。drawString(label; horizMargin;
verMarg in + ascent + leading);
}
class AL implements ActionListener {
public void actionPerformed(ActionEvent e) {
clickCounter++;
label = 〃click #〃 + clickCounter +
〃 〃 + e。toString();
repaint();
}
}
}
public class GoodTechnique extends Frame {
GoodTechnique() {
setLayout(new GridLayout(2;2));
add(new EnabledPanel(1; Color。cyan));
add(new EnabledPanel(2; Color。lightGray));
add(new EnabledPanel(3; Color。yellow));
}
public static void main(String'' args) {
Frame f = new GoodTechnique();
f。setTitle(〃Good Technique〃);
f。addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e){
System。out。println(e);
442
…………………………………………………………Page 444……………………………………………………………
System。out。println(〃Window Closing〃);
System。exit(0);
}
});
f。setSize(700;700);
f。setVisible(true);
}
} ///:~
这个程序例子同样证明了各种各样的发现和显示关于它们的信息的事件。这种显示是一种集中显示信息的方
法。一组字符串去获取关于每种类型的事件的信息,并且 show()方法对任何图像对象都设置了一个句柄,我
们采用并直接地写在外观代码上。这种设计是有意的被某种事件重复使用。
激活面板代表了这种新型的组件。它是一个底部有一个按钮的彩色的面板,并且它由利用接收器类为每一个
单独的事件来引发捕捉所有发生在它之上的事件,除了那些在激活面板过载的老式的 processEvent()方法
(注意它应该同样调用super。processEvent())。利用这种方法的唯一理由是它捕捉发生的每一个事件,因
此我们可以观察持续发生的每一事件。processEvent()方法没有更多的展示代表每个事件的字符串,否则它
会不得不使用一串条件语句去寻找事件。在其它方面,内嵌接收类早已清晰地知道被发现的事件。(假定我
们注册它们到组件,我们不需要任何的控件的逻辑,这将成为我们的目的。)因此,它们不会去检查任何事
件;这些事件正好做它们的原材料。
每个接收器修改显示字符串和它的指定事件,并且调用重画方法repaint()因此将显示这个字符串。我们同
样能注意到一个通常能消除闪烁的秘诀:
public void update(Graphics g) {
paint(g);
}
我们不会始终需要过载 update() ,但如果我们写下一些闪烁的程序,并运行它。默认的最新版本的清除背景
然后调用paint()方法重新画出一些图画。这个清除动作通常会产生闪烁,但是不必要的,因为paint()重画
了整个的外观。
我们可以看到许多的接收器——但是,对接收器输入检查指令,但我们却不能接收任何组件不支持的事件。
(不像BadTechnuque。java 那样我们能时时刻刻看到)。
试验这个程序是十分的有教育意义的,因为我们学习了许多的关于在Java 中事件发生的方法。一则它展示了
大多数开窗口的系统中设计上的瑕疵:它相当的难以去单击和释放鼠标,除非移动它,并且当我们实际上正
试图用鼠标单击在某物体上时开窗口的会常常认为我们是在拖动。一个解决这个问题的方案是使用
mousePressed() 鼠标按下方法和mouseReleased()鼠标释放方法去代替mouseClicked() 鼠标单击方法,然后
判断是否去调用我们自己的以时间和4 个像素的鼠标滞后作用的“mouseReallyClicked()真实的鼠标单击”
方法。
5。 蹩脚的组件继承
另一种做法是调用 enableEvent()方法,并将与希望控制的事件对应的模型传递给它(许多参考书中都曾提
及这种做法)。这样做会造成那些事件被发送至老式方法(尽管它们对Java 1。1 来说是新的),并采用象
processFocusEvent()这样的名字。也必须要记住调用基础类版本。下面是它看起来的样子。
//: BadTechnique。java
// It's possible to override ponents this way;
// but the listener approach is much better; so
// why would you?
import java。awt。*;
import java。awt。event。*;
class Display {
public static final int
EVENT = 0; PONENT = 1;
MOUSE = 2; MOUSE_MOVE = 3;
443
…………………………………………………………Page 445……………………………………………………………
FOCUS = 4; KEY = 5; ACTION = 6;
LAST = 7;
public String'' evnt;
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);
// Type checking is lost。 You can enable and
// process events that the ponent doesn't
// capture:
enableEvents(
// Panel doesn't handle these:
AWTEvent。ACTION_EVENT_MASK |
AWTEvent。ADJUSTMENT_EVENT_MASK |
AWTEvent。ITEM_EVENT_MASK |
AWTEvent。TEXT_EVENT_MASK |
AWTEvent。WINDOW_EVENT_MASK |
// Panel can handle these:
AWTEvent。PONENT_EVENT_MASK |
AWTEvent。FOCUS_EVENT_MASK |
AWTEvent。KEY_EVENT_MASK |
AWTEvent。MOUSE_EVENT_MASK |
AWTEvent。MOUSE_MOTION_EVENT_MASK |
AWTEvent。CONTAINER_EVENT_MASK);
// You can enable an event without
// overriding its process method。
}
// 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);
444
…………………………………………………………Page 446……………………………………………………………
display。show(g);
}
public void processEvent(AWTEvent e) {
display。evnt'Display。EVENT'= e。toString();
repaint();
super。processEvent(e);
}
public void
processponentEvent(ponentEvent e) {
switch(e。getID()) {
case ponentEvent。PONENT_MOVED:
display。evnt'Display。PONENT' =
〃ponent moved〃;
break;
case ponentEvent。PONENT_RESIZED:
display。evnt'Display。PONENT' =
〃ponent resized〃;
break;
case ponentEvent。PONENT_HIDDEN:
display。evnt'Display。PONENT' =
〃ponent hidden〃;
break;
case ponentEvent。PONENT_SHOWN:
display。evnt'Display。PONENT' =
〃ponent shown〃;
break;
default:
}
repaint();
// Must always remember to call the 〃super〃
// version of whatever you override:
super。processponentEvent(e);
}
public void processFocusEvent(FocusEvent e) {
switch(e。getID()) {
case FocusEvent。FOCUS_GAINED:
display。evnt'Display。FOCUS' =
〃FOCUS gained〃;
break;
case FocusEvent。FOCUS_LOST:
display。evnt'Display。FOCUS' =
〃FOCUS lost〃;
break;
default:
}
repaint();
super。processFocusEvent(e);
}
public void processKeyEvent(KeyEvent e) {
switch(e。getID()) {
case KeyEvent。KEY_PRESSED:
display。evnt'Display。KEY' =
445
…………………………………………………………Page 447……………………………………………………………
〃KEY pressed: 〃;
break;
case KeyEvent。KEY_RELEASED:
display。evnt'