Java编程思想第4版[中文版](PDF格式)-第108部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
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(〃North〃; p);
405
…………………………………………………………Page 407……………………………………………………………
add(〃South〃; new Button(〃go〃));
}
public boolean handleEvent(Event evt) {
if(evt。id == Event。WINDOW_DESTROY)
System。exit(0);
else
return super。handleEvent(evt);
return true;
}
public boolean action(Event evt; Object arg) {
if(arg。equals(〃go〃)) {
Dialog d = new ToeDialog(
this;
Integer。parseInt(rows。getText());
Integer。parseInt(cols。getText()));
d。show();
}
else
return super。action(evt; arg);
return true;
}
public stat ic void main(String'' args) {
Frame f = new ToeTest();
f。resize(200;100);
f。show();
}
} ///:~
ToeButton 类保留了一个句柄到它 ToeDialog 型的父类中。正如前面所述,ToeButton 和 ToeDialog 高度的结
合因为一个 ToeButton 只能被一个ToeDialog 所使用,但它却解决了一系列的问题,事实上这实在不是一个
糟糕的解决方案因为没有另外的可以记录用户选择的对话类。当然我们可以使用其它的制造ToeDialog。turn
(ToeButton 的静态的一部分)方法。这种方法消除了它们的紧密联系,但却阻止了我们一次拥有多个
ToeDialog (无论如何,至少有一个正常地运行)。
paint()是一种与图形有关的方法:它围绕按钮画出矩形并画出“X”或“O”。这完全是冗长的计算,但却
十分的直观。
一个鼠标单击被过载的 mouseDown()方法所俘获,最要紧的是检查是否有事件写在按钮上。如果没有,父窗
口会被询问以找出谁选择了它并用来确定按钮的状态。值得注意的是按钮随后交回到父类中并且改变它的选
择。如果按钮已经显示这为“X”和“O”,那么它们会被改变状态。我们能注意到本书第三章中描述的在
这些计算中方便的使用的三个一组的 If…else。当一个按钮的状态改变后,按钮会被重画。
ToeDialog 的构建器十分的简单:它像我们所需要的一样增加一些按钮到 GridLayout 布局管理器中,然后调
整每个按钮每边大小为 50 个像素(如果我们不调整窗口,那么它就不会显示出来)。注意 handleEvent()正
好为WINDOW_DESTROY 调用dispose(),因此整个应用程序不会被关闭。
ToeTest 设置整个应用程序以创建 TextField (为输入按钮网格的行和列)和“go”按钮。我们会领会
action()在这个程序中使用不太令人满意的“字符串匹配”技术来测试按钮的按下(请确定我们拼写和大写
都是正确的!)。当按钮按下时,TextField 中的数据将被取出,并且,因为它们在字符串结构中,所以需
要利用静态的 Integer。paresInt()方法来转变成中断。一旦对话类被建立,我们就必须调用 show()方法来显
示和激活它。
我们会注意到ToeDialog 对象赋值给一个对话句柄 d。这是一个上溯造型的例子,尽管它没有真正地产生重
要的差异,因为所有的事件都是show()调用的。但是,如果我们想调用ToeDialog 中已经存在的一些方法,
我们需要对 ToeDialog 句柄赋值,就不会在一个上溯中丢失信息。
1。 文件对话类
406
…………………………………………………………Page 408……………………………………………………………
在一些操作系统中拥有许多的特殊内建对话框去处理选择的事件,例如:字库,颜色,打印机以及类似的事
件。几乎所有的操作系统都支持打开和保存文件,但是,Java 的FileDialog 包更容易使用。当然这会不再
检测所有使用的程序片,因为程序片在本地磁盘上既不能读也不能写文件。(这会在新的浏览器中交换程序
片的信任关系。)
下面的应用程序运用了两个文件对话类的窗体,一个是打开,一个是保存。大多数的代码到如今已为我们所
熟悉,而所有这些有趣的活动发生在两个不同按钮单击事件的 action()方法中。
//: FileDialogTest。java
// Demonstration of File dialog boxes
import java。awt。*;
public class FileDialogTest extends Frame {
TextField filename = new TextField();
TextField directory = new TextField();
Button open = new Button(〃Open〃);
Button save = new Button(〃Save〃);
public FileDialogTest() {
setTitle(〃File Dialog Test〃);
Panel p = new Panel();
p。setLayout(new FlowLayout());
p。add(open);
p。add(save);
add(〃South〃; p);
directory。setEditable(false);
filename。setEditable(false);
p = new Panel();
p。setLayout(new GridLayout(2;1));
p。add(filename);
p。add(directory);
add(〃North〃; p);
}
public boolean handleEvent(Event evt) {
if(evt。id == Event。WINDOW_DESTROY)
System。exit(0);
else
return super。handleEvent(evt);
return true;
}
public boolean action(Event evt; Object arg) {
if(evt。target。equals(open)) {
// Two arguments; defaults to open file:
FileDialog d = new FileDialog(this;
〃What file do you want to open?〃);
d。setFile(〃*。java〃); // Filename filter
d。setDirectory(〃。〃); // Current directory
d。show();
String openFile;
if((openFile = d。getFile()) != null) {
filename。setText(openFile);
directory。setText(d。getDirectory());
} else {
filename。setText(〃You pressed cancel〃);
407
…………………………………………………………Page 409……………………………………………………………
directory。setText(〃〃);
}
}
else if(evt。target。equals(save)) {
FileDialog d = new FileDialog(this;
〃What file do you want to save?〃;
FileDialog。SAVE);
d。setFile(〃*。java〃);
d。setDirectory(〃。〃);
d。show();
String saveFile;
if((saveFile = d。getFile()) != null) {
filename。setText(saveFile);
directory。setText(d。getDirectory());
} else {
filename。setText(〃You pressed cancel〃);
directory。setText(〃〃);
}
}
else
return super。action(evt; arg);
return true;
}
public static void main(String'' args) {
Frame f = new FileDialogTest();
f。resize(250;110);
f。show();
}
} ///:~
对一个“打开文件”对话框,我们使用构建器设置两个自变量;首先是父窗口句柄,其次是 FileDialog 标题
条的标题。setFile()方法提供一个初始文件名--也许本地操作系统支持通配符,因此在这个例子中所有
的。java 文件最开头会被显示出来。setDirectory()方法选择文件决定开始的目录(一般而言,操作系统允
许用户改变目录)。
show()命令直到对话类关闭才返回。FileDialog 对象一直存在,因此我们可以从它那里读取数据。如果我们
调用getFile()并且它返回空,这意味着用户退出了对话类。文件名和调用getDirectory()方法的结果都显
示在TextFields 里。
按钮的保存工作使用同样的方法,除了因为FileDialog 而使用不同的构建器。这个构建器设置了三个自变量
并且第三的一个自变量必须为FileDialog。SAVE 或 FileDialog。OPEN。
13。16 新型 AWT
在Java 1。1 中一个显著的改变就是完善了新AWT 的创新。大多数的改变围绕在 Java 1。1 中使用的新事件模
型:老的事件模型是糟糕的、笨拙的、非面向对象的,而新的事件模型可能是我所见过的最优秀的。难以理
解一个如此糟糕的(老的 AWT )和一个如此优秀的(新的事件模型)程序语言居然出自同一个集团之手。新
的考虑事件的方法看来中止了,因此争议不再变成障碍,从而轻易进入我们的意识里;相反,它是一个帮助
我们设计系统的工具。它同样是Java Beans 的精华,我们会在本章后面部分进入讲述。
新的方法设计对象做为“事件源”和“事件接收器”以代替老 AWT 的非面向对象串联的条件语句。正象我们
将看到的内部类的用途是集成面向对象的原始状态的新事件。另外,事件现在被描绘为在一个类体系以取代
单一的类并且我们可以创建自己的事件类型。
我们同样会发现,如果我们采用老的AWT 编程,Java 1。1 版会产生一些看起来不合理的名字转换。例如,
setsize()改成resize() 。当我们学习Java Beans 时这会变得更加的合理,因为 Beans 使用一个独特的命名
协议。名字必须被修改以在Beans 中产生新的标准AWT 组件。
408
…………………………………………………………Page 410……………………………………………………………
剪贴板操作在Java 1。1 版中也得到支持,尽管拖放操作“将在新版本中被支持”。我们可能访问桌面色彩组
织,所以我们的Java 可以同其余桌面保持一致。可以利用弹出式菜单,并且为图像和图形作了改进。也同样
支持鼠标操作。还有简单的为打印的API 以及简单地支持滚动。
13。16。1 新的事件模型
在新的事件模型的组件可以开始一个事件。每种类型的事件被一个个别的类所描绘。当事件开始后,它受理
一个或更多事件指明“接收器”。因此,事件源和处理事件的地址可以被分离。
每个事件接收器都是执行特定的接收器类型接口的类对象。因此作为一个程序开发者,我们所要做的是创建
接收器对象并且在被激活事件的组件中进行注册。event…firing 组件调用一个 addXXXListener()方法来完成
注册,以描述XXX 事件类型接受。我们可以容易地了解到以 addListened 名的方法通知我们任何的事件类型
都可以被处理,如果我们试图接收事件我们会发现编译时我们的错误。Java Beans 同样使用这种
addListener 名的方法去判断那一个程序可以运行。
我们所有的事件逻辑将装入到一个接收器类中。当我们创建一个接收器类时唯一的一点限制是必须执行专用
的接口。我们可以创建一个全局接收器类,这种情况在内部类中有助于被很好地使用,不仅仅是因为它们提
供了一个理论上的接收器类组到它们服务的UI 或业务逻辑类中,但因为(正像我们将会在本章后面看到的)
事实是一个内部类维持一个句柄到它的父对象,提供了一个很好的通过类和子系统边界的调用方法。
一个简单的例子将使这一切变得清晰明确。同时思考本章前部 Button2。java 例子与这个例子的差异。
//: Button2New。java
// Capturing button presses
import java。awt。*;
import java。awt。event。*; // Must add this
import java。applet。*;
public class Button2New extends Applet {
Button
b1 = new Button(〃Button 1〃);
b2 = new Button(〃Button 2〃);
public void init() {
b1。addActionListener(new B1());
b2。addActionListener(new B2());
add(b1);
add(b2);
}
class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
getAppletContext()。showStatus(〃Button 1〃);
}
}
class B2 implements ActionListener {