Java Applet
v· 1.JavaApplet概述
JavaApplet程序分为两类:Java小程序(Applet)和Java应用程序(Application),这两类程序是有区别的。JavaApplet嵌入在WWW的页面,作为页面的组成部分被下载,并能运行在实现Java虚机器(JVM)的Web浏览器中。Java的安全机制可以防止小程序存取本地文件或其他安全方面的问题。而一个Java应用程序运行于Web浏览器之外,没有Applet运行时的诸多限制。另外,两者程序设计上的最大区别在于:JavaApplet没有主程序,而Java应用程序一定要有主程序。在Java中每个applet都是由Applet的子类来实现。开发人员自定义的applet通过重载Applet的几个主要成员函数完成小应用程序的初始化、绘制和运行。这些函数是init()、paint()、start()、stop()和destory()。
一个applet的生命周期与Web页面有关。当首次加载含applet的页面时,浏览器调用init()方法,完成applet的初始化。然后调用paint()或start()方法绘制或启动程序。当用户离开页面时,浏览器调用stop()方法停止小程序运行。若用户关闭浏览器将使applet停止运行,浏览器调用destory()方法终止,使小应用程序有机会释放其存在期间锁定的资源。只要用户不关闭浏览器,重新加载页面,浏览器则只调用start()方法和paint()方法重新绘制并运行小程序。Applet生命周期如图1所示。
· 2.扩展小程序基类支持多线程
通常情况下,设计小程序是为了给主页增加交互性,使页面更加生动活泼。因此,那些真正有用小程序,如动画、实时更新Internet服务器信息回取、一般娱乐等通常都是持续运行的,即小程序的逻辑主体存在着无限循环。这个逻辑主体不宜放在几个浏览器调用方法中,如init()、paint()、
start()等。这是因为隐含情况下,小程序所有主逻辑都采用单一线程。当浏览器调用方法中出现死循环,则程序控制不返回。如果用户换到另一个页面之后小程序还在运行,就会浪费处理器资源。你可以做一个实验,使用小程序查阅器运行小程序,你会发现查阅器本身完全停止作用,因为它要等到调用函数返回后,才能继续处理其他事情(如响应菜单)。显然,这个逻辑主体必须放在其他地方。解决方法是在小程序框架中加入线程,把逻辑主体放在线程run()方法中。只在浏览器调用方法start()中生成线程,而在
stop()中终止线程运行,这样当用户不查阅时不会占用处理器资源。图2表示浏览器、小程序和线程之间的关系。
由于浏览器/小程序/线程是所有浏览器都采用的模型,而Java.applet.Applet类本身并不支持线程。在实际使用中,为方便操作,我们可以派生Applet类生成一个支持线程的子类,今后再编写applet时,就可以直接从子类中派生,程序逻辑主体放在run()方法中,将线程控制隐藏起来。这个子类如下:
import Java.applet.*;
import Java.awt.*;
class MultiThreadApplet extends Applet implements Runnable {
Thread thisThread;
Public void start( ) { if(thisThread==null) {
thisThread=new Thread(this);
thisThread.start( );{
}
public void stop( ) {
if (thisThread! =null) {
thisThread.stop( );
thisThread=null;}
}
public void run ( ) {}}
由于run()是接口Runnable的抽象方法,所以在MultiThreadApplet类中也需要进行定义,只不过内容为空。下面的例子显示如何使用这个类。程序包含一个无限循环累加操作,并将结果显示在屏幕上:
import java.awt.*;
public class counter extends MultiThreadApplet{
int Counter;
public void run( ){
while(ue){
counter ;
repaint( );}
}
public void paint(Graphics g) {
g.drawSing(sing.valueof(counter),10,10);{
}
很显然,这个小程序对线程的操作已被隐藏在MultiThreadApplet中。
=========================
6.3.1 Applet 介绍
Applet就是使用Java语言编写的一段代码,它可以在浏览器环境中运行。它与Application的区别主要在于其执行方式的不同。application 是从其中的main() 方法开始运行的,而Applet 是在浏览器中运行的,必须创建一个HTML 文件,通过编写HTML语言代码告诉浏览器载入何种Applet 以及如何运行。
1. Applet 举例
例6.7 HelloWorld.java 源程序:
import java.awt.Graphics; //引入图形类Graphics
import java.applet.Applet; //引入Applet类
public class HelloWorld extends Applet {
String hw_text ;
public void init () { //init()方法是Applet首先执行的方法
hw_text = "Hello World";
}
public void paint(Graphics g) {
g.drawString (hw_text , 25, 25) ;
//在坐标为(25,25)的地方显示字符串hw_text
}
}
Applet程序编写完后,首先要用java编译器编译成为字节码文件,然后编写相应的HTML文件才能够正常执行,例如为运行上面的Applet程序所编写的HTML文件HelloWorld.html如下:
<HTML>
<APPLET CODE="HelloWorld.class" WIDTH=200 HEIGHT=100
</APPLET>
</HTML>
2.Applet的 安全性
"沙箱"机制:Java虚拟机为Applet提供能够良好运行的沙箱,一旦它们试图离开沙箱则会被禁止。
由于小应用程序是通过网络传递的,这就不可避免地使人想到会发生安全问题。例如有人编写恶意程序通过小应用程序读取用户密码并散播到网络上,这将会是一件非常可怕的事情。所以,必须对小应用程序进行限制。
浏览器禁止Applet执行下列操作:
(1)在运行时调用其它程序。
(2)文件读写操作。
(3)装载动态连接库和调用任何本地方法。
(4)试图打开一个socket进行网络通信,但是所连接的主机并不是提供Applet的主机。
◇ Applet的类层次:
◇ Applet的生命周期
小应用程序的生命周期相对于Application而言较为复杂。在其生命周期中涉及到Applet类的四个方法(也被JApplet类继承):init()、start()、stop()和destroy()。下面首先用图来表示一个小应用程序的生命周期,然后再简要描述这四个方法。
Applet的生命周期中有四个状态:初始态、运行态、停止态和消亡态。当程序执行完init()方法以后,Applet程序就进入了初始态;然后马上执行start()方法,Applet程序进入运行态;当Applet程序所在的浏览器图标化或者是转入其它页面时,该Applet程序马上执行stop()方法,Applet程序进入停止态;在停止态中,如果浏览器又重新装载该Applet程序所在的页面,或者是浏览器从图标中复原,则Applet程序马上调用start()方法,进入运行态;当然,在停止态时,如果浏览器关闭,则Applet程序调用destroy()方法,进入消亡态。
◇ Applet的主要方法:
1. init( )
创建Applet时执行,只执行一次
当小应用程序第一次被支持Java的浏览器加载时,便执行该方法。在小应用程序的生命周期中,只执行一次该方法,因此可以在其中进行一些只执行一次的初始化操作,如处理由浏览器传递进来的参数、添加用户接口组件、加载图像和声音文件等。
小应用程序有默认的构造方法,但它习惯于在init()方法中执行所有的初始化,而不是在默认的构造方法内。
2.start( )
多次执行,当浏览器从图标恢复成窗口,或者是返回该主页时执行。
系统在调用完init()方法之后,将自动调用start()方法。而且每当浏览器从图标恢复为窗口时,或者用户离开包含该小应用程序的主页后又再返回时,系统都会再执行一遍start()方法。start()方法在小应用程序的生命周期中被调用多次,以启动小应用程序的执行,这一点与init()方法不同。该方法是小应用程序的主体,在其中可以执行一些需要重复执行的任务或者重新激活一个线程,例如开始动画或播放声音等。
3.stop( )
多次执行,当浏览器变成图标时,或者是离开主页时执行,主要功能是停止一些耗用系统资源的工作,。
与start()相反,当用户离开小应用程序所在页面或浏览器变成图标时,会自动调用stop()方法。因此,该方法在生命周期中也被多次调用。这样使得可以在用户并不注意小应用程序的时候,停止一些耗用系统资源的工作(如中断一个线程),以免影响系统的运行速度,且并不需要去人为地去调用该方法。如果你的小应用程序中不包含动画、声音等程序,通常也不必重载该方法。
4.destroy( )
用来释放资源,在stop( )之后执行
浏览器正常关闭时,Java自动调用这个方法。destroy()方法用于回收任何一个与系统无关的内存资源。当然,如果这个小应用程序仍然处于活动状态,Java会在调用destroy()之前,调用stop()方法。
下面的例子使用了小应用程序生命周期中的这几个方法。
例6.8
import java.awt.Graphics;
import java.applet.Applet;
public class HWloop extends Applet {
AudioClip sound; //声音片断对象
public void init( ){
sound=getAudioClip("audio/hello.au"); //获得声音片断
}
public void paint(Graphics g) {
g.drawString("hello Audio",25,25); //显示字符串
}
public void start( )
{
sound.loop( ); //声音片断开始播放
}
public void stop( )
{
sound.stop( ); //声音片断停止
}
}
在本例子中,Applet开始执行后就不停的播放声音,如果浏览器图标化或者是转到其它页面,则声音停止播放;如果浏览器恢复正常或者是从其它页面跳回,则程序继续播放声音。
由于Applet程序要嵌入到HTML文件中才能够正常执行,下面介绍与Applet程序有关的HTML文件标记。
<applet>
[archive=archiveList] //同一个codebase中需预先下载的文件
code=appletFile.class //applet的名称
width=pixels height=pixels //applet的初始显示空间
[codebase=codebaseURL] //代码的地址
[alt=alternateText] //如果浏览器不支持applet时,显示的替代文本
[name=appletInstanceName]
//给该applet取名,用于同页面applet之间的通信
[align=alignment] //对齐方式,如left,right,top,baseline...
[vspace=pixels] [hspace=pixels] //预留的边缘空白
>
[<param name=appletAttribute1 value=value>]
[<param name=appletAttribute2 value=value>]
…… //参数名称及其值
[alternateHTML]
</applet>
注意:
1)不支持Java的浏览器会把<applet></applet>之间的普通HTML文档显示出来;支持Java的浏览器,则把其中的普通HTML文档忽略。
2)AppletViewer仅支持<applet> </applet>标记,其它标记不会被显示出来。