按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
围。这儿没有帧和标题条从菜单处弹出,出现的帧和标题条是属于WEB 浏览器的。也许将来设计能被改变成
允许我们将浏览器菜单和程序片菜单相结合起来——程序片可以影响它的环境将导致太危及整个系统的安全
并使程序片过于的复杂。
(3) 对话框是不被信任的。在Java 中,对话框存在一些令人难解的地方。首先,它们不能正确地拒绝程序
片,这实在是令人沮丧。如果我们从程序片弹出一个对话框,我们会在对话框上看到一个附上的消息框“不
被信任的程序片”。这是因为在理论上,它有可能欺骗用户去考虑他们在通过WEB 同一个老顾客的本地应用
程序交易并且让他们输入他们的信用卡号。在看到 AWT 开发的那种 GUI 后,我们可能会难过地相信任何人都
会被那种方法所愚弄。但程序片是一直附着在一个 Web 页面上的,并可以在浏览器中看到,而对话框没有这
种依附关系,所以理论上是可能的。因此,我们很少会见到一个使用对话框的程序片。
在较新的浏览器中,对受到信任的程序片来说,许多限制都被放宽了(受信任程序片由一个信任源认证)。
涉及程序片的开发时,还有另一些问题需要考虑:
■程序片不停地从一个适合不同类的单独的服务器上下载。我们的浏览器能够缓存程序片,但这没有保证。
在Java 1。1 版中的一个改进是 JAR (Java ARchive)文件,它允许将所有的程序片组件(包括其它的类文
件、图像、声音)一起打包到一个的能被单个服务器处理下载的压缩文件。“数字签字”(能校验类创建
器)可有效地加入每个单独的 JAR 文件。
■因为安全方面的缘故,我们做某些工作更加困难,例如访问数据库和发送电子邮件。另外,安全限制规则
使访问多个主机变得非常的困难,因为每一件事都必须通过WEB 服务器路由,形成一个性能瓶颈,并且单一
环节的出错都会导致整个处理的停止。
■浏览器里的程序片不会拥有同样的本地应用程序运行的控件类型。例如,自从用户可以开关页面以来,在
程序片中不会拥有一个形式上的对话框。当用户对一个WEB 页面进行改变或退出浏览器时,对我们的程序片
而言简直是一场灾难——这时没有办法保存状态,所以如果我们在处理和操作中时,信息会被丢失。另外,
当我们离开一个WEB 页面时,不同的浏览器会对我们的程序片做不同的操作,因此结果本来就是不确定的。
400
…………………………………………………………Page 402……………………………………………………………
13。14。1 程序片的优点
如果能容忍那些限制,那么程序片的一些优点也是非常突出的,尤其是在我们构建客户/服务器应用或者其
它网络应用时:
■没有安装方面的争议。程序片拥有真正的平台独立性(包括容易地播放声音文件等能力)所以我们不需要
针对不同的平台修改代码也不需要任何人根据安装运行任何的“tweaking ”。事实上,安装每次自动地将
WEB 页连同程序片一起,因此安静、自动地更新。在传统的客户机/服务器系统中,建立和安装一个新版本的
客户端软件简直就是一场恶梦。
■因为安全的原因创建在核心Java 语言和程序片结构中,我们不必担心坏的代码而导致毁坏某人的系统。这
样,连同前面的优点,可使用 Java (可从JavaScript 和VBScript 中选择客户端的WEB 编程工具)为所谓的
Intrant (在公司内部使用而不向Internet 转移的企业内部网络)客户机/服务器开发应用程序。
■由于程序片是自动同HTML 集成的,所以我们有一个内建的独立平台文件系统去支持程序片。这是一个很有
趣的方法,因为我们惯于拥有程序文件的一部分而不是相反的拥有文件系统。
13。15 视窗化应用
出于安全的缘故,我们会看到在程序片我们的行为非常的受到限制。我们真实地感到,程序片是被临时地加
入在WEB 浏览器中的,因此,它的功能连同它的相关知识,控件都必须加以限制。但是,我们希望Java 能制
造一个开窗口的程序去运行一些事物,否则宁愿安放在一个WEB 页面上,并且也许我们希望它可以运行一些
可靠的应用程序,以及夸张的实时便携性。在这本书前面的章节中我们制造了一些命令行应用程序,但在一
些操作环境中(例如:Macintosh)没有命令行。所以我们有很多的理由去利用Java 创建一个设置窗口,非
程序片的程序。这当然是一个十分合理的要求。
一个Java 设置窗口应用程序可以拥有菜单和对话框(这对一个程序片来说是不可能的和很困难的),可是如
果我们使用一个老版本的Java,我们将会牺牲本地操作系统环境的外观和感受。JFC/Swing 库允许我们制造
一个保持原来操作系统环境的外观和感受的应用程序。如果我们想建立一个设置窗口应用程序,它会合理地
运作,同样,如果我们可以使用最新版本的Java 并且集合所有的工具,我们就可以发布不会使用户困惑的应
用程序。如果因为一些原因,我们被迫使用老版本的Java,请在毁坏以建立重要的设置窗口的应用程序前仔
细地考虑。
13。15。1 菜单
直接在程序片中安放一个菜单是不可能的(Java 1。0;Java1。1 和 Swing 库不允许),因为它们是针对应用程
序的。继续,如果您不相信我并且确定在程序片中可以合理地拥有菜单,那么您可以去试验一下。程序片中
没有 setMenuBar()方法,而这种方法是附在菜单中的(我们会看到它可以合理地在程序片产生一个帧,并且
帧包含菜单)。
有四种不同类型的Menuponent (菜单组件),所有的菜单组件起源于抽象类:菜单条(我们可以在一个
事件帧里拥有一个菜单条),菜单去支配一个单独的下拉菜单或者子菜单、菜单项来说明菜单里一个单个的
元素,以及起源于MenuItem;产生检查标志(checkmark)去显示菜单项是否被选择的CheckBoxMenuItem。
不同的系统使用不同的资源,对Java 和 AWT 而言,我们必须在源代码中手工汇编所有的菜单。
//: Menu1。java
// Menus work only with Frames。
// Shows submenus; checkbox menu items
// and swapping menus。
import java。awt。*;
public class Menu1 extends Frame {
String'' flavors = { 〃Chocolate〃; 〃Strawberry〃;
〃Vanilla Fudge Swirl〃; 〃Mint Chip〃;
〃Mocha Almond Fudge〃; 〃Rum Raisin〃;
〃Praline Cream〃; 〃Mud Pie〃 };
TextField t = new TextField(〃No flavor〃; 30);
MenuBar mb1 = new MenuBar();
Menu f = new Menu(〃File〃);
401
…………………………………………………………Page 403……………………………………………………………
Menu m = new Menu(〃Flavors〃);
Menu s = new Menu(〃Safety〃);
// Alternative approach:
CheckboxMenuItem'' safety = {
new CheckboxMenuItem(〃Guard〃);
new CheckboxMenuItem(〃Hide〃)
};
MenuItem'' file = {
new MenuItem(〃Open〃);
new MenuItem(〃Exit〃)
};
// A second menu bar to swap to:
MenuBar mb2 = new MenuBar();
Menu fooBar = new Menu(〃fooBar〃);
MenuItem'' other = {
new MenuItem(〃Foo〃);
new MenuItem(〃Bar〃);
new MenuItem(〃Baz〃);
};
Button b = new Button(〃Swap Menus〃);
public Menu1() {
for(int i = 0; i 《 flavors。length; i++) {
m。add(new MenuItem(flavors'i'));
// Add separators at intervals:
if((i+1) % 3 == 0)
m。addSeparator();
}
for(int i = 0; i 《 safety。length; i++)
s。add(safety'i');
f。add(s);
for(int i = 0; i 《 file。length; i++)
f。add(file'i');
mb1。add(f);
mb1。add(m);
setMenuBar(mb1);
t。setEditable(false);
add(〃Center〃; t);
// Set up the system for swapping menus:
add(〃North〃; b);
for(int i = 0; i 《 other。length; i++)
fooBar。add(other'i');
mb2。add(fooBar);
}
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(b)) {
402
…………………………………………………………Page 404……………………………………………………………
MenuBar m = getMenuBar();
if(m == mb1) setMenuBar(mb2);
else if (m == mb2) setMenuBar(mb1);
}
else if(evt。target instanceof MenuItem) {
if(arg。equals(〃Open〃)) {
String s = t。getText();
boolean chosen = false;
for(int i = 0; i 《 flavors。length; i++)
if(s。equals(flavors'i')) chosen = true;
if(!chosen)
t。setText(〃Choose a flavor first!〃);
else
t。setText(〃Opening 〃+ s +〃。 Mmm; mm!〃);
}
else if(evt。target。equals(file'1'))
System。exit(0);
// CheckboxMenuItems cannot use String
// matching; you must match the target:
else if(evt。target。equals(safety'0'))
t。setText(〃Guard the Ice Cream! 〃 +
〃Guarding is 〃 + safety'0'。getState());
else if(evt。target。equals(safety'1'))
t。setText(〃Hide the Ice Cream! 〃 +
〃Is it