第 12章 Java 小应用程序 (Applet)的设计
第 12章 Java 小应用程序 (Applet)
的设计
12.1 编写一个 Applet
12.2 Applet的通信
第 12章 Java 小应用程序 (Applet)的设计
12.1 编写一个 Applet
要编写一个 Applet,必须首先从 java.applet.Applet
派生一个类:
import java.applet.*;
public class SimpleApplet extends Applet {…}
需要注意的是,派生出的 Applet的类必须定义为
public类型。 java.applet.Applet类实际上是 java.awt.Panel
的子类。 Applet和 AWT类的继承关系如图 12.1所示。
第 12章 Java 小应用程序 (Applet)的设计
图 12.1
j a v a, l a n g,O b j e c t
j a v a, a w t, C o m p o n e n t
j a v a, a w t, C o n t a i n e r
j a v a, a w t, P a n e lj a v a, a w t, W i n d o w
j a v a, a p p l e t, A p p l e tj a v a, a w t, F r a m e
第 12章 Java 小应用程序 (Applet)的设计
这种层次关系显示,一个 Applet可直接用作一个
AWT布局的容器。因为 Applet是 Panel的子类,所以它
有一个缺省的流 (Flow)布局管理器。 Component,
Container和 Panel类的方法被 Applet类继承了下来。
12.1.1 Applet的执行框架
在 Java出现之前,人们就已经开始使用 HTML(超
文本标记语言 )进行 Web页面的设计了。然而,对
HTML稍有了解的人都知道,HTML所提供的设计能力
是极其有限的。 Java率先提供了让 Web页面实现更丰富
的 GUI和逻辑运算能力的方法,这种方法是通过将一
个 Java的类插入到 Web页面中来实现的。
第 12章 Java 小应用程序 (Applet)的设计
如何编写一个 Applet并令它在浏览器中执行呢?方
法很简单,只要继承 java.applet包下的 Applet类,并实
现一些必要的方法即可。下面我们来看一个最简单的
Applet的例子,并学会怎样在浏览器中令它运行。
例 12.1 SimpleApplet.java
import java.applet.*;
import java.awt.*;
public class SimpleApplet extends Applet
{
第 12章 Java 小应用程序 (Applet)的设计
String text = null;
public void init()
{
text = "A simple applet demo!";
setBackground(Color.YELLOW);
}
public void start()
{
System.out.println("starting...");
}
public void stop()
第 12章 Java 小应用程序 (Applet)的设计
{
System.out.println("stopping...");
}
public void destroy()
{
System.out.println("preparing to unload...");
}
public void paint(Graphics g)
{
System.out.println("Paint");
第 12章 Java 小应用程序 (Applet)的设计
g.drawString(text,15,25);
}
}
上面是一个最简单的 Applet例子,大家可能已经发
现,这个程序没有 main()方法,的确,我们前面所学到
的 Java应用程序都必须由 main()方法处进入,而在一个
Applet中却不是这样。 Applet的生命周期稍微有些复杂,
它需要通过浏览器来运行,所以为了执行它,还必须
有一个 HTML编写的 Web页面。
第 12章 Java 小应用程序 (Applet)的设计
例 12.2 SimpleApplet.html
<html>
<body>
<applet name="Simple Applet" codebase=,
code=SimpleApplet.class width=200
height=100>
</applet>
</body>
</html>
第 12章 Java 小应用程序 (Applet)的设计
这里将不准备详细讨论有关 HTML的问题,如果不
太了解,可以自己查阅相关资料。我们只稍微解释一
下上面的 HTML代码。它通过标记 <Applet>和参数告诉
浏览器下载执行一个 Applet。其中,name这个参数表
示 Applet的名字; codebase表示编译好的 Applet字节码
的路径; code表示 Applet文件的文件名; width和 height
指定了该 Applet的宽度和高度。 name和 codebase这两个
参数并不是必须的,如果 Applet字节码文件和 html文件
在同一路径下,则可以不加 codebase参数。 width和
height这两个参数一定要加,所以在 Applet程序中可以
不需要设置 Applet的 Panel的大小。
第 12章 Java 小应用程序 (Applet)的设计
把这个 HTML文件和编译好的 Applet保存在同一个
目录下 (HTML文件并不一定要和 Applet同名 ),然后用
浏览器打开这个 HTML文件,将看到这个最简单的小
应用程序的运行结果。除了通过浏览器来运行 Applet,
Java平台本身也提供了一个调试 Applet的方法。在 JDK
包中带有一个小应用程序观察器 AppletViewer.exe,只
要在 Windows命令行窗口中输入:
appletviewer SimpleApplet.html
就会看到和在浏览器中运行基本相同的输出结果。
图 12.2和图 12.3分别列出了通过两种方式运行例子
SimpleApplet的输出结果。
第 12章 Java 小应用程序 (Applet)的设计
现在我们来看看这个 Applet到底是如何运作的。大
家可能已经注意到,在上面的例子 SimpleApplet中,没
有 main()方法。一般的 Java应用程序都是由 main()方法
处进入,而在 Applet中却不是这样。在构造函数完成了
它的任务后,浏览器将自动调用 init()方法,所以通常
把 Applet的基本初始化操作放在这里。 init()结束后,浏
览器调用另一个称为 start()的方法,start()通常在 Applet
成为可见时被调用。
第 12章 Java 小应用程序 (Applet)的设计
start()方法结束后,piant()方法会紧接着被调用来
向 Applet的 Panel上绘图。这样,一个 Applet就已经运行
起来了。用户离开了 Applet所在的页面时,stop()方法
被调用停止 Applet的一些工作。直到浏览器关闭时,
destroy()方法才被调用来完成最后的清除工作。当然
Applet的生命周期比上面所讨论的要稍微复杂一些。
第 12章 Java 小应用程序 (Applet)的设计
图 12.2
第 12章 Java 小应用程序 (Applet)的设计
图 12.3
第 12章 Java 小应用程序 (Applet)的设计
12.1.2 Applet的安全机制
我们已经知道,Applet是通过浏览器下载并自动运
行的,这听起来好像有些可怕,通过浏览器自动运行,
这不正是病毒制造者的 "梦想 "吗。 Applet的设计者可能
会把 Applet设计成一个病毒,并借助浏览器让它进入用
户的计算机。听起来很可怕,但 Java的设计者们也考
虑到了这一点,所以对 Applet的能力做了种种限制,只
要一个 Applet试图违反安全条例,小应用程序安全管理
器 (Applet Security Manager)就会发出一个
SecurityException(安全违例 )消息。
第 12章 Java 小应用程序 (Applet)的设计
那么到底哪些是 Applet可以做的,哪些是不可以做
的呢?小应用程序所能够控制的安全程度是在浏览器
层次上实现的,小应用程序的安全机制通过 "沙箱
"(sandbox)控制。在大多数浏览器上,在沙箱内运行时,
缺省地禁止以下操作:
● 运行时执行另一程序:小应用程序绝不能运行任何
一个本地可执行程序。
● 任何文件的输入 /输出:小应用程序不能读 /写本地计
算机的文件系统。
第 12章 Java 小应用程序 (Applet)的设计
● 调用任何本地方法:除了所用 Java版本号,操作系
统名和版本号,小应用程序不能获取任何与本地计算
机有关的信息,也不能通过调用任何本地方法,API等
方法获得。特别是,小应用程序不能获得用户名、电
子邮件地址等等信息。
● 尝试打开除提供 Applet的主机之外的任何系统的
Socket:除了下载它的服务器之外,小应用程序不能和
任何一台主机通信。
第 12章 Java 小应用程序 (Applet)的设计
这些限制的关键在于:通过限制 Applet对系统文件
的存取来阻止它侵犯一个远程系统的隐私或破坏该系
统;禁止执行另一程序和不允许调用本地方法限制了
Applet启动未经 JVM检查的代码;对 Socket的限制则禁
止了与另一个可能有危害性的程序的通信。
由于小应用程序是由 JVM(Java Virtual Machine)解
释执行的字节码,而非由 CPU直接执行的机器码,所
以只要在 JVM中检查了小应用程序的指令和程序区域,
就可以确定,小应用程序不会对用户计算机系统造成
较大的危害。表 12.1显示了小应用程序在沙箱中运行时
的功能。
第 12章 Java 小应用程序 (Applet)的设计
表 12.1 小应用程序的功能
浏览器中运行 小应用程序观察器中运行
读 /写本地文件 否 是
获取文件信息 否 是
删除文件 否 是
运行另一程序 否 否
读取 username属性 否 是
连接服务器上的网络端口 是 是
连接另一台主机上的网络端口 否 是
下载 Java库 否 是
调用退出 否 是
创建一个弹出试窗口 带有警告信息 是
第 12章 Java 小应用程序 (Applet)的设计
在这些限制下,小应用程序的能力似乎大打折扣
了,这对那些恶意的设计者是有效的措施,但是也给
开发者们造成了限制。如果没有办法打破这些限制,
那么小应用程序所能做的就太有限了。对此,Java的
设计者也提供了解决办法,那就是签名类。小程序提
供者可以编写一个带有签名的 Applet,当浏览器下载并
运行这个 Applet的时候,会提示用户这是一个签名
Applet类,并询问用户是否信任该设计者。如果取得用
户的信任,那么这个 Applet就可以突破所有的限制,像
一个普通应用程序那样在用户的计算机上运行了。
第 12章 Java 小应用程序 (Applet)的设计
12.1.3 Applet的主要方法
Applet类的一些主要方法有:
● public void init()
该方法在 Applet被浏览器载入内存后自动调用,通
常用来初始化数据的值。本方法只在 Applet首次装入时
被调用,并在调用 start()方法前完成。假如要创建一个
Applet生存期内的线程,就可以在该方法中创建,在
destory方法中结束。
第 12章 Java 小应用程序 (Applet)的设计
● public void start()
当 init()方法完成后,浏览器会自动调用 start()方法。
它的执行使得 Applet成为 "活动 "的。并且每次 Applet成
为可见的时,它都要执行一次,如:当浏览器在被最
小化后又恢复时,或者从其他 web页返回含有这个
Applet的页面时。通常我们把主要程序代码写在这里,
这一方法的典型用法是启动动画和播放声音。
第 12章 Java 小应用程序 (Applet)的设计
● public void stop()
当浏览器切换到另一个 web页面或将要关闭时,会
自动调用 stop()方法。通常在该方法中加入一些暂停动
作,例如暂停音乐或动画的播放,以便用户从其他
Web页面切换回包含该 Applet的页面时,可以通过调用
start()方法继续播放下去。
第 12章 Java 小应用程序 (Applet)的设计
● public void destroy()
用户关闭浏览器时,必须终止 Applet的运行,并
回收资源。此时,destroy()方法会自动被调用。该方
法是 Applet在生存期中执行的最后一个方法,所以通
常在这里释放一些在 init()中分配的资源,如创建的线
程等。浏览器在调用 destory()方法时,会先调用一次
stop()方法。
第 12章 Java 小应用程序 (Applet)的设计
● public AudioClip getAudioClip(URL url)
返回由参数 url所指定的 AudioClip对象。 AudioClip
是一个音频剪辑对象的接口,它提供了音频对象的抽
象控制。无论 url指定的音乐文件是否存在,
getAudioClip()方法都会很快返回值,因为音频文件要
等到播放的时候才下载。 url参数指定的必须是一个绝
对地址。
● public URL getCodeBase()
返回 Applet所在网址。
● public URL getDocumentBase()
返回包含该 Applet对象的 Web页面的地址。
第 12章 Java 小应用程序 (Applet)的设计
● public Image getImage(URL url)
返回参数 url所指定的图片文件的 Image对象。和
getAudioClip()方法类似,不管指定地址的文件是否存
在,getImage()方法都会立即返回值。图片文件在
Applet显示在屏幕上时才会下载。 url参数指定的必须
是一个绝对地址。
● public String getParameter(String name)
返回由 HTML文件所提供的参数信息。 Applet提供
了从 Web页面文件中提取参数的方法,可以在 HTML文
件中通过 <param>标记设置一些参数供 Applet使用,例
如有如下的 HTML代码:
第 12章 Java 小应用程序 (Applet)的设计
<applet code="Clock" width=50 height=50>
<param name=Color value="blue">
</applet>
调用 "getParameter("Color")"将返回 "blue"。注意参
数名是不区分大小写的。
● public Boolean isActive()
检查 Applet是否处于活动状态。当浏览器调用 start()
方法时,Applet即进入活动状态,而一旦 stop()方法被
调用,即进入非活动状态。
第 12章 Java 小应用程序 (Applet)的设计
● public void play(URL url)
播放由参数 url指定的音频剪辑,如果该音频剪辑
不存在,则不做任何事情。 url参数指定的必须是一个
绝对地址
● public void showStatus(String msg)
在浏览器的状态栏上显示由参数 msg指定的文字信
息,以便通知用户 Applet的当前状态。
通过第一节的例子,我们已经明白了 Applet运行的
方式和它的生命周期。下面我们通过实例来学习如何
运用以上方法写出有趣的 Applet。
第 12章 Java 小应用程序 (Applet)的设计
例 12.3 ShowImageApplet.java
import java.applet.*;
import java.awt.*;
import java.net.*;
public class ShowImageApplet extends Applet
{
String ImageName = null;
String AudioName = null;
Image img = null;
AudioClip audio = null;
第 12章 Java 小应用程序 (Applet)的设计
public void init()
{
ImageName = getParameter("image");
img = getImage(getDocumentBase(),ImageName);
AudioName = getParameter("audio");
audio = getAudioClip(getDocumentBase(),
AudioName);
}
public void start()
{
audio.play();
}
第 12章 Java 小应用程序 (Applet)的设计
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
}
}
ShowImageApplet.html
<html>
<body>
<applet name="Image Shower"
code=ShowImageApplet.class width=200 height=100>
第 12章 Java 小应用程序 (Applet)的设计
<param name="image" value="getJava.gif">
<param name="audio" value="windows start.wav">
</applet>
</body>
</html>
第 12章 Java 小应用程序 (Applet)的设计
图 12.4
第 12章 Java 小应用程序 (Applet)的设计
这个例子展示了如何通过 getImage()方法载入一个图
片对象,并将它显示在浏览器中以及在启动 Applet的时
候播放一段音乐。首先,通过 getParameter()方法从
HTML代码中提取出参数,即 Image和 Audio文件的文件
名。然后通过 getImage()方法和 getAudioClip()方法取得
Image和 Audio文件的对象。它们包括两个参数,
getDocument()返回包含 Applet的 Web页所在的地址,第
二个参数 getJava.gif指定图片文件名。最后在 start()方法
中播放音乐。这样,Applet每次启动时都会伴随着一段
音乐。在 paint()方法中调用 drawImage()方法显示图片,
运行时图片 getJava.gif和 windows start.wav两个文件必须
和 ShowImageApplet.html文件在同一目录下,其运行结
果如图 12.4所示。
第 12章 Java 小应用程序 (Applet)的设计
运行结果如图 12.4所示。
值的注意的是,如果通过图片来源地址
http://java.sun.com/getjava/images/getJava_head.gif来构
造一个 URL对象,并通过 getImage()方法载入它的话可
能会引发一个访问违例。这是由于 Applet的安全机制。
前面已经提到,Applet禁止:包含该 Applet的 Web页面
所在主机以外的其他任何机器通信。所以无法从其他
的 URL下载一个资源。
第 12章 Java 小应用程序 (Applet)的设计
12.1.4 Applet标记
以下为 Applet标记的完整句法:
<applet>
[archive=archiveList]
code=appletFile.class
width=pixels height=pixels
[codebase=codebaseURL]
[alt=alternateText]
[name=appletInstanceName]
[align=alignment]
[vspace=pixels] [hspace=pixels]
>
第 12章 Java 小应用程序 (Applet)的设计
[<param name=appletAttribute1 value=value>]
[<param name=appletAttribute2 value=value>]
.,,
[alternateHTML]
</applet>
这些标记的意义如下:
● archive = archiveList
这一可选属性描述了一个或多个含有将被 "预装 "的
类和其他资源的 archives。类的装载由带有给定
codebase的 AppletClassLoader的一个实例来完成。
ArchiveList中的 archives以逗号 (,)分隔。
第 12章 Java 小应用程序 (Applet)的设计
● code = appletFile.class
这是一个必需的属性,它给定了含有已编译好的
Applet子类的文件名。也可用 package.appletFile.class的
格式来表示。
注:这个文件与你要装入的 HTML文件的基 URL有
关,它不能含有路径名。要改变 Applet的基 URL,可使
用 <codebase>。
● width = pixels height = pixels
这些必需的属性给出了 Applet显示区域的初始宽度
和高度 (以像素为单位 ),不包括 Applet所产生的任何窗
口或对话框。
第 12章 Java 小应用程序 (Applet)的设计
● codebase = codebaseURL
这一可选属性指定了 Applet的基 URL―― 包含有
Applet代码的目录。如果这一属性未指定,则采用文档
的 URL。
● alt = alternateText
这一可选属性指定了当浏览器能读取 Applet标记,
但不能 执行 Java Applet时要显示的文本。
● name = appletInstanceName
这个可选属性为 Applet实例指定有关名称,从而使
得在同一页面上的 Applet可找到彼此 (以及互相通信 )。
第 12章 Java 小应用程序 (Applet)的设计
● align = alignment
这个可选属性指定了 Applet的对齐方式。它的可取
值与基本的 HTML中 IMG标记的相应属性相同,为 left,
right,top,texttop,middle,absmiddle,baseline,bottom和
absbottom等。
● vspace = pixels hspace = pixels
这些可选属性指定了在 Applet上下 (vspace)及左右
(hspace)的像素数目。其用法与 IMG标记的 vspace和
hspace属性相同。
第 12章 Java 小应用程序 (Applet)的设计
● <param name = appletAttribute1 value = value>
这个标记提供了一种可带有由 "外部 "指定的数值的
Applet,它对一个 Java应用程序的作用与命令行参数相
同。 Applet用 getParameter()方法来存取它们的属性,该
方法将在稍后作更详细的讨论。
不支持 Java程序执行的浏览器将显示被包括在
<applet>和 </applet>标记之间的任何常规的 HTML;而
可支持 Java技术的浏览器则忽略介于这两个标记之间
的 HTML代码。
第 12章 Java 小应用程序 (Applet)的设计
12.1.5 从 Applet中弹出窗口
有时候我们可能觉得浏览器的界面不利于布局管
理,一个浮在顶端的窗口或对话框更能引人注目。实
际上,确实可以从 Applet程序中弹出一个如同应用程序
一般的窗口来。这有时也有利于我们将现成的应用程
序转成小应用程序,如果我们只是仅仅想它通过浏览
器下载运行,而不需要做太多功能上的调整,从 Applet
程序中弹出一个窗口也许是个好的解决办法,也就是
给它披上一个 Applet的外壳。下面这个例子是一个小型
的计算器的程序,它通过 Applet的一个按键弹出一个
Frame,而计算器功能的实现都在 Frame中。 Applet的
功能仅仅是从浏览器启动它,仅仅是它的一层外壳。
第 12章 Java 小应用程序 (Applet)的设计
例 12.4 CalculatorApplet.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class CalculatorApplet extends Applet
implements ActionListener
{
// 弹出的窗口
private Frame calcFrame = new CalculatorFrame();
public void init()
第 12章 Java 小应用程序 (Applet)的设计
{
// 弹出的按键
Button calcButton = new Button("Calculator");
calcButton.addActionListener(this);
add(calcButton);
}
public void actionPerformed(ActionEvent evt)
{
// 弹出窗口如果没有被显示,则显示它,否则关闭它
if (calcFrame.isVisible())
calcFrame.setVisible(false);
第 12章 Java 小应用程序 (Applet)的设计
else
calcFrame.setVisible(true);
}
}
class CalculatorFrame extends Frame
implements ActionListener
{
private TextField display = null;
private double arg1 = 0;
private StringBuffer arg2 = new StringBuffer();
private char op = '=';
第 12章 Java 小应用程序 (Applet)的设计
public CalculatorFrame()
{
setTitle("Calculator");
setSize(200,200);
setLayout(new BorderLayout());
// 输出窗口
display = new TextField("0");
display.setEditable(false);
add(display,"North");
// 数字按键盘
Panel keypad = new Panel();
第 12章 Java 小应用程序 (Applet)的设计
Panel keypad = new Panel();
keypad.setLayout(new GridLayout(4,4));
// 添加数字和运算符按键
String keys = "789/456*123-0.=+";
for (int i = 0; i < keys.length(); i++)
{
Button btn = new Button(keys.substring(i,i+1));
keypad.add(btn);
// 为按键添加事件监听器
btn.addActionListener(this);
}
add(keypad,"Center");
第 12章 Java 小应用程序 (Applet)的设计
}
public void actionPerformed(ActionEvent evt)
{
// 响应按键,如果是数字则连接到 StringBuffer中,
// 如果是运算符则进行运算。
String key = evt.getActionCommand();
char c = key.charAt(0);
if ((c >= '0' && c <= '9') || c == '.' ||
(c == '-' && arg2.length() == 0))
{
arg2.append(c);
display.setText(arg2.toString());
第 12章 Java 小应用程序 (Applet)的设计
}
else
{
calculate(Double.parseDouble(arg2.toString()));
op = c;
arg2.setLength(0);
if (c == '=')
arg2.append(arg1);
}
}
public void calculate(double arg2)
{
第 12章 Java 小应用程序 (Applet)的设计
// 计算
switch (op)
{
case '+',arg1 += arg2; break;
case '-',arg1 -= arg2; break;
case '*',arg1 *= arg2; break;
case '/ ',arg1 /= arg2; break;
case '=',arg1 = arg2; break;
default,break;
第 12章 Java 小应用程序 (Applet)的设计
}
display.setText(""+arg1);
}
}
这个窗口是一个功能简陋的计算器面板。由于只
需给它配上最简单的 HTML代码,所以这里不再列出。
图 12.5是该程序的运行结果。
第 12章 Java 小应用程序 (Applet)的设计
图 12.5
弹出窗口 Applet
第 12章 Java 小应用程序 (Applet)的设计
我们注意到,在弹出窗口的最底下有一行字 "Java
Applet Window",这是对这个窗口的一个说明,也是
所有浏览器都具备的一个安全特性。它提示用户这是
一个由运行于浏览器的 Applet弹出的窗口,而不是从机
器上运行的一个程序。试想如你运行了一个恶意的
Applet程序,它可能会弹出一个窗口,这个窗口与你本
地某个需要输入账号、密码的应用程序有着相同的界
面,也许你会被它蒙蔽而错误性的输入了信息,这个
Applet就会把这些信息送回主机。
第 12章 Java 小应用程序 (Applet)的设计
为了避免这种恶作剧出现,所有的弹出窗口都在底
端显示一个标签,警告用户这是一个小应用程序,而
不是本地应用程序。当然,如果你制作一个签名的小
应用程序并得到了用户的信任,则可以不显示这个警
告标签。
值的一题的是,正如前面所说,这个小应用程序
只是通过 Applet来启动了一个弹出窗口,如果在
CalculatorApplet类中为它加入一个 mian()方法的话,它
就可以同时作为 Applet和应用程序来运行,大家可以自
己试试。
第 12章 Java 小应用程序 (Applet)的设计
12.1.6 基于 Swing与 AWT的 Applet的区别
我们已经知道,Applet类是从 AWT包中的 Panel类
派生的,而 Java2提供的新一代 GUI设计包 Swing也提供
了支持 Applet设计的类,javax.swing.Japplet。注意,
JApplet类并不是从 JPanel类派生的,而是直接从
java.applet.Applet类派生出来的。
用 AWT设计小应用程序时,我们从
java.applet.Applet类派生一个子类,现在为了使用
Swing包,就必须从 avax.swing.JApplet类派生子类。让
我们先来看一个基于 JApplet类的小应用程序的实例,
然后再分析二者的区别。
第 12章 Java 小应用程序 (Applet)的设计
例 12.5 JAppletTest.java
import java.awt.*;
import javax.swing.*;
public class JAppletTest extends JApplet
{
private JMenuBar menuBar = new JMenuBar();
public void init()
{
第 12章 Java 小应用程序 (Applet)的设计
Container contentPane = getContentPane();
Image img = getImage(getDocumentBase(),
"getJava.GIF");
Icon icon = new ImageIcon(
getImage(getDocumentBase(),"getJava.GIF"));
JLabel label = new JLabel("Swing!",icon,
SwingConstants.CENTER);
第 12章 Java 小应用程序 (Applet)的设计
contentPane.add(label,BorderLayout.CENTER);
JMenu fileMenu = new JMenu("File");
String[] fileItems = {"New","Open","Save","Exit"};
for (int i = 0; i < fileItems.length; i++)
fileMenu.add(fileItems[i]);
JMenu helpMenu = new JMenu("Help");
String[] helpItems = {"Help of help","About"};
for (int i = 0; i < helpItems.length; i++)
helpMenu.add(helpItems[i]);
第 12章 Java 小应用程序 (Applet)的设计
menuBar.add(fileMenu);
menuBar.add(helpMenu);
setJMenuBar(menuBar);
}
}
该程序的运行结果如图 12.6所示。在该程序中,为
小应用程序加入了一个菜单条,这也是基于 Swing的小
应用程序的一种新特性。
第 12章 Java 小应用程序 (Applet)的设计
图 12.6
第 12章 Java 小应用程序 (Applet)的设计
从上面的例子来看,基于 Swing的小应用程序和基
于 AWT的小应用程序在架构上没有什么分别,它们的
生存方式也是相同的,所以上述例子中也没有给出
start(),stop(),destory()这些方法,而是使用了默认的
方法,但是,有几点需要注意:
(1) JApplet类默认使用 BorderLayout作为其容器的
布局管理器,其默认约束条件是
BordenLayout.CENTER,而 Applet的缺省的布局管理器
是 FlowLayout,且 FlowLayout的缺省约束条件是
FlowLayout.LEFT,这是二者最显著的区别之一。
第 12章 Java 小应用程序 (Applet)的设计
(2) JApplet是只包含一个组件的容器,这个组件就
是 JRootPane的一个实例,而 JRootPane包含了一个称作
内容窗格的容器。
(3) "内容窗格 "包含与特定的小应用程序有关的所
有内容,可通过 getContentPane()方法获得。即是说,
小应用程序必须把所有的组件添加到内容窗格中,而
Applet则是把它们直接添加到小应用程序中。
(4) 我们不能直接为小应用程序设置布局管理器,
而只能对它的内容窗格设置布局管理。
(5) JApplet的实例可以有一个菜单栏,它是由
setJMenuBar()方法指定的,而 AWT小应用程序却不能。
第 12章 Java 小应用程序 (Applet)的设计
基于 Swing的小应用程序比基于 AWT的小应用程序有
更多的优势,它可以使用 Swing提供的更多界面元素和性
能。但是它也有一个很大的缺陷,那就是很多浏览器都
不能支持 Swing编写的小应用程序,而必须依靠安装 Java
Plug-in包。虽然可以让浏览器在运行 Swing小应用程序时
自动下载这个包,但是由于 Java Plug-in包并不小,所以
对于非宽带上网的用户来说是不可忍受的。
第 12章 Java 小应用程序 (Applet)的设计
12.2 Applet的通信
12.2.1 Applet与浏览器的通信
我们已经学习过如何通过 getParameter()方法从浏
览器的 Web页中获取信息,同时,Applet也可以要求浏
览器为自己做事,例如我们可以让浏览器打开一个指
定的 Web页。为了与浏览器通信,需调用 Applet的
getAppletContext()方法。这个方法返回一个实现了
AppletContext接口的对象,这个接口是实现 Applet和浏
览器通信的一座桥梁。
第 12章 Java 小应用程序 (Applet)的设计
除了 getAudioClip()和 getImage()外,AppletContext
接口还提供了四个有用的方法,它们是 get-Applet()、
getStream(),showDocument()和 showStatus(),我们将
在本节和下面的小节中讲述它们的用法。
在小应用程序中可以访问浏览器的两个区:状态
行和页面显示区,但都必须通过调用 AppletContext接
口中的方法来实现。
通过调用 showStatus(String status)方法,可以在浏
览器底部的状态行中显示一行字符串提示信息,例如:
showStatus("Loading Data…please wait");
第 12章 Java 小应用程序 (Applet)的设计
但是,遗憾的是,使用 showStatus()显示提示信息
的功能很有限,因为浏览器自己也在使用状态行,而
且经常使用。它总是用新的提示信息改写前一次的信
息,用户往往无法注意到某一条信息,所以不能用该
方法来显示一些重要信息。
在浏览器页面显示区显示信息的方法是
showDocument(),它可以通知浏览器打开一个指定的
URL资源。 showDocument()方法的定义如下:
showDocument(URL url);
showDocument(URL url,String target);
第 12章 Java 小应用程序 (Applet)的设计
第一种格式的调用可以让浏览器直接打开一个新的
URL资源,并将它显示在当前浏览器显示区中,替换原
来显示的 Web页面。第二种格式的调用多了一个 String
类型的参数,第一个参数依然是指定要显示的 URL资源,
第二个参数则用于指明浏览器打开页面的方式。如果指
定值为 "_blank",浏览器就会另外打开一个新窗口,在
新的浏览器窗口中显示指定的 Web页。如果使用
HTML3.2以上版本提供的帧特性,则可以将一个浏览
器的窗口分成多个帧,并给每个帧指定一个名字。用户
可以把自己的 Applet放入一个帧中,并利用它来控制其
他帧的页面显示。
表 12.2展示了可以用作 ShowDocument()方法的第二
个参数的所有字符串及其功能。
第 12章 Java 小应用程序 (Applet)的设计
表 12.2 show Document参数
showDocument()的两个参数 位 置
“_self”或无 显示在当前帧内
“_parent” 显示在父容器帧内
“_top” 显示在顶层帧内
“_blank” 显示在一个新打开的浏览器窗口中
其他字符 显示在该字符串指定名的帧内, 如果没有该帧, 就打开一个新窗口显示, 并把这个名称
指定给他
第 12章 Java 小应用程序 (Applet)的设计
例 12.6 Bookmark.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Bookmark extends Applet
implements ItemListener
{
第 12章 Java 小应用程序 (Applet)的设计
private List links = new List();
public void init()
{
int i = 1;
String s;
while ((s = getParameter("link"+i)) != null)
{
links.add(s);
i++;
}
第 12章 Java 小应用程序 (Applet)的设计
}
public void itemStateChanged(ItemEvent evt)
{
List source = (List)evt.getSource();
String link = source.getSelectedItem();
try
{
AppletContext context = getAppletContext();
URL url = new URL(link);
context.showDocument(url,"right");
第 12章 Java 小应用程序 (Applet)的设计
}
catch (Exception e)
{
showStatus("Error " + e);
}
}
}
Bookmark.html
<html>
第 12章 Java 小应用程序 (Applet)的设计
<head>
<title>Bookmark Applet</title>
<head>
<frameset cols="300,*">
<frame name="left" src="left.html">
<frame name="right">
</frameset>
<html>
// Left.html
<html>
第 12章 Java 小应用程序 (Applet)的设计
<title>A Bookmar Applet</title>
<body>
<Applet code="Bookmark.class" width=250
height=200>
<param name=link1 value="http://java.sun.com/">
<param name=link2 value="http://www.szptt.net.cn/">
<param name=link3 value="http://www.163.net/">
<param name=link4 value="http://www.21cn.com/">
<param name=link5
value="http://www.yahoo.com.cn/">
</applet>
</body>
<html>
第 12章 Java 小应用程序 (Applet)的设计
这个小应用程序利用了 HTML3.2以上版本的窗口分
帧的特性,将浏览器的页面显示区垂直地分成了两个
帧。左边的帧包含了上面的 Bookmark小应用程序,它
在一个列表框中列出了一列网址。点击其中任何一个
网址,就会在右边的帧中显示出相应的 Web页来。这
个功能类似收藏夹的小应用程序在浏览器中运行,结
果如图 12.7所示。
第 12章 Java 小应用程序 (Applet)的设计
图 12.7
第 12章 Java 小应用程序 (Applet)的设计
12.2.2 同页 Applet之间的通信
我们已经学习了如何在一个 Web页面中嵌入 Applet,
实际上,完全可以在同一个 Web页上嵌入一个以上的
小应用程序,甚至还可以让这些 Applet互相通信,互相
控制。要实现 Web页中的不同 Applet之间的通信,这些
Applet的 codebase必须是相同的,即它们的 class文件放
在服务器上的同一路径下。
第 12章 Java 小应用程序 (Applet)的设计
Applet之前的通信是一个高级技巧。我们还记得
在嵌入小应用程序的 <applet>标记中有一个 name参数,
我们可以通过这个参数为嵌入的小应用程序赋予一个
名字。然后调用 AppletContext接口的 getApplet()方法,
获得对这个小应用程序的一个引用。利用这个应用,
就可以调用小应用程序中任何 public的方法。请看如
下例子。
第 12章 Java 小应用程序 (Applet)的设计
例 12.7 ListApplet.java
import java.applet.*;
import java.awt.*;
public class ListApplet extends Applet
{
private List list = new List();
public void init()
第 12章 Java 小应用程序 (Applet)的设计
{
setLayout(new BorderLayout());
add(list);
}
public void addItem(String item)
{
list.add(item);
}
}
第 12章 Java 小应用程序 (Applet)的设计
import Applet.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class InputerApplet extends Applet
implements ActionListener
{
private TextField inputer = new TextField();
第 12章 Java 小应用程序 (Applet)的设计
private Button addBtn = new Button("ADD");
private Applet listApplet;
public void init()
{
AppletContext context = getAppletContext();
listApplet = context.getApplet("ListApplet");
add(inputer);
addBtn.addActionListener(this);
add(addBtn);
第 12章 Java 小应用程序 (Applet)的设计
}
public void actionPerformed(ActionEvent evt)
{
String item = inputer.getText();
System.out.print(item);
((ListApplet)listApplet).addItem(item);
}
}
第 12章 Java 小应用程序 (Applet)的设计
TwoAppletDemo.html
<html>
<title>A Bookmar Applet</title>
<body>
<applet code="ListApplet.class" width=100 height=100
name="ListApplet">
</applet> <p>
第 12章 Java 小应用程序 (Applet)的设计
图 12.8
第 12章 Java 小应用程序 (Applet)的设计
<applet code="InputerApplet.class" width=100 height=100
name="InputerApplet">
</applet>
</body>
<html>
这个例子是在一个 Web页面中插入两个小应用程
序。第一个小应用程序叫 ListApplet,它包含一个 List
组件,并实现一个向 List中添加字符串项的方法。
第 12章 Java 小应用程序 (Applet)的设计
第二个小应用程序叫 InputerApplet,它包含一个
TextField和一个 Button,点击这个 Button,就可以将
TextField中输入的文字添加到第一个小应用程序的 List
中。方法就是通过调用 getApplet()方法获得
InputerApplet的一个引用,然后通过这个引用调用
ListApplet中的方法 AddItem()。程序的运行结果如图
12.8所示。
第 12章 Java 小应用程序 (Applet)的设计
12.2.3 Applet网络通信设计
前面已经讲过,小应用程序的安全机制规定 Applet
只能与它所在 Web页面的服务器通信。 Applet与服务器
之间的通信除了可以利用 getAudioClip()和 getImage()这
两个方法获取服务器上的资源外,还可以通过和服务
器上的服务程序建立 Socket连接来实现。当然 Applet绝
不能和其他的主机建立 Socket连接。
第 12章 Java 小应用程序 (Applet)的设计
利用 Applet做网络服务的客户端的做法是很常见的,
例如一些股票行情的实时走势显示的 Applet等。在
Applet中,使用 Socket编程和在应用程序中编程没有什
么不同,本章中不再举例,大家可以自己尝试。但是,
Applet和服务器之间的通信还有一种特殊的方式,就是
和服务器上一种叫作 Servlet的 Java服务程序通信。
Applet和 Servlet的通信方式是非常方便和实用的。有关
Servlet的知识在本书中不做讲解,有兴趣的读者可以
参考有关资料。
第 12章 Java 小应用程序 (Applet)
的设计
12.1 编写一个 Applet
12.2 Applet的通信
第 12章 Java 小应用程序 (Applet)的设计
12.1 编写一个 Applet
要编写一个 Applet,必须首先从 java.applet.Applet
派生一个类:
import java.applet.*;
public class SimpleApplet extends Applet {…}
需要注意的是,派生出的 Applet的类必须定义为
public类型。 java.applet.Applet类实际上是 java.awt.Panel
的子类。 Applet和 AWT类的继承关系如图 12.1所示。
第 12章 Java 小应用程序 (Applet)的设计
图 12.1
j a v a, l a n g,O b j e c t
j a v a, a w t, C o m p o n e n t
j a v a, a w t, C o n t a i n e r
j a v a, a w t, P a n e lj a v a, a w t, W i n d o w
j a v a, a p p l e t, A p p l e tj a v a, a w t, F r a m e
第 12章 Java 小应用程序 (Applet)的设计
这种层次关系显示,一个 Applet可直接用作一个
AWT布局的容器。因为 Applet是 Panel的子类,所以它
有一个缺省的流 (Flow)布局管理器。 Component,
Container和 Panel类的方法被 Applet类继承了下来。
12.1.1 Applet的执行框架
在 Java出现之前,人们就已经开始使用 HTML(超
文本标记语言 )进行 Web页面的设计了。然而,对
HTML稍有了解的人都知道,HTML所提供的设计能力
是极其有限的。 Java率先提供了让 Web页面实现更丰富
的 GUI和逻辑运算能力的方法,这种方法是通过将一
个 Java的类插入到 Web页面中来实现的。
第 12章 Java 小应用程序 (Applet)的设计
如何编写一个 Applet并令它在浏览器中执行呢?方
法很简单,只要继承 java.applet包下的 Applet类,并实
现一些必要的方法即可。下面我们来看一个最简单的
Applet的例子,并学会怎样在浏览器中令它运行。
例 12.1 SimpleApplet.java
import java.applet.*;
import java.awt.*;
public class SimpleApplet extends Applet
{
第 12章 Java 小应用程序 (Applet)的设计
String text = null;
public void init()
{
text = "A simple applet demo!";
setBackground(Color.YELLOW);
}
public void start()
{
System.out.println("starting...");
}
public void stop()
第 12章 Java 小应用程序 (Applet)的设计
{
System.out.println("stopping...");
}
public void destroy()
{
System.out.println("preparing to unload...");
}
public void paint(Graphics g)
{
System.out.println("Paint");
第 12章 Java 小应用程序 (Applet)的设计
g.drawString(text,15,25);
}
}
上面是一个最简单的 Applet例子,大家可能已经发
现,这个程序没有 main()方法,的确,我们前面所学到
的 Java应用程序都必须由 main()方法处进入,而在一个
Applet中却不是这样。 Applet的生命周期稍微有些复杂,
它需要通过浏览器来运行,所以为了执行它,还必须
有一个 HTML编写的 Web页面。
第 12章 Java 小应用程序 (Applet)的设计
例 12.2 SimpleApplet.html
<html>
<body>
<applet name="Simple Applet" codebase=,
code=SimpleApplet.class width=200
height=100>
</applet>
</body>
</html>
第 12章 Java 小应用程序 (Applet)的设计
这里将不准备详细讨论有关 HTML的问题,如果不
太了解,可以自己查阅相关资料。我们只稍微解释一
下上面的 HTML代码。它通过标记 <Applet>和参数告诉
浏览器下载执行一个 Applet。其中,name这个参数表
示 Applet的名字; codebase表示编译好的 Applet字节码
的路径; code表示 Applet文件的文件名; width和 height
指定了该 Applet的宽度和高度。 name和 codebase这两个
参数并不是必须的,如果 Applet字节码文件和 html文件
在同一路径下,则可以不加 codebase参数。 width和
height这两个参数一定要加,所以在 Applet程序中可以
不需要设置 Applet的 Panel的大小。
第 12章 Java 小应用程序 (Applet)的设计
把这个 HTML文件和编译好的 Applet保存在同一个
目录下 (HTML文件并不一定要和 Applet同名 ),然后用
浏览器打开这个 HTML文件,将看到这个最简单的小
应用程序的运行结果。除了通过浏览器来运行 Applet,
Java平台本身也提供了一个调试 Applet的方法。在 JDK
包中带有一个小应用程序观察器 AppletViewer.exe,只
要在 Windows命令行窗口中输入:
appletviewer SimpleApplet.html
就会看到和在浏览器中运行基本相同的输出结果。
图 12.2和图 12.3分别列出了通过两种方式运行例子
SimpleApplet的输出结果。
第 12章 Java 小应用程序 (Applet)的设计
现在我们来看看这个 Applet到底是如何运作的。大
家可能已经注意到,在上面的例子 SimpleApplet中,没
有 main()方法。一般的 Java应用程序都是由 main()方法
处进入,而在 Applet中却不是这样。在构造函数完成了
它的任务后,浏览器将自动调用 init()方法,所以通常
把 Applet的基本初始化操作放在这里。 init()结束后,浏
览器调用另一个称为 start()的方法,start()通常在 Applet
成为可见时被调用。
第 12章 Java 小应用程序 (Applet)的设计
start()方法结束后,piant()方法会紧接着被调用来
向 Applet的 Panel上绘图。这样,一个 Applet就已经运行
起来了。用户离开了 Applet所在的页面时,stop()方法
被调用停止 Applet的一些工作。直到浏览器关闭时,
destroy()方法才被调用来完成最后的清除工作。当然
Applet的生命周期比上面所讨论的要稍微复杂一些。
第 12章 Java 小应用程序 (Applet)的设计
图 12.2
第 12章 Java 小应用程序 (Applet)的设计
图 12.3
第 12章 Java 小应用程序 (Applet)的设计
12.1.2 Applet的安全机制
我们已经知道,Applet是通过浏览器下载并自动运
行的,这听起来好像有些可怕,通过浏览器自动运行,
这不正是病毒制造者的 "梦想 "吗。 Applet的设计者可能
会把 Applet设计成一个病毒,并借助浏览器让它进入用
户的计算机。听起来很可怕,但 Java的设计者们也考
虑到了这一点,所以对 Applet的能力做了种种限制,只
要一个 Applet试图违反安全条例,小应用程序安全管理
器 (Applet Security Manager)就会发出一个
SecurityException(安全违例 )消息。
第 12章 Java 小应用程序 (Applet)的设计
那么到底哪些是 Applet可以做的,哪些是不可以做
的呢?小应用程序所能够控制的安全程度是在浏览器
层次上实现的,小应用程序的安全机制通过 "沙箱
"(sandbox)控制。在大多数浏览器上,在沙箱内运行时,
缺省地禁止以下操作:
● 运行时执行另一程序:小应用程序绝不能运行任何
一个本地可执行程序。
● 任何文件的输入 /输出:小应用程序不能读 /写本地计
算机的文件系统。
第 12章 Java 小应用程序 (Applet)的设计
● 调用任何本地方法:除了所用 Java版本号,操作系
统名和版本号,小应用程序不能获取任何与本地计算
机有关的信息,也不能通过调用任何本地方法,API等
方法获得。特别是,小应用程序不能获得用户名、电
子邮件地址等等信息。
● 尝试打开除提供 Applet的主机之外的任何系统的
Socket:除了下载它的服务器之外,小应用程序不能和
任何一台主机通信。
第 12章 Java 小应用程序 (Applet)的设计
这些限制的关键在于:通过限制 Applet对系统文件
的存取来阻止它侵犯一个远程系统的隐私或破坏该系
统;禁止执行另一程序和不允许调用本地方法限制了
Applet启动未经 JVM检查的代码;对 Socket的限制则禁
止了与另一个可能有危害性的程序的通信。
由于小应用程序是由 JVM(Java Virtual Machine)解
释执行的字节码,而非由 CPU直接执行的机器码,所
以只要在 JVM中检查了小应用程序的指令和程序区域,
就可以确定,小应用程序不会对用户计算机系统造成
较大的危害。表 12.1显示了小应用程序在沙箱中运行时
的功能。
第 12章 Java 小应用程序 (Applet)的设计
表 12.1 小应用程序的功能
浏览器中运行 小应用程序观察器中运行
读 /写本地文件 否 是
获取文件信息 否 是
删除文件 否 是
运行另一程序 否 否
读取 username属性 否 是
连接服务器上的网络端口 是 是
连接另一台主机上的网络端口 否 是
下载 Java库 否 是
调用退出 否 是
创建一个弹出试窗口 带有警告信息 是
第 12章 Java 小应用程序 (Applet)的设计
在这些限制下,小应用程序的能力似乎大打折扣
了,这对那些恶意的设计者是有效的措施,但是也给
开发者们造成了限制。如果没有办法打破这些限制,
那么小应用程序所能做的就太有限了。对此,Java的
设计者也提供了解决办法,那就是签名类。小程序提
供者可以编写一个带有签名的 Applet,当浏览器下载并
运行这个 Applet的时候,会提示用户这是一个签名
Applet类,并询问用户是否信任该设计者。如果取得用
户的信任,那么这个 Applet就可以突破所有的限制,像
一个普通应用程序那样在用户的计算机上运行了。
第 12章 Java 小应用程序 (Applet)的设计
12.1.3 Applet的主要方法
Applet类的一些主要方法有:
● public void init()
该方法在 Applet被浏览器载入内存后自动调用,通
常用来初始化数据的值。本方法只在 Applet首次装入时
被调用,并在调用 start()方法前完成。假如要创建一个
Applet生存期内的线程,就可以在该方法中创建,在
destory方法中结束。
第 12章 Java 小应用程序 (Applet)的设计
● public void start()
当 init()方法完成后,浏览器会自动调用 start()方法。
它的执行使得 Applet成为 "活动 "的。并且每次 Applet成
为可见的时,它都要执行一次,如:当浏览器在被最
小化后又恢复时,或者从其他 web页返回含有这个
Applet的页面时。通常我们把主要程序代码写在这里,
这一方法的典型用法是启动动画和播放声音。
第 12章 Java 小应用程序 (Applet)的设计
● public void stop()
当浏览器切换到另一个 web页面或将要关闭时,会
自动调用 stop()方法。通常在该方法中加入一些暂停动
作,例如暂停音乐或动画的播放,以便用户从其他
Web页面切换回包含该 Applet的页面时,可以通过调用
start()方法继续播放下去。
第 12章 Java 小应用程序 (Applet)的设计
● public void destroy()
用户关闭浏览器时,必须终止 Applet的运行,并
回收资源。此时,destroy()方法会自动被调用。该方
法是 Applet在生存期中执行的最后一个方法,所以通
常在这里释放一些在 init()中分配的资源,如创建的线
程等。浏览器在调用 destory()方法时,会先调用一次
stop()方法。
第 12章 Java 小应用程序 (Applet)的设计
● public AudioClip getAudioClip(URL url)
返回由参数 url所指定的 AudioClip对象。 AudioClip
是一个音频剪辑对象的接口,它提供了音频对象的抽
象控制。无论 url指定的音乐文件是否存在,
getAudioClip()方法都会很快返回值,因为音频文件要
等到播放的时候才下载。 url参数指定的必须是一个绝
对地址。
● public URL getCodeBase()
返回 Applet所在网址。
● public URL getDocumentBase()
返回包含该 Applet对象的 Web页面的地址。
第 12章 Java 小应用程序 (Applet)的设计
● public Image getImage(URL url)
返回参数 url所指定的图片文件的 Image对象。和
getAudioClip()方法类似,不管指定地址的文件是否存
在,getImage()方法都会立即返回值。图片文件在
Applet显示在屏幕上时才会下载。 url参数指定的必须
是一个绝对地址。
● public String getParameter(String name)
返回由 HTML文件所提供的参数信息。 Applet提供
了从 Web页面文件中提取参数的方法,可以在 HTML文
件中通过 <param>标记设置一些参数供 Applet使用,例
如有如下的 HTML代码:
第 12章 Java 小应用程序 (Applet)的设计
<applet code="Clock" width=50 height=50>
<param name=Color value="blue">
</applet>
调用 "getParameter("Color")"将返回 "blue"。注意参
数名是不区分大小写的。
● public Boolean isActive()
检查 Applet是否处于活动状态。当浏览器调用 start()
方法时,Applet即进入活动状态,而一旦 stop()方法被
调用,即进入非活动状态。
第 12章 Java 小应用程序 (Applet)的设计
● public void play(URL url)
播放由参数 url指定的音频剪辑,如果该音频剪辑
不存在,则不做任何事情。 url参数指定的必须是一个
绝对地址
● public void showStatus(String msg)
在浏览器的状态栏上显示由参数 msg指定的文字信
息,以便通知用户 Applet的当前状态。
通过第一节的例子,我们已经明白了 Applet运行的
方式和它的生命周期。下面我们通过实例来学习如何
运用以上方法写出有趣的 Applet。
第 12章 Java 小应用程序 (Applet)的设计
例 12.3 ShowImageApplet.java
import java.applet.*;
import java.awt.*;
import java.net.*;
public class ShowImageApplet extends Applet
{
String ImageName = null;
String AudioName = null;
Image img = null;
AudioClip audio = null;
第 12章 Java 小应用程序 (Applet)的设计
public void init()
{
ImageName = getParameter("image");
img = getImage(getDocumentBase(),ImageName);
AudioName = getParameter("audio");
audio = getAudioClip(getDocumentBase(),
AudioName);
}
public void start()
{
audio.play();
}
第 12章 Java 小应用程序 (Applet)的设计
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);
}
}
ShowImageApplet.html
<html>
<body>
<applet name="Image Shower"
code=ShowImageApplet.class width=200 height=100>
第 12章 Java 小应用程序 (Applet)的设计
<param name="image" value="getJava.gif">
<param name="audio" value="windows start.wav">
</applet>
</body>
</html>
第 12章 Java 小应用程序 (Applet)的设计
图 12.4
第 12章 Java 小应用程序 (Applet)的设计
这个例子展示了如何通过 getImage()方法载入一个图
片对象,并将它显示在浏览器中以及在启动 Applet的时
候播放一段音乐。首先,通过 getParameter()方法从
HTML代码中提取出参数,即 Image和 Audio文件的文件
名。然后通过 getImage()方法和 getAudioClip()方法取得
Image和 Audio文件的对象。它们包括两个参数,
getDocument()返回包含 Applet的 Web页所在的地址,第
二个参数 getJava.gif指定图片文件名。最后在 start()方法
中播放音乐。这样,Applet每次启动时都会伴随着一段
音乐。在 paint()方法中调用 drawImage()方法显示图片,
运行时图片 getJava.gif和 windows start.wav两个文件必须
和 ShowImageApplet.html文件在同一目录下,其运行结
果如图 12.4所示。
第 12章 Java 小应用程序 (Applet)的设计
运行结果如图 12.4所示。
值的注意的是,如果通过图片来源地址
http://java.sun.com/getjava/images/getJava_head.gif来构
造一个 URL对象,并通过 getImage()方法载入它的话可
能会引发一个访问违例。这是由于 Applet的安全机制。
前面已经提到,Applet禁止:包含该 Applet的 Web页面
所在主机以外的其他任何机器通信。所以无法从其他
的 URL下载一个资源。
第 12章 Java 小应用程序 (Applet)的设计
12.1.4 Applet标记
以下为 Applet标记的完整句法:
<applet>
[archive=archiveList]
code=appletFile.class
width=pixels height=pixels
[codebase=codebaseURL]
[alt=alternateText]
[name=appletInstanceName]
[align=alignment]
[vspace=pixels] [hspace=pixels]
>
第 12章 Java 小应用程序 (Applet)的设计
[<param name=appletAttribute1 value=value>]
[<param name=appletAttribute2 value=value>]
.,,
[alternateHTML]
</applet>
这些标记的意义如下:
● archive = archiveList
这一可选属性描述了一个或多个含有将被 "预装 "的
类和其他资源的 archives。类的装载由带有给定
codebase的 AppletClassLoader的一个实例来完成。
ArchiveList中的 archives以逗号 (,)分隔。
第 12章 Java 小应用程序 (Applet)的设计
● code = appletFile.class
这是一个必需的属性,它给定了含有已编译好的
Applet子类的文件名。也可用 package.appletFile.class的
格式来表示。
注:这个文件与你要装入的 HTML文件的基 URL有
关,它不能含有路径名。要改变 Applet的基 URL,可使
用 <codebase>。
● width = pixels height = pixels
这些必需的属性给出了 Applet显示区域的初始宽度
和高度 (以像素为单位 ),不包括 Applet所产生的任何窗
口或对话框。
第 12章 Java 小应用程序 (Applet)的设计
● codebase = codebaseURL
这一可选属性指定了 Applet的基 URL―― 包含有
Applet代码的目录。如果这一属性未指定,则采用文档
的 URL。
● alt = alternateText
这一可选属性指定了当浏览器能读取 Applet标记,
但不能 执行 Java Applet时要显示的文本。
● name = appletInstanceName
这个可选属性为 Applet实例指定有关名称,从而使
得在同一页面上的 Applet可找到彼此 (以及互相通信 )。
第 12章 Java 小应用程序 (Applet)的设计
● align = alignment
这个可选属性指定了 Applet的对齐方式。它的可取
值与基本的 HTML中 IMG标记的相应属性相同,为 left,
right,top,texttop,middle,absmiddle,baseline,bottom和
absbottom等。
● vspace = pixels hspace = pixels
这些可选属性指定了在 Applet上下 (vspace)及左右
(hspace)的像素数目。其用法与 IMG标记的 vspace和
hspace属性相同。
第 12章 Java 小应用程序 (Applet)的设计
● <param name = appletAttribute1 value = value>
这个标记提供了一种可带有由 "外部 "指定的数值的
Applet,它对一个 Java应用程序的作用与命令行参数相
同。 Applet用 getParameter()方法来存取它们的属性,该
方法将在稍后作更详细的讨论。
不支持 Java程序执行的浏览器将显示被包括在
<applet>和 </applet>标记之间的任何常规的 HTML;而
可支持 Java技术的浏览器则忽略介于这两个标记之间
的 HTML代码。
第 12章 Java 小应用程序 (Applet)的设计
12.1.5 从 Applet中弹出窗口
有时候我们可能觉得浏览器的界面不利于布局管
理,一个浮在顶端的窗口或对话框更能引人注目。实
际上,确实可以从 Applet程序中弹出一个如同应用程序
一般的窗口来。这有时也有利于我们将现成的应用程
序转成小应用程序,如果我们只是仅仅想它通过浏览
器下载运行,而不需要做太多功能上的调整,从 Applet
程序中弹出一个窗口也许是个好的解决办法,也就是
给它披上一个 Applet的外壳。下面这个例子是一个小型
的计算器的程序,它通过 Applet的一个按键弹出一个
Frame,而计算器功能的实现都在 Frame中。 Applet的
功能仅仅是从浏览器启动它,仅仅是它的一层外壳。
第 12章 Java 小应用程序 (Applet)的设计
例 12.4 CalculatorApplet.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class CalculatorApplet extends Applet
implements ActionListener
{
// 弹出的窗口
private Frame calcFrame = new CalculatorFrame();
public void init()
第 12章 Java 小应用程序 (Applet)的设计
{
// 弹出的按键
Button calcButton = new Button("Calculator");
calcButton.addActionListener(this);
add(calcButton);
}
public void actionPerformed(ActionEvent evt)
{
// 弹出窗口如果没有被显示,则显示它,否则关闭它
if (calcFrame.isVisible())
calcFrame.setVisible(false);
第 12章 Java 小应用程序 (Applet)的设计
else
calcFrame.setVisible(true);
}
}
class CalculatorFrame extends Frame
implements ActionListener
{
private TextField display = null;
private double arg1 = 0;
private StringBuffer arg2 = new StringBuffer();
private char op = '=';
第 12章 Java 小应用程序 (Applet)的设计
public CalculatorFrame()
{
setTitle("Calculator");
setSize(200,200);
setLayout(new BorderLayout());
// 输出窗口
display = new TextField("0");
display.setEditable(false);
add(display,"North");
// 数字按键盘
Panel keypad = new Panel();
第 12章 Java 小应用程序 (Applet)的设计
Panel keypad = new Panel();
keypad.setLayout(new GridLayout(4,4));
// 添加数字和运算符按键
String keys = "789/456*123-0.=+";
for (int i = 0; i < keys.length(); i++)
{
Button btn = new Button(keys.substring(i,i+1));
keypad.add(btn);
// 为按键添加事件监听器
btn.addActionListener(this);
}
add(keypad,"Center");
第 12章 Java 小应用程序 (Applet)的设计
}
public void actionPerformed(ActionEvent evt)
{
// 响应按键,如果是数字则连接到 StringBuffer中,
// 如果是运算符则进行运算。
String key = evt.getActionCommand();
char c = key.charAt(0);
if ((c >= '0' && c <= '9') || c == '.' ||
(c == '-' && arg2.length() == 0))
{
arg2.append(c);
display.setText(arg2.toString());
第 12章 Java 小应用程序 (Applet)的设计
}
else
{
calculate(Double.parseDouble(arg2.toString()));
op = c;
arg2.setLength(0);
if (c == '=')
arg2.append(arg1);
}
}
public void calculate(double arg2)
{
第 12章 Java 小应用程序 (Applet)的设计
// 计算
switch (op)
{
case '+',arg1 += arg2; break;
case '-',arg1 -= arg2; break;
case '*',arg1 *= arg2; break;
case '/ ',arg1 /= arg2; break;
case '=',arg1 = arg2; break;
default,break;
第 12章 Java 小应用程序 (Applet)的设计
}
display.setText(""+arg1);
}
}
这个窗口是一个功能简陋的计算器面板。由于只
需给它配上最简单的 HTML代码,所以这里不再列出。
图 12.5是该程序的运行结果。
第 12章 Java 小应用程序 (Applet)的设计
图 12.5
弹出窗口 Applet
第 12章 Java 小应用程序 (Applet)的设计
我们注意到,在弹出窗口的最底下有一行字 "Java
Applet Window",这是对这个窗口的一个说明,也是
所有浏览器都具备的一个安全特性。它提示用户这是
一个由运行于浏览器的 Applet弹出的窗口,而不是从机
器上运行的一个程序。试想如你运行了一个恶意的
Applet程序,它可能会弹出一个窗口,这个窗口与你本
地某个需要输入账号、密码的应用程序有着相同的界
面,也许你会被它蒙蔽而错误性的输入了信息,这个
Applet就会把这些信息送回主机。
第 12章 Java 小应用程序 (Applet)的设计
为了避免这种恶作剧出现,所有的弹出窗口都在底
端显示一个标签,警告用户这是一个小应用程序,而
不是本地应用程序。当然,如果你制作一个签名的小
应用程序并得到了用户的信任,则可以不显示这个警
告标签。
值的一题的是,正如前面所说,这个小应用程序
只是通过 Applet来启动了一个弹出窗口,如果在
CalculatorApplet类中为它加入一个 mian()方法的话,它
就可以同时作为 Applet和应用程序来运行,大家可以自
己试试。
第 12章 Java 小应用程序 (Applet)的设计
12.1.6 基于 Swing与 AWT的 Applet的区别
我们已经知道,Applet类是从 AWT包中的 Panel类
派生的,而 Java2提供的新一代 GUI设计包 Swing也提供
了支持 Applet设计的类,javax.swing.Japplet。注意,
JApplet类并不是从 JPanel类派生的,而是直接从
java.applet.Applet类派生出来的。
用 AWT设计小应用程序时,我们从
java.applet.Applet类派生一个子类,现在为了使用
Swing包,就必须从 avax.swing.JApplet类派生子类。让
我们先来看一个基于 JApplet类的小应用程序的实例,
然后再分析二者的区别。
第 12章 Java 小应用程序 (Applet)的设计
例 12.5 JAppletTest.java
import java.awt.*;
import javax.swing.*;
public class JAppletTest extends JApplet
{
private JMenuBar menuBar = new JMenuBar();
public void init()
{
第 12章 Java 小应用程序 (Applet)的设计
Container contentPane = getContentPane();
Image img = getImage(getDocumentBase(),
"getJava.GIF");
Icon icon = new ImageIcon(
getImage(getDocumentBase(),"getJava.GIF"));
JLabel label = new JLabel("Swing!",icon,
SwingConstants.CENTER);
第 12章 Java 小应用程序 (Applet)的设计
contentPane.add(label,BorderLayout.CENTER);
JMenu fileMenu = new JMenu("File");
String[] fileItems = {"New","Open","Save","Exit"};
for (int i = 0; i < fileItems.length; i++)
fileMenu.add(fileItems[i]);
JMenu helpMenu = new JMenu("Help");
String[] helpItems = {"Help of help","About"};
for (int i = 0; i < helpItems.length; i++)
helpMenu.add(helpItems[i]);
第 12章 Java 小应用程序 (Applet)的设计
menuBar.add(fileMenu);
menuBar.add(helpMenu);
setJMenuBar(menuBar);
}
}
该程序的运行结果如图 12.6所示。在该程序中,为
小应用程序加入了一个菜单条,这也是基于 Swing的小
应用程序的一种新特性。
第 12章 Java 小应用程序 (Applet)的设计
图 12.6
第 12章 Java 小应用程序 (Applet)的设计
从上面的例子来看,基于 Swing的小应用程序和基
于 AWT的小应用程序在架构上没有什么分别,它们的
生存方式也是相同的,所以上述例子中也没有给出
start(),stop(),destory()这些方法,而是使用了默认的
方法,但是,有几点需要注意:
(1) JApplet类默认使用 BorderLayout作为其容器的
布局管理器,其默认约束条件是
BordenLayout.CENTER,而 Applet的缺省的布局管理器
是 FlowLayout,且 FlowLayout的缺省约束条件是
FlowLayout.LEFT,这是二者最显著的区别之一。
第 12章 Java 小应用程序 (Applet)的设计
(2) JApplet是只包含一个组件的容器,这个组件就
是 JRootPane的一个实例,而 JRootPane包含了一个称作
内容窗格的容器。
(3) "内容窗格 "包含与特定的小应用程序有关的所
有内容,可通过 getContentPane()方法获得。即是说,
小应用程序必须把所有的组件添加到内容窗格中,而
Applet则是把它们直接添加到小应用程序中。
(4) 我们不能直接为小应用程序设置布局管理器,
而只能对它的内容窗格设置布局管理。
(5) JApplet的实例可以有一个菜单栏,它是由
setJMenuBar()方法指定的,而 AWT小应用程序却不能。
第 12章 Java 小应用程序 (Applet)的设计
基于 Swing的小应用程序比基于 AWT的小应用程序有
更多的优势,它可以使用 Swing提供的更多界面元素和性
能。但是它也有一个很大的缺陷,那就是很多浏览器都
不能支持 Swing编写的小应用程序,而必须依靠安装 Java
Plug-in包。虽然可以让浏览器在运行 Swing小应用程序时
自动下载这个包,但是由于 Java Plug-in包并不小,所以
对于非宽带上网的用户来说是不可忍受的。
第 12章 Java 小应用程序 (Applet)的设计
12.2 Applet的通信
12.2.1 Applet与浏览器的通信
我们已经学习过如何通过 getParameter()方法从浏
览器的 Web页中获取信息,同时,Applet也可以要求浏
览器为自己做事,例如我们可以让浏览器打开一个指
定的 Web页。为了与浏览器通信,需调用 Applet的
getAppletContext()方法。这个方法返回一个实现了
AppletContext接口的对象,这个接口是实现 Applet和浏
览器通信的一座桥梁。
第 12章 Java 小应用程序 (Applet)的设计
除了 getAudioClip()和 getImage()外,AppletContext
接口还提供了四个有用的方法,它们是 get-Applet()、
getStream(),showDocument()和 showStatus(),我们将
在本节和下面的小节中讲述它们的用法。
在小应用程序中可以访问浏览器的两个区:状态
行和页面显示区,但都必须通过调用 AppletContext接
口中的方法来实现。
通过调用 showStatus(String status)方法,可以在浏
览器底部的状态行中显示一行字符串提示信息,例如:
showStatus("Loading Data…please wait");
第 12章 Java 小应用程序 (Applet)的设计
但是,遗憾的是,使用 showStatus()显示提示信息
的功能很有限,因为浏览器自己也在使用状态行,而
且经常使用。它总是用新的提示信息改写前一次的信
息,用户往往无法注意到某一条信息,所以不能用该
方法来显示一些重要信息。
在浏览器页面显示区显示信息的方法是
showDocument(),它可以通知浏览器打开一个指定的
URL资源。 showDocument()方法的定义如下:
showDocument(URL url);
showDocument(URL url,String target);
第 12章 Java 小应用程序 (Applet)的设计
第一种格式的调用可以让浏览器直接打开一个新的
URL资源,并将它显示在当前浏览器显示区中,替换原
来显示的 Web页面。第二种格式的调用多了一个 String
类型的参数,第一个参数依然是指定要显示的 URL资源,
第二个参数则用于指明浏览器打开页面的方式。如果指
定值为 "_blank",浏览器就会另外打开一个新窗口,在
新的浏览器窗口中显示指定的 Web页。如果使用
HTML3.2以上版本提供的帧特性,则可以将一个浏览
器的窗口分成多个帧,并给每个帧指定一个名字。用户
可以把自己的 Applet放入一个帧中,并利用它来控制其
他帧的页面显示。
表 12.2展示了可以用作 ShowDocument()方法的第二
个参数的所有字符串及其功能。
第 12章 Java 小应用程序 (Applet)的设计
表 12.2 show Document参数
showDocument()的两个参数 位 置
“_self”或无 显示在当前帧内
“_parent” 显示在父容器帧内
“_top” 显示在顶层帧内
“_blank” 显示在一个新打开的浏览器窗口中
其他字符 显示在该字符串指定名的帧内, 如果没有该帧, 就打开一个新窗口显示, 并把这个名称
指定给他
第 12章 Java 小应用程序 (Applet)的设计
例 12.6 Bookmark.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Bookmark extends Applet
implements ItemListener
{
第 12章 Java 小应用程序 (Applet)的设计
private List links = new List();
public void init()
{
int i = 1;
String s;
while ((s = getParameter("link"+i)) != null)
{
links.add(s);
i++;
}
第 12章 Java 小应用程序 (Applet)的设计
}
public void itemStateChanged(ItemEvent evt)
{
List source = (List)evt.getSource();
String link = source.getSelectedItem();
try
{
AppletContext context = getAppletContext();
URL url = new URL(link);
context.showDocument(url,"right");
第 12章 Java 小应用程序 (Applet)的设计
}
catch (Exception e)
{
showStatus("Error " + e);
}
}
}
Bookmark.html
<html>
第 12章 Java 小应用程序 (Applet)的设计
<head>
<title>Bookmark Applet</title>
<head>
<frameset cols="300,*">
<frame name="left" src="left.html">
<frame name="right">
</frameset>
<html>
// Left.html
<html>
第 12章 Java 小应用程序 (Applet)的设计
<title>A Bookmar Applet</title>
<body>
<Applet code="Bookmark.class" width=250
height=200>
<param name=link1 value="http://java.sun.com/">
<param name=link2 value="http://www.szptt.net.cn/">
<param name=link3 value="http://www.163.net/">
<param name=link4 value="http://www.21cn.com/">
<param name=link5
value="http://www.yahoo.com.cn/">
</applet>
</body>
<html>
第 12章 Java 小应用程序 (Applet)的设计
这个小应用程序利用了 HTML3.2以上版本的窗口分
帧的特性,将浏览器的页面显示区垂直地分成了两个
帧。左边的帧包含了上面的 Bookmark小应用程序,它
在一个列表框中列出了一列网址。点击其中任何一个
网址,就会在右边的帧中显示出相应的 Web页来。这
个功能类似收藏夹的小应用程序在浏览器中运行,结
果如图 12.7所示。
第 12章 Java 小应用程序 (Applet)的设计
图 12.7
第 12章 Java 小应用程序 (Applet)的设计
12.2.2 同页 Applet之间的通信
我们已经学习了如何在一个 Web页面中嵌入 Applet,
实际上,完全可以在同一个 Web页上嵌入一个以上的
小应用程序,甚至还可以让这些 Applet互相通信,互相
控制。要实现 Web页中的不同 Applet之间的通信,这些
Applet的 codebase必须是相同的,即它们的 class文件放
在服务器上的同一路径下。
第 12章 Java 小应用程序 (Applet)的设计
Applet之前的通信是一个高级技巧。我们还记得
在嵌入小应用程序的 <applet>标记中有一个 name参数,
我们可以通过这个参数为嵌入的小应用程序赋予一个
名字。然后调用 AppletContext接口的 getApplet()方法,
获得对这个小应用程序的一个引用。利用这个应用,
就可以调用小应用程序中任何 public的方法。请看如
下例子。
第 12章 Java 小应用程序 (Applet)的设计
例 12.7 ListApplet.java
import java.applet.*;
import java.awt.*;
public class ListApplet extends Applet
{
private List list = new List();
public void init()
第 12章 Java 小应用程序 (Applet)的设计
{
setLayout(new BorderLayout());
add(list);
}
public void addItem(String item)
{
list.add(item);
}
}
第 12章 Java 小应用程序 (Applet)的设计
import Applet.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class InputerApplet extends Applet
implements ActionListener
{
private TextField inputer = new TextField();
第 12章 Java 小应用程序 (Applet)的设计
private Button addBtn = new Button("ADD");
private Applet listApplet;
public void init()
{
AppletContext context = getAppletContext();
listApplet = context.getApplet("ListApplet");
add(inputer);
addBtn.addActionListener(this);
add(addBtn);
第 12章 Java 小应用程序 (Applet)的设计
}
public void actionPerformed(ActionEvent evt)
{
String item = inputer.getText();
System.out.print(item);
((ListApplet)listApplet).addItem(item);
}
}
第 12章 Java 小应用程序 (Applet)的设计
TwoAppletDemo.html
<html>
<title>A Bookmar Applet</title>
<body>
<applet code="ListApplet.class" width=100 height=100
name="ListApplet">
</applet> <p>
第 12章 Java 小应用程序 (Applet)的设计
图 12.8
第 12章 Java 小应用程序 (Applet)的设计
<applet code="InputerApplet.class" width=100 height=100
name="InputerApplet">
</applet>
</body>
<html>
这个例子是在一个 Web页面中插入两个小应用程
序。第一个小应用程序叫 ListApplet,它包含一个 List
组件,并实现一个向 List中添加字符串项的方法。
第 12章 Java 小应用程序 (Applet)的设计
第二个小应用程序叫 InputerApplet,它包含一个
TextField和一个 Button,点击这个 Button,就可以将
TextField中输入的文字添加到第一个小应用程序的 List
中。方法就是通过调用 getApplet()方法获得
InputerApplet的一个引用,然后通过这个引用调用
ListApplet中的方法 AddItem()。程序的运行结果如图
12.8所示。
第 12章 Java 小应用程序 (Applet)的设计
12.2.3 Applet网络通信设计
前面已经讲过,小应用程序的安全机制规定 Applet
只能与它所在 Web页面的服务器通信。 Applet与服务器
之间的通信除了可以利用 getAudioClip()和 getImage()这
两个方法获取服务器上的资源外,还可以通过和服务
器上的服务程序建立 Socket连接来实现。当然 Applet绝
不能和其他的主机建立 Socket连接。
第 12章 Java 小应用程序 (Applet)的设计
利用 Applet做网络服务的客户端的做法是很常见的,
例如一些股票行情的实时走势显示的 Applet等。在
Applet中,使用 Socket编程和在应用程序中编程没有什
么不同,本章中不再举例,大家可以自己尝试。但是,
Applet和服务器之间的通信还有一种特殊的方式,就是
和服务器上一种叫作 Servlet的 Java服务程序通信。
Applet和 Servlet的通信方式是非常方便和实用的。有关
Servlet的知识在本书中不做讲解,有兴趣的读者可以
参考有关资料。