Java编程思想第4版[中文版](PDF格式)-第113部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
public void actionPerformed(ActionEvent e) {
t。setText(〃Foo selected〃);
}
}
class BarL implements ActionListener {
public void actionPerformed(ActionEvent e) {
t。setText(〃Bar selected〃);
}
}
class BazL implements ActionListener {
public void actionPerformed(ActionEvent e) {
t。setText(〃Baz selected〃);
}
}
class CMIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
CheckboxMenuItem target =
(CheckboxMenuItem)e。getSource();
String actionmand =
target。getActionmand();
if(actionmand。equals(〃Guard〃))
t。setText(〃Guard the Ice Cream! 〃 +
〃Guarding is 〃 + target。getState());
else if(actionmand。equals(〃Hide〃))
t。setText(〃Hide the Ice Cream! 〃 +
426
…………………………………………………………Page 428……………………………………………………………
〃Is it cold? 〃 + target。getState());
}
}
public static void main(String'' args) {
MenuNew f = new MenuNew();
f。addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System。exit(0);
}
});
f。setSize(300;200);
f。setVisible(true);
}
} ///:~
在我们开始初始化节(由注解“Initialization code:”后的右大括号指明)的前面部分的代码同先前
(Java 1。0 版)版本相同。这里我们可以注意到项目接收器和动作接收器被附加在不同的菜单组件上。
Java 1。1 支持“菜单快捷键”,因此我们可以选择一个菜单项目利用键盘替代鼠标。这十分的简单;我们只
要使用过载菜单项构建器设置第二个自变量为一个 MenuShortcut (菜单快捷键事件)对象即可。菜单快捷键
构建器设置重要的方法,当它按下时不可思议地显示在菜单项上。上面的例子增加了 Control…E 到“Exit ”
菜单项中。
我们同样会注意 setActionmand()的使用。这看似一点陌生因为在各种情况下“action mand”完全同
菜单组件上的标签一样。为什么不正好使用标签代替可选择的字符串呢?这个难题是国际化的。如果我们重
新用其它语言写这个程序,我们只需要改变菜单中的标签,并不审查代码中可能包含新错误的所有逻辑。因
此使这对检查文字字符串联合菜单组件的代码而言变得简单容易,当菜单标签能改变时“动作指令”可以不
作任何的改变。所有这些代码同“动作指令”一同工作,因此它不会受改变菜单标签的影响。注意在这个程
序中,不是所有的菜单组件都被它们的动作指令所审查,因此这些组件都没有它们的动作指令集。
大多数的构建器同前面的一样,将几个调用的异常增加到接收器中。大量的工作发生在接收器里。在前面例
子的BL 中,菜单交替发生。在ML 中,“寻找ring ”方法被作为动作事件(ActionEvent)的资源并对它进
行造型送入菜单项,然后得到动作指令字符串,再通过它去贯穿串联组,当然条件是对它进行声明。这些大
多数同前面的一样,但请注意如果“Exit ”被选中,通过进入封装类对象的句柄(MenuNew。this)并创建一
个WINDOW_CLOSING 事件,一个新的窗口事件就被创建了。新的事件被分配到封装类对象的dispatchEvent()
方法,然后结束调用windowsClosing() 内部帧的窗口接收器(这个接收器作为一个内部类被创建在main()
里),似乎这是“正常”产生消息的方法。通过这种机制,我们可以在任何情况下迅速处理任何的信息,因
此,它非常的强大。
FL 接收器是很简单尽管它能处理特殊菜单的所有不同的特色。如果我们的逻辑十分的简单明了,这种方法对
我们就很有用处,但通常,我们使用这种方法时需要与FooL,BarL 和BazL 一道使用,它们每个都附加到一
个单独的菜单组件上,因此必然无需测试逻辑,并且使我们正确地辨识出谁调用了接收器。这种方法产生了
大量的类,内部代码趋向于变得小巧和处理起来简单、安全。
7。 对话框
在这个例子里直接重写了早期的ToeTest。java 程序。在这个新的版本里,任何事件都被安放进一个内部类
中。虽然这完全消除了需要记录产生的任何类的麻烦,作为ToeTest。java 的一个例子,它能使内部类的概念
变得不那遥远。在这点,内嵌类被嵌套达四层之深!我们需要的这种设计决定了内部类的优点是否值得增加
更加复杂的事物。另外,当我们创建一个非静态的内部类时,我们将捆绑非静态类到它周围的类上。有时,
单独的类可以更容易地被复用。
//: ToeTestNew。java
// Demonstration of dialog boxes
// and creating your own ponents
import java。awt。*;
427
…………………………………………………………Page 429……………………………………………………………
import java。awt。event。*;
public class ToeTestNew extends Frame {
TextField rows = new TextField(〃3〃);
TextField cols = new TextField(〃3〃);
public ToeTestNew() {
setTitle(〃Toe Test〃);
Panel p = new Panel();
p。setLayout(new GridLayout(2;2));
p。add(new Label(〃Rows〃; Label。CENTER));
p。add(rows);
p。add(new Label(〃Columns〃; Label。CENTER));
p。add(cols);
add(p; BorderLayout。NORTH);
Button b = new Button(〃go〃);
b。addActionListener(new BL());
add(b; BorderLayout。SOUTH);
}
static final int BLANK = 0;
static final int XX = 1;
static fina l int OO = 2;
class ToeDialog extends Dialog {
// w = number of cells wide
// h = number of cells high
int turn = XX; // Start with x's turn
public ToeDialog(int w; int h) {
super(ToeTestNew。this;
〃The game itself〃; false);
setLayout(new GridLayout(w; h));
for(int i = 0; i 《 w * h; i++)
add(new ToeButton());
setSize(w * 50; h * 50);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
dispose();
}
});
}
class ToeButton extends Canvas {
int state = BLANK;
ToeButton() {
addMouseListener(new ML());
}
public void paint(Graphics g) {
int x1 = 0;
int y1 = 0;
int x2 = getSize()。width 1;
int y2 = getSize()。height 1;
g。drawRect(x1; y1; x2; y2);
x1 = x2/4;
y1 = y2/4;
int wide = x2/2;
428
…………………………………………………………Page 430……………………………………………………………
int high = y2/2;
if(state == XX) {
g。drawLine(x1; y1;
x1 + wide; y1 + high);
g。drawLine(x1; y1 + high;
x1 + wide; y1);
}
if(state == OO) {
g。drawOval(x1; y1;
x1 + wide/2; y1 + high/2);
}
}
class ML extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if(state == BLANK) {
state = turn;
turn = (turn == XX ? OO : XX);
}
else
state = (state == XX ? OO : XX);
repaint();
}
}
}
}
class BL implements ActionListener {
public void actionPerformed(ActionEvent e) {
Dialog d = new ToeDialog(
Integer。parseInt(rows。getText());
Integer。parseInt(cols。getText()));
d。show();
}
}
public static void main(String'' args) {
Frame f = new ToeTestNew();
f。addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System。exit(0);
}
});
f。setSize(200;100);
f。setVisible(true);
}
} ///:~
由于“静态”的东西只能位于类的外部一级,所以内部类不可能拥有静态数据或者静态内部类。
8。 文件对话框
这个例子是直接用新事件模型对FileDialogTest。java 修改而来。
//: FileDialogNew。java
429
…………………………………………………………Page 431……………………………………………………………
// Demonstration of File dialog boxes
import java。awt。*;
import java。awt。event。*;
public class FileDialogNew extends Frame {
TextField filename = new TextField();
TextField directory = new TextField();
Button open = new Button(〃Open〃);
Button save = new Button(〃Save〃);
public FileDialogNew() {
setTitle(〃File Dialog Test〃);
Panel p = new Panel();
p。setLayout(new FlowLayout());
open。addActionListener(new OpenL());
p。add(open);
save。addActionListener(new SaveL());
p。add(save);
add(p; BorderLayout。SOUTH);
directory。setEditable(false);
filename。setEditable(false);
p = new Panel();
p。setLayout(new GridLayout(2;1));
p。add(filename);
p。add(directory);
add(p; BorderLayout。NORTH);
}
class OpenL implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Two arguments; defaults to open file:
FileDialog d = new FileDialog(
FileDialogNew。this;
〃What file do you want to open?〃);
d。setFile(〃*。java〃);
d。setDirectory(〃。〃); // Current directory
d。show();
String yourFile = 〃*。*〃;
if((yourFile = d。getFile()) != null) {
filename。setText(yourFile);
directory。setText(d。getDirectory());
} else {
filename。setText(〃You pressed cancel〃);
directory。setText(〃〃);
}
}
}
class SaveL implements ActionListener {
public void actionPerformed(ActionEvent e) {
FileDialog d = new FileDialog(
FileDialogNew。this;
〃What file do you want to save?〃;
FileDialog。SAVE);
d。setFile(〃*。java〃);
430
…………………………………………………………Page 432……………………………………………………………
d。setDirectory(〃。〃);
d。show();
String saveFile;
if((saveFile = d。getFile()) != null) {
filename。setText(saveFile);
directory。setText(d。getDirectory());
} else {