天天看点

Java applet(小程序)介绍(转)

导读:

  

  Java applet(小程序)介绍

  关键词: Java applet

  本节讨论了JDK对Applet的支持,以及Applet在编程方式、操作上下文和

  如何开始等方面与应用程序的区别。

  7.1·什么是Applet?

  Applet是能够嵌入到一个HTML页面中,且可通过Web浏览器下载和执行的

  一种Java类。它是Java技术容器(container)的一种特定类型,其执行

  方式不同于应用程序。一个应用程序是从它的main()方法被调用开始的,

  而一个Applet的生命周期在一定程度上则要复杂得多。本模块分析了

  Applet如何运行,如何被装载到浏览器中,以及它是如何编写的。

  7.1.1·装入Applet

  由于Applet在Web浏览器环境中运行,所以它并不直接由键入的一个命令启动。

  你必须要创建一个HTML文件来告诉浏览器需装载什么以及如何运行它。

  1. 浏览器装入URL

  2. 浏览器装入HTML文档

  3. 浏览器装入Applet类

  4. 浏览器运行Applet

  7.1.2·Applet的安全限制

  由于通过网络装载,Applet的代码具有一种内在的危险性。如果有人编写了

  一个恶意的类来读取你的密码文件,并把它通过Internet传送,会产生怎样

  的后果呢?所能够控制的安全程度是在浏览器层次上实现的。大多数浏览器

  (包括Netscape Nevigator)缺省地禁止以下操作:

  -- 运行时执行另一程序

  -- 任何文件的输入/输出

  -- 调用任何本地方法

  -- 尝试打开除提供Applet的主机之外的任何系统的Socket

  这些限制的关键在于,通过限制Applet对系统文件的存取来阻止它侵犯一个

  远程系统的隐私或破坏该系统。禁止执行另一程序和不允许调用本地方法

  限制了Applet启动未经JVM检查的代码。对Socket的限制则禁止了与另一个

  可能有危害性的程序的通信。JDK1.2提供了一种方式,它指定了一个特殊的

  "保护域"或一个特殊Applet运行的安全性环境。远程系统检查原始的URL以

  及它下载的Applet的签名,和一个含有从特殊的Applet到特殊保护域的映射

  入口的本地文件进行比较。因此,来自特别位置的特殊Applet具有一些

  运行特权。

  7.2·编写一个Applet

  要编写一个Applet,必须首先用以下方式创建一个类:

  import java.applet.*;

  public class HelloWorld extends Applet {

  Applet的类必须为public,且它的名称必须与它所在的文件名匹配;在这里,

  就是HelloWorld.java。而且,该类必须为java.applet.Applet的子类。

  Applet类的层次

  Java.applet.Applet类实际上是java.awt.Panel的子类。Applet和AWT类的

  层次如下:

  这种层次关系显示,一个Applet可直接用作一个AWT布局的起始点。因为

  Applet为一Panel,所以它有一个缺省的流(flow)布局管理器。

  Component,Container和Panel类的方法被Applet类继承了下来。

  7.2.1·主要的Applet方法

  在一个应用程序中,程序由main()方法处进入,而在一个Applet中却不是

  这样。在构造函数完成了它的任务后,浏览器调用init()对Applet进行

  基本的初始化操作。init()结束后,浏览器调用另一个称为start()的方法。

  本模块稍后将对start()做更细致的剖析;start()通常在Applet成为可见

  时被调用。方法init()和start()都是在Applet成为"活动的"之前运行

  完成的,正因为这样,它们都不能用来编写Applet中继续下去的动作。

  实际上,与一个简单应用程序中的方法main()不同的是,没有什么方法的

  执行是贯穿于Applet的整个生命过程中的。你在后面将看到如何使用线程

  来实现这一特色。此外,你在编写Applet子类时可用的方法还有:stop(),

  destroy()和paint()。

  7.2.2·Applet显示

  Applet本质上是图形方式的,所以尽管你可以提出System.out.println()

  的调用请求,通常也不能这样做,而是应该在图形环境中创建你的显示。

  你可以通过创建一个paint()方法在Applet的panel上绘图。只要Applet

  的显示需要刷新,paint()方法就会被浏览器环境调用。例如,当浏览器

  窗口被最小化或被要求以图标方式显示时,这种调用就会发生。你应该编

  写自己的paint()方法,以使它在任何时候被调用时都能正常地工作。

  对它的调用是异步产生的,且由环境而不是程序来驱动。

  7.2.3·paint()方法和图形对象

  paint()方法带有一个参数,它是java.awt.Graphics类的一个实例。这个

  参数总是建立该Applet的panel的图形上下文。你能用这个上下文在你的

  Applet中绘图或写入文本。下面是使用paint()方法写出文字的一例。

  1.import java.awt.*;

  2.import java.applet.*;

  3.

  4.public class HelloWorld extends Applet {

  5.

  6.public void paint(Graphics g){

  7.g.drawString("Hello World!", 25, 25);

  8.}

  9.}

  注-drawString方法的数字型参数为文本起始处的x和y的象素坐标。

  (0,0)表示左上角。这些坐标是针对字体的基线来讲的,所以在y坐标

  为0处写的结果是:文字的大部分在显示器顶部的上方,只有象字母y尾部

  那样的下面部分是可见的。

  7.3·Applet的方法和Applet的生命周期

  Applet的生命周期比所讨论的要稍微复杂一些。与其生命周期相关的有三个

  主要方法:init(),start()和stop()。

  7.3.1·init()

  本成员函数在Applet被创建并装入一个能支持Java技术的浏览器

  (如appletviewer)时被调用。Applet可用这个方法来初始化数据的值。

  本方法只在Applet首次装入时被调用,并且在调用start()之前执行完成。

  7.3.2·start()

  init()方法一完成,start()就开始执行。它的执行使得Applet成为"活动"的。

  无论Applet何时成为可见的,它同样要执行一次,如:当浏览器在被图标化后

  又恢复时,或者当浏览器在链接到另一个URL后又返回含有这个Applet的

  页面时。这一方法的典型用法是启动动画和播放声音。

  1.public void start() {

  2.musicClip.play();

  3.}

  7.3.3·stop()

  stop()方法是在Applet成为不可见时被调用的,这种情况一般在浏览器被

  图标化或链接到另一个URL时会出现。Applet用该方法使动画停止。

  1.public void stop() {

  2.musicClip.stop();

  3.}

  start()和stop()形成一对动作:典型地,start()激活Applet中的某一行为,

  而stop()则可将它禁止。

  7.4·AWT绘图

  除了基本的生命周期外,Applet还有与其显示有关的一些重要的方法。这些

  方法的声明和文档在AWT组件类中。使用AWT做显示处理时遵循正确的模型是

  非常重要的。更新显示由一种被称为AWT线程的独立的线程来完成。这个线程

  可用来处理与显示更新相关的两种情况。第一种情况是显露(exposure),

  它或在首次显示时,或在部分显示已被破坏而必须刷新时出现。显示的破坏

  可能发生在任何时刻,因此,你的程序必须能在任意时刻更新显示。第二种

  情况是在程序重画带有新内容的画面时。这种重画可能会要求首先擦除原来

  的图像。

  7.4.1·Paint(Graphics g)方法

  显露处理自动地发生,且导致对paint()方法的一次调用。一种Graphics类

  的被称为裁剪矩形的设备常用于对paint()方法进行优化。除非必要,更新

  不会完全覆盖整个图形区域,而是严格限制在被破坏的范围内。

  7.4.2·repaint()方法

  对repaint()的调用可通知系统:你想改变显示,于是系统将调用paint()。

  7.4.3·update(Graphics g)方法

  repaint()实际上产生了一个调用另一方法update()的AWT线程。update

  方法通常清除当前的显示并调用paint()。update()方法可以被修改,

  如:为了减少闪烁可不清除显示而直接调用paint()。

  7.4.4·方法的交互

  下面的框图描述了paint(),update()和repaint()方法间的内在关系。

  图略

  7.4.5·Applet的显示策略

  Applet模型要求你采取一种特定的策略来维护你的显示:

  -- 维护一个显示模型。这个模型是对为再次提供显示而所需做的事情的一个

  定义。关于如何去做的指令在paint()方法中被具体化;这些指令所用的数据

  通常是全局成员变量。

  -- 使paint()提供仅仅基于该模型的显示。这使得无论paint()何时被调用,

  它都能以一致的方法再生该显示,并正确地处理显露问题。

  -- 使得程序对显示的改变,通过更新该模型而调用repaint()方法来进行,

  以使update()方法(最终是paint()方法)被AWT线程调用。

  注-一个单一AWT线程处理所有的绘图组件和输入事件的分发。应保持

  paint()和update()的简单性,以避免它们使AWT线程发生故障的可能性更大;

  在极端情况下,你将需要其他线程的帮助以达到这一目的。有关线程的编程

  是模块14的主题。

  7.5·什么是appletviewer?

  Applet通常运行于一个Web浏览器中,如HotJava TM或Netscape Navigator,

  它们有支持Java软件程序运行的能力。为了简化和加速开发过程,JDK应运而生,

  它附带有一个专为查看Applet而设计但不支持HTML页面查看的工具。这个工具

  就是appletviewer。appletviewer是使你不必使用Web浏览器即可运行

  Applet的一个Java应用程序。它犹如一个"最小化的浏览器"。appletviewer

  读取命令行中URL所指定的HTML文件。这个文件必须包含装入及执行一个或

  多个Applet的指令。appletviewer忽略了所有其他的HTML代码。它不能显示

  普通的HTML或嵌人在一个文本页中的Applet。

  7.5.1·用appletviewer启动Applet

  appletviewer将一个框架样式的区域粘贴在屏幕上,然后实例化该Applet并

  将这个Applet实例贴在已有的框架中。appletviewer带有一个命令行参数

  形式的URL,它指向一个含有Applet引用的HTML文件。这个Applet引用是

  一个指定了appletviewer要装载的代码的HTML标记。

  注意,这个标记的通用格式与任何其他的HTML相同,即,用 <和> 两个符号来

  分隔指令。上例中显示的所有部分都是必需的,你必须使用。

  其中

  -- archive = archiveList - 这一可选属性描述了一个或多个含有将被

  "预装"的类和其他资源的archives。类的装载由带有给定codebase的

  AppletClassLoader的一个实例来完成。ArchiveList中的archives以

  逗号(,)分隔。

  -- code = appletFile.class - 这是一个必需的属性,它给定了含有

  已编译好的Applet子类的文件名。也可用package.appletFile.class的

  格式来表示。

  注-这个文件与你要装入的HTML文件的基URL有关,它不能含有路径名。

  要改变Applet的基URL,可使用。

  7.6.2·描述

  -- width = pixels height = pixels - 这些必需的属性给出了Applet

  显示区域的初始宽度和高度(以象素为单位),不包括Applet所产生的任何

  窗口或对话框。

  -- codebase = codebaseURL - 这一可选属性指定了Applet的基

  URL――包含有Applet代码的目录。如果这一属性未指定,则采用文档的URL。

  -- alt = alternateText - 这一可选属性指定了当浏览器能读取Applet

  标记但不能执行Java Applet时要显示的文本。

  -- name = appletInstanceName - 这个可选属性为Applet实例指定有关

  名称,从而使得在同一页面上的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属性相同。

  -- - 这个标记

  提供了一种可带有由"外部"指定的数值的Applet,它对一个Java应用程序

  的作用与命令行参数相同。Applet用getParameter()方法来存取它们的

  属性,该方法将在本模块稍后作更详细的讨论。

  -- 不支持Java程序执行的浏览器将显示被包括在

  标记之间的任何常规的HTML;而可支持Java技术的浏览器则忽略介于这

  两个标记之间的HTML代码。

  7.7·其他的Applet工具

  在Applet中有若干其他特色。

  所有的Java软件程序都具有访问网络的特色,这可使用模块15中所讲到的

  java.net包中的类来实现。此外,Applet还有些其他的方法可允许它们取

  得有关自己启动时所在的浏览器环境的信息。类java.net.URL描述了URL,

  并可用于它们之间的连接。在Applet类中有两个方法决定了URL的重要的值:

  -- getDocumentBase()返回一个描述当前浏览器中带有Applet标记的HTML

  文件所属页面目录的URL对象

  -- getCodeBase()返回一个描述Applet类文件本身源目录的URL对象。它

  通常与HTML文件目录相同,但并不是一定要这样。

  其他的Applet特色

  用URL对象作为一个起始点,你可以将声音和图像取回到你的Applet中。

  -- getImage(URL base, String target)从被命名为target且位于由

  base所指定目录的文件中取回一幅图像。其返回值是类Image的一个实例。

  -- getAudioClip(URL base, String target) 从被命名为target且位

  于由base所指定目录的文件中取回一声音。其返回值是类Audio Clip的

  一个实例。

  注-getImage(URL, String)和getAudioClip(URL, String)方法中

  的String target能包括一个来自于URL的相对目录路径。但是请注意,

  在目录层次中向上的相对路径名,在某些系统上可能是不允许的。

  7.8·一个简单的图像测试

  下面的Applet获得了相对于getDocumentBase方法返回的目录路径为

  graphics/joe.gif的图像文件,并将它显示在appletviewer中:

  1.// HelloWorld extended to draw an image

  2.// Assumes existence of

  3.//"graphics/SurferDuke.gif"

  4.//

  5.import java.awt.*;

  6.import java.applet.Applet;

  7.

  8.public class HwImage extends Applet {

  9.Image duke;

  10.

  11.public void init() {

  12.duke = getImage(getDocumentBase(),

  13."graphics/SurferDuke.gif");

  14.}

  15.

  16.public void paint(Graphics g) {

  17.g.drawImage(duke, 25, 25, this);

  18.}

  19.}

  drawImage()方法的参数是:

  -- 将要被绘出的Image对象

  -- 绘图的x轴坐标

  -- 绘图的y轴坐标

  -- 图像观察者。图像观察者是可以得知该图像的状态是否改变的一个接口

  (如:在装入过程中发生了什么)。

  由getImage()装载的图像在调用首次提出后过一段时间将会改变,这是

  由于装载是在后台完成的。每次,图像的更多部分被装入,paint()

  方法被又一次调用。这种对paint()方法调用的发生是因为Applet将

  自己作为drawImage()的第四个参数传递给了自己,从而使自己被

  注册为一个观察者。

  7.8·一个简单的图像测试

  下面的Applet获得了相对于getDocumentBase方法返回的目录路径为

  graphics/joe.gif的图像文件,并将它显示在appletviewer中:

  1.// HelloWorld extended to draw an image

  2.// Assumes existence of

  3.//"graphics/SurferDuke.gif"

  4.//

  5.import java.awt.*;

  6.import java.applet.Applet;

  7.

  8.public class HwImage extends Applet {

  9.Image duke;

  10.

  11.public void init() {

  12.duke = getImage(getDocumentBase(),

  13."graphics/SurferDuke.gif");

  14.}

  15.

  16.public void paint(Graphics g) {

  17.g.drawImage(duke, 25, 25, this);

  18.}

  19.}

  drawImage()方法的参数是:

  -- 将要被绘出的Image对象

  -- 绘图的x轴坐标

  -- 绘图的y轴坐标

  -- 图像观察者。图像观察者是可以得知该图像的状态是否改变的一个接口

  (如:在装入过程中发生了什么)。由getImage()装载的图像在调用首次

  提出后过一段时间将会改变,这是由于装载是在后台完成的。每次,图像的

  更多部分被装入,paint()方法被又一次调用。这种对paint()方法调用的

  发生是因为Applet将自己作为drawImage()的第四个参数传递给了自己,

  从而使自己被注册为一个观察者。

  7.9·Audio Clips

  Java编程语言也具有播放Audio Clips的方法。这些方法在

  java.applet.AudioClip类中。为了播放Audio Clips,你将需要为你

  的计算机装配适当的硬件。

  7.9.1·播放一段Clip

  欣赏一段audio clip的最简单的方式是通过Applet的play方法:

  play(URL soundDirectory, String soundFile);

  或更简单的:

  play(URL soundURL);

  例如:

  play(getDocumentBase(), "bark.au");

  将播放存放在与HTML文件相同目录的bark.au。

  7.9.2·一个简单的Audio测试

  以下的Applet在appletviewer中打印出消息"Audio Test",然后播放

  audio文件sounds/cuckoo.au:

  1.//

  2.// HelloWorld extended to play an Audio sound

  3.// Assumes existence of "sounds/cuckoo.au" file

  4.//

  5.

  6.import java.awt.Graphics;

  7.import java.applet.Applet;

  8.

  9.public class HwAudio extends Applet {

  10.

  11.public void paint(Graphics g) {

  12.g.drawString("Audio Test", 25, 25);

  13.play(getDocumentBase(),"sounds/cuckoo.au");

  14.}

  15.}

  7.9.3·循环播放一段Audio Clip

  你可以用与装入图像相同的方式装入audio clip。在将它们装载之后进

  行播放。

  -- 装入一段Audio Clip

  为了装入一段Audio Clip,可使用来自java.applet.Applet类的

  getAudioClip方法:

  AudioClip sound;

  sound = getAudioClip(getDocumentBase(), "bark.au");

  一旦一段clip被装载,可选择与之相关的三个方法之一:play,loop,

  或stop。

  -- 播放Audio Clip

  使用java.applet.AudioClip接口中的play方法将已装入的audio clip

  播放一遍:

  sound.play();

  为了启动clip的播放并使它不断循环(自动重放),可使用

  java.applet.AudioClip中的loop方法:

  sound. loop();

  -- 停止Audio Clip

  要停止一段正在播放的clip,可用java.applet.AudioClip中的stop方法:

  sound. stop();

  7.9.4·一个简单的Audio循环测试

  下例中将一段装入的audio clip自动循环播放:

  1.//

  2.// HelloWorld extended to loop an audio track

  3.// Assumes existence of "sounds/cuckoo.au"

  4.//

  5.

  6.import java.awt.Graphics;

  7.import java.applet.*;

  8.

  9.public class HwLoop extends Applet {

  10.AudioClip sound;

  11.

  12.public void init() {

  13.sound = getAudioClip(getDocumentBase(),

  14."sounds/cuckoo.au");

  15.}

  16.

  17.public void paint(Graphics g) {

  18.g.drawString("Audio Test", 25, 25);

  19.}

  20.

  21.public void start() {

  22.sound.loop();

  23.}

  24.

  25.public void stop() {

  26.sound.stop();

  27.}

  注-JDK1.2支持一种新的声音引擎,这个引擎提供了对MIDI文件和

  全部 .wav,aiff及 .au文件的回放功能。它给出了一个新

  方法newAudioClip(URL url),这个方法从给定的URL获取

  一段audio clip,参数URL指向该audio clip。第13行中的

  getAudioClip方法可用这个方法替换。NewAudioClip方法不需要

  第二个参数String,只有URL参数要求被传递。

  7.10·鼠标输入

  Java编程语言所支持的最有用的特色之一是直接的交互动作。Java Applet,

  同应用程序一样,能注意到鼠标,并对鼠标事件作出反应。在这里,我们将对

  鼠标的支持作一次快速的回顾,以帮助理解下面的例子。

  回想一下模块9中,JDK1.2事件模型对每一类交互动作都支持一种事件类型。

  鼠标事件由实现MouseListener接口的类来接收,它们可接收的事件为:

  -- mouseClicked -鼠标已被点击(鼠标按钮被按下然后被释放,作为一个动作)

  -- mouseEntered -鼠标光标进入一个组件

  -- mouseExited -鼠标光标离开一个组件

  -- mousePressed -鼠标按钮被按下

  -- mouseReleased -鼠标按钮被释放

  7.10.1·一个简单的Mouse测试

  下面的程序显示了鼠标在Applet中点击的位置:

  1.//

  2.// HelloWorld extended to watch for mouse input

  3.// "Hello World!" is reprinted at the location of

  4.// the mouse click.

  5.//

  6.

  7.import java.awt.*;

  8.import java.awt.event.*;

  9.import java.applet.Applet;

  10.

  11.public class HwMouse extends Applet

  12.implements MouseListener {

  13.

  14.int mouseX=25;

  15.int mouseY=25;

  16.

  17.// Register this applet instance to catch // MouseListener events

  18.public void init () {

  19.addMouseListener (this);

  20.}

  21.

  22.public void paint(Graphics g) {

  23.g.drawString("Hello World!", mouseX, mouseY);

  24.}

  25.

  26.// Process the mousePressed MouseListener event

  27.public void mousePressed(MouseEvent evt){

  28.mouseX = evt.getX();

  29.mouseY = evt.getY();

  30.repaint();

  31.}

  32.

  33.// We are not using the other mouse events

  34.public void mouseClicked (MouseEvent e) {}

  35.public void mouseEntered (MouseEvent e) {}

  36.public void mouseExited (MouseEvent e) {}

  37.public void mouseReleased (MouseEvent e) {}

  38.

  39.}

  7.11·读取参数

  在一个HTML文件中,上下文为

  在这个Applet内部,你可用方法getParameter()来读取这些值。

  1.import java.awt.*;

  2.import java.applet.*;

  3.

  4.public class DrawAny extends Applet {

  5.Image im;

  6.

  7.public void init() {

  8.URL url = getDocumentBase();

  9.String imageName = getParameter( " image " );

  10.im = getImage(url, imageName);

  11.}

  12.

  13.public void paint(Graphics g) {

  14.g.drawImage(im, 0, 0, this);

  15.}

  16.}

  -- 读取参数

  方法getParameter()搜索匹配的名称,并将与之相关的值以字符串的形式返回。

  如果这个参数名称在位于标记对中的任何标记中都

  未找到,则getParameter()返回null。一个商业化程序应该很好地处理这种情况。

  参数的类型都是String。如果你需要其他类型的参数,则必须自己做一些转换处

  理;例如,读取应为int类型的参数:

  int speed = Integer.parseInt (getParameter ( " speed " ));

  由于HTML的本性,参数名称对大小写不敏感;但是,使它们全部为大写或小写是

  一种良好的风格。如果参数值的字符串中含有空格,则应把整个字符串放入双引

  号中。值的字符串对大小写敏感;不论是否使用双引号,它们的大小写都保持不变。

  7.12·双重目的代码

  是可以在一个单一的类文件中创建既可用作Java Applet,又可用作Java

  应用程序的Java软件代码。为了理解应用程序的要求,需要做较多的工作,

  但是一旦已经创建,Applet/应用程序代码可作为一个更复杂程序的模板来使用。

  1.// Applet/Application which shows an image of Duke in

  2.// surfing mode

  3.import java.applet.Applet;

  4.import java.awt.*;

  5.import java.awt.event.*;

  6.import java.util.*;

  7.

  8.public class AppletApp extends Applet {

  9.

  10.Date date;

  11.

  12.// An application will require a main()

  13.public static void main (String args[]) {

  14.

  15.// Create a Frame to house the applet

  16.Frame frame = new Frame("Application");

  17.

  18.// Create an instance of the class (applet)

  19.AppletApp app = new AppletApp();

  20.

  21.// Add it to the center of the frame

  22.frame.add(app, BorderLayout.CENTER);

  23.frame.setSize (250, 150);

  24.

  25.// Register the AppletApp class as the

  26.// listener for a Window Destroy event

  27.frame.addWindowListener (new WindowAdapter() {

  28.public void windowClosing (WindowEvent e) {

  29.System.exit(0);

  30.}

  31.} );

  32.

  33.// Call the applet methods

  1.app.init();

  2.app.start();

  3.frame.setVisible(true); // Invokes paint()

  4.}

  5.

  6.public void init() {

  7.date = new Date();

  8.}

  9.

  10.public void paint (Graphics g) {

  11.g.drawString("This Java program started at", 25, 25);

  12.g.drawString(date.toString(), 25, 60);

  13.}

  14.}

  注-应用程序没有浏览器所提供的资源,因此不能使用getImage()

  或getAudioClip()。

  

本文转自

http://iboring.blog.163.com/blog/static/148072752007916261574/