Java最初奉献给世人的就是Applet,随即它吸引了全世界的目光,Applet运行于浏览器上,可以生成生动美丽的页面,进行友好的人机交互,同时还能处理图像、声音、动画等多媒体数据。Applet在Java的成长过程中起到不可估量的作用,到今天Applet依然是Java程序设计最吸引的人之一。在本期专题中我将向读者介绍Applet编程的一些技巧。
Java Applet 是用Java 语言编写的一些小应用程序,这些程序是直接嵌入到页面中,由支持Java的浏览器(IE 或 Nescape)解释执行能够产生特殊效果的程序。它可以大大提高Web页面的交互能力和动态执行能力。包含Applet的网页被称为Java-powered页,可以称其为Java支持的网页。
当用户访问这样的网页时,Applet被下载到用户的计算机上执行,但前提是用户使用的是支持Java的网络浏览器。由于Applet是在用户的计算机上执行的,所以它的执行速度不受网络带宽或者Modem存取速度的限制,用户可以更好地欣赏网页上Applet产生的多媒体效果。
Applet 小应用程序的实现主要依靠java.applet 包中的Applet类。与一般的应用程序不同,Applet应用程序必须嵌入在HTML页面中,才能得到解释执行;同时Applet可以从Web页面中获得参数,并和Web页面进行交互。
含有Applet的网页的HTML文件代码中必须带有<applet>和</applet>这样一对标记,当支持Java的网络浏览器遇到这对标记时,就将下载相应的小程序代码并在本地计算机上执行该Applet小程序。
Applet是一种Java的小程序,它通过使用该Applet的HTML文件,由支持Java的网页浏览器下载运行。也可以通过java开发工具的appletviewer来运行。Applet 程序离不开使用它的HTML文件。这个HTML文件中关于Applet的信息至少应包含以下三点:
1)字节码文件名(编译后的Java文件,以.class为后缀)
2)字节码文件的地址
3)在网页上显示Applet的方式。
一个HTML文件增加Applet有关的内容只是使网页更加富有生气,如添加声音、动画等这些吸引人的特征,它并不会改变HTML文件中与Applet无关的元素。
显示文字是Java中最基本的功能,使用非常简单的方式来支持文字的显示,只要使用类Graphics中的drawString()函数就能实现。我们来看最简单的ghq例子:
//ghq.java
import java.awt.*;
import java.applet.*;
public class ghq extends Applet
{
String text=ghq is a student!;
public void paint(Graphics g)
{
g.drawString(text,20,20);
} //在坐标20,20 处显示text的内容
}
这是最基本的Java Applet,运行的时候仅显示“ghq is a student!”。Java支持Unicode,因此中文也能在Java中很好地显示出来,我们把“ghq is a student!”改成“你好!欢迎参观!”,同样可以显示(如果无法正确显示,则是浏览器的Bug,如用的IE4.0 就存在这样的问题,请改用Netscape 或IE5.0 以上版本)。值得注意的是,在Java中每个字符用16位来表示,而不是8位,这与C语言是不同的。
[NextPage]
[文章导读]与用户的交互是Java的主要作用,也正是Java吸引人的原因,用户可以通过鼠标和键盘与Java Applet程序对话
与用户的交互是Java的主要作用,也正是Java吸引人的原因,用户可以通过鼠标与Java Applet程序对话。我们先来看响应鼠标的例子:
//Mouse.java
import java.awt.*;
import java.applet.*;
public class Mouse extends Applet
{
String text=;
public void paint(Graphics g)
{
g.drawString(text,20,20);
}
public boolean mouseDown(Event evt,int x,int y)//鼠标按下处理函数
{
text=Mouse Down;
repaint();
return true;
}
public boolean mouseUp(Event evt,int x,int y)//鼠标松开处理函数
{
text=;
repaint();
return true;
}
}
当用户点击程序时,程序将显示Mouse Down,说明程序对鼠标作出了响应。然而要注意Java并不区分鼠标的左右键。
我们再来看对键盘响应的例子:
//Keyboard.java
import java.awt.*;
import java.applet.*;
public class Keyboard extends Applet
{
String text=;
public void paint(Graphics g)
{
g.drawString(text,20,20);}
public boolean keyDown(Event evt,int x)//键盘被按下的处理函数
{
text=Key Down;
repaint();
return true;
}
public boolean keyUp(Event evt,int x)//键盘被松开的处理函数
{
text=;
repaint();
return true;
}
}
}
当键盘被按下时,程序就会显示Key Down,键盘松开时清除文字。利用这些函数,我们就可以用鼠标和键盘函数与用户交互。
[NextPage]
[文章导读] Java Applet常用来显示存储在GIF文件中的图像
Java Applet常用来显示存储在GIF文件中的图像。Java Applet装载GIF图像非常简单,在Applet内使用图像文件时需定义Image对象。多数Java Applet使用的是GIF或JPEG格式的图像文件。Applet使用getImage方法把图像文件和Image对象联系起来。
Graphics类的drawImage方法用来显示Image对象。为了提高图像的显示效果,许多Applet都采用双缓冲技术:首先把图像装入内存,然后再显示在屏幕上。
Applet可通过imageUpdate方法测定一幅图像已经装了多少在内存中。
装载一幅图像
Java把图像也当做Image对象处理,所以装载图像时需首先定义Image对象,格式如下所示:
Image picture;
然后用getImage方法把Image对象和图像文件联系起来:
picture=getImage(getCodeBase(),ImageFileName.GIF);
getImage方法有两个参数。第一个参数是对getCodeBase方法的调用,该方法返回Applet的URL地址,如www.sun.com/Applet。第二个参数指定从URL装入的图像文件名。如果图文件位于Applet之下的某个子目录,文件名中则应包括相应的目录路径。
用getImage方法把图像装入后,Applet便可用Graphics类的drawImage方法显示图像,形式如下所示:
g.drawImage(Picture,x,y,this);
该drayImage方法的参数指明了待显示的图像、图像左上角的x坐标和y坐标以及this。
第四个参数的目的是指定一个实现ImageObServer接口的对象,即定义了imageUpdate方法的对象(该方法随后讨论)。
显示图像(ShowImage.java)
//源程序清单
import java.awt.*;
import java.applet.*;
public class ShowImage extends Applet
Image picure; //定义类型为Image的成员变量
public void init()
{
picture=getImage(getCodeBase(),Image.gif); //装载图像
}
public void paint(Graphics g)
{
g.drawImage(picture,0,0,this); //显示图像
}
}
为此,HTML文件中有关Applet的语句如下:
<HTML>
<TITLE>Show Image Applet</TITLE>
<APPLET
CODE=ShowImage.class //class文件名为ShowImage.class
WIDTH=600
HEIGHT=400>
</APPLET>
</HTML>
编译之后运行该Applet时,图像不是一气呵成的。这是因为程序不是drawImage方法返回之前把图像完整地装入并显示的。与此相反,drawImage方法创建了一个线程,该线程与Applet的原有执行线程并发执行,它一边装入一边显示,从而产生了这种不连续现象。为了提高显示效果。许多Applet都采用图像双缓冲技术,即先把图像完整地装入内存然后再显示在屏幕上,这样可使图像的显示一气呵成。
双缓冲图像
为了提高图像的显示效果应采用双缓冲技术。首先把图像装入内存,然后再显示在Applet窗口中。
使用双缓冲图像技术例子(BackgroundImage.java)
//源程序清单
import java.awt.*;
import java. applet.*;
public class BackgroundImage extends Applet //继承Applet
{
Image picture;
Boolean ImageLoaded=false;
public void init()
{
picture=getImage(getCodeBase(),Image.gif); //装载图像
Image offScreenImage=createImage(size().width,size().height);
//用方法createImage创建Image对象
Graphics offScreenGC=offScreenImage.getGraphics(); //获取Graphics对象
offScreenGC.drawImage(picture,0,0,this); //显示非屏幕图像
}
public void paint(Graphics g)
{
if(ImageLoaded)
{
g.drawImage(picture,0,0,null); //显示图像,第四参数为null,不是this
showStatus(Done);
}
else
showStatus(Loading image);
}
public boolean imageUpdate(Image img,int infoflags,int x,int y,int w,int h)
{
if(infoflags= =ALLBITS)
{
imageLoaded=true;
repaint();
return false;
}
else
reture true;
}
}
分析该Applet的init方法可知,该方法首先定义了一个名为offScreenImage的Image对象并赋予其createImage方法的返回值,然后创建了一个名为offScreenGC的Graphics对象并赋予其图形环境——非屏幕图像将由它来产生。因为这里画的是非屏幕图像,所以Applet窗口不会有图像显示。
每当Applet调用drawImage方法时,drawImage将创建一个调用imageUpdate方法的线程。Applet可以在imageUpdate方法里测定图像已有装入内存多少。drawImage创建的线程不断调用imageUpdate方法,直到该方法返回false为止。
imageUpdate方法的第二个参数infoflags使Applet能够知道图像装入内存的情况。该参数等于ImageLoaded设置为true并调用repaint方法重画Applet窗口。该方法最终返回false,防止drawImage的执行线程再次调用imageUpdate方法。
该Applet在paint方法里的操作是由ImageLoaded变量控制的。当该变量变为true时,paint方法便调用drawImage方法显示出图像。paint方法调用drawImage方法时把null作为第四参数,这样可防止drawImage调用imageUpdate方法。因为这时图像已装入内存,所以图像在Applet窗口的显示可一气呵成。
[NextPage]
[文章导读]使用Applet播放声音时需首先定义AudioClip对象,GetAudioClip方法能把声音赋予AudioClip对象使用Applet播放声音时需首先定义AudioClip对象,GetAudioClip方法能把声音赋予AudioClip对象,如果仅想把声音播放一遍,应调用AudioClip类的play方法,如果想循环把声音剪辑,应选用AudioClip类的loop方法。
(1) 播放声音文件
图像格式各种各样,如BMP、GIF和JPEG等。声音文件也一样,WAV和AU是最常用的两种声音文件。目前Java仅支持AU文件,但Windows环境下常用的却是WAV文件,所以最好能有一个可把WAV文件转换为AU文件的工具。
* 播放声音的AudioClip类
AudioClip类用来在Java Applet内播放声音,该类在java.Applet包中有定义。
下面演示了如何利用AudioClip类播放声音。
装入一个名为Sample.Au的声音文件并播放(SoundDemo.java)
//源程序清单
import java.awt.*;
import java.applet.*
public class SoundDemo extends Applet
{
public void paint(Graphics g)
{
AudioClip audioClip=getAudioClip(getCodeBase(),”Sample.AU”);
//创建AudioClip对象并用//getAudioClip方法将其初始化。
g.drawstring(Sound Demo! ,5,15);
audioClip.loop();//使用AudioClip类的loop方法循环播放
}
}
需把如下的HTML语句放入SoundDemo.HTML文件,为运行该Applet做准备。
<HTML>
<TITLE>SoundDemo Applet</TITLE>
<APPLET CODE=SoundDemo.class WIDTH=300 HEIGHT=200>
</APPLET>
</HTML>
编译并运行该Applet,屏幕上将显示出一个Applet窗口并伴以音乐。关闭Applet时音乐终止。
[NextPage]
[文章导读]在Java中实现动画有很多种办法,但它们实现的基本原理是一样的,即在屏幕上画出一系列的帧来造成运动的感觉
Java 不仅提供了对图形、图像的支持,还允许用户实现连续的图像播放,即动画技术。Java 动画的实现,首先用Java.awt 包中的 Graphics 类的drawImage()方法在屏幕上画出图像,然后通过定义一个线程,让该线程睡眠一段时间,然后再切换成另外一幅图像;如此循环,在屏幕上画出一系列的帧来造成运动的感觉,从而达到显示动画的目的。
为了每秒钟多次更新屏幕,必须创建一个线程来实现动画的循环,这个循环要跟踪当前帧并响应周期性的屏幕更新要求;实现线程的方法有两种,可以创建一个类Thread 的派生类,或附和在一个Runnable 的界面上。
* 动画技巧
在编写动画过程时,遇到最常见的问题是屏幕会出现闪烁现象。闪烁有两个原因:一是绘制每一帧花费的时间太长(因为重绘时要求的计算量大);二是在每次调用Pain()前,Java 会用背景颜色重画整个画面,当在进行下一帧的计算时,用户看到的是背景。
有两种方法可以明显地减弱闪烁:重载 update()或使用双缓冲。
(1) 重载 update()
当AWT接收到一个applet的重绘请求时,它就调用applet的 update(),默认地,update() 清除applet的背景,然后调用 paint()。重载 update(),将以前在paint()中的绘图代码包含在update()中,从而避免每次重绘时将整个区域清除。下面是 update()方法的原始程序代码:
public void update(Graphics g)
{
//首先用背景色来绘制整个画面
g.setColor(getBackGround());
g.fillRect(0,0,width,height);
//接着设置前景色为绘制图像的颜色,然后调用paint()方法
g.setColor(getForeGround());
paint(g);
}
所以要消除画面闪烁就一定要改写 update() 方法,使该方法不会清除整个画面,只是消除必要的部分。
(2) 使用双缓冲技术
另一种减小帧之间闪烁的方法是使用双缓冲,它在许多动画Applet中被使用。其主要原理是创建一个后台图像,将需要绘制的一帧画入图像,然后调用DrawImage()将整个图像一次画到屏幕上去;好处是大部分绘制是离屏的,将离屏图像一次绘至屏幕上比直接在屏幕上绘制要有效得多,大大提高做图的性能。
双缓冲可以使动画平滑,但有一个缺点,要分配一张后台图像,如果图像相当大,这将需要很大一块内存;当你使用双缓冲技术时,应重载 update()。