java程序设计--孙鑫java无难事Lesson11《Applet》
1.Applet简介
本节要点:
1.Applet编程,详细讲解Applet的生命周期,子体的设置
2.Applet从网页中获取信息,applet和浏览器的通信
3.Applet更新显示的原理,用Applet来制作动画程序,以及动画程序的优化。
详细内容:
1.Applet编程,详细讲解Applet的生命周期,子体的设置
2.Applet从网页中获取信息,applet和浏览器的通信
3.Applet更新显示的原理,用Applet来制作动画程序,以及动画程序的优化。
详细内容:
(1)Applet是什么
Applet又称为Java小应用程序,是能够嵌入到一个HTML页面中,并且可通过Web浏览器下载和执行的一种Java类 。
Applet不需要main()方法,由Web浏览器中内嵌的Java虚拟机调用执行。
(2)Applet的安全限制
因为applet是从远端服务器上下载并且在本地执行,所以安全性就显得格外重要。
通过限制applet在沙箱(applet的运行环境)中运行,保证了对本地系统而言applet是安全的。
applet在沙箱中运行时:
a.不能运行任何本地可执行程序;
b.除了存放下载的applet的服务器外,applet不能和其它主机进行通信。
c.不能对本地文件系统进行读写。
(3)Applet的生命周期
init():当浏览器加载applet,进行初始化的时候调用该方法。
start():在init()方法之后调用。当用户从其它页面转到包含applet的页面时,该方法也被调用。
stop():在用户离开包含applet的页面时被调用。
destroy():当applet不再被使用,或浏览器退出的时候,该方法被调用。
2.Applet和浏览器的交互
(1)Applet获取网页信息
正如应用程序可以通过命令行参数来获取信息一样,通过使用param标记,applet可以从网页中获取信息。
(2)Applet和浏览器的通信
在浏览器中显示信息 调用AppletContext接口中的showStatus()方法
请求浏览器显示指定的网页 调用AppletContext接口中的showDocument()方法。
简单的Applet测试程序代码如下:
- package imageTest;
- import java.applet.Applet;
- import java.awt.Graphics;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Button;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.ActionEvent;
- import java.net.URL;
- public class TestApplet extends Applet
- {
- String strFont;
- int xOrigin,yOrigin;
- public void init()
- {
- Button btn=new Button("链接");
- //写入状态栏
- getAppletContext().showStatus("java Applet test,a simple demo");
- add(btn);
- //链接新文件
- btn.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- try
- {
- getAppletContext().showDocument(
- new URL(getDocumentBase(),"test.html"),"_blank");
- }
- catch(Exception ex)
- {
- ex.printStackTrace();
- }
- }
- });
- //获取网页字体信息
- strFont=getParameter("font");
- //捕获用户鼠标动作 绘制直线
- addMouseListener(new MouseAdapter()
- {
- public void mousePressed(MouseEvent e)
- {
- xOrigin=e.getX();
- yOrigin=e.getY();
- }
- public void mouseReleased(MouseEvent e)
- {
- Graphics g=getGraphics();
- g.setColor(Color.red);
- g.drawLine(xOrigin,yOrigin,e.getX(),e.getY());
- }
- });
- }
- public void start()
- {
- System.out.println("start");
- }
- public void stop()
- {
- System.out.println("stop");
- }
- public void destroy()
- {
- System.out.println("destroy");
- }
- //绘图操作
- public void paint(Graphics g)
- {
- //Font f=new Font("华文行楷",Font.BOLD,30);//构造字体
- Font f=new Font(strFont,Font.BOLD,30);
- g.setFont(f);
- g.setColor(Color.blue);
- g.drawString("java Applet Test",0,30);
- }
- }
- //AppletTest.html
- /*
- <applet code="imageTest.TestApplet.class" width=600 height=400 >
- <param name="font" value="楷体_GB2312">
- */
package imageTest;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.Button;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.net.URL;
public class TestApplet extends Applet
{
String strFont;
int xOrigin,yOrigin;
public void init()
{
Button btn=new Button("链接");
//写入状态栏
getAppletContext().showStatus("java Applet test,a simple demo");
add(btn);
//链接新文件
btn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
getAppletContext().showDocument(
new URL(getDocumentBase(),"test.html"),"_blank");
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
//获取网页字体信息
strFont=getParameter("font");
//捕获用户鼠标动作 绘制直线
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
xOrigin=e.getX();
yOrigin=e.getY();
}
public void mouseReleased(MouseEvent e)
{
Graphics g=getGraphics();
g.setColor(Color.red);
g.drawLine(xOrigin,yOrigin,e.getX(),e.getY());
}
});
}
public void start()
{
System.out.println("start");
}
public void stop()
{
System.out.println("stop");
}
public void destroy()
{
System.out.println("destroy");
}
//绘图操作
public void paint(Graphics g)
{
//Font f=new Font("华文行楷",Font.BOLD,30);//构造字体
Font f=new Font(strFont,Font.BOLD,30);
g.setFont(f);
g.setColor(Color.blue);
g.drawString("java Applet Test",0,30);
}
}
//AppletTest.html
/*
<applet code="imageTest.TestApplet.class" width=600 height=400 >
<param name="font" value="楷体_GB2312">
*/
运行效果如下图所示:
3.AWT绘图
(1)paint()方法
Applet本质上是图形方式的,我们应该在图形环境中绘制我们的显示内容。
我们可以通过创建一个paint()方法在Applet的panel上绘图。只要Applet的显示需要刷新,paint()方法就会被浏览器环境调用。例如,当Applet的显示尺寸发生变化的时候,或浏览器窗口被最小化或被要求以图标方式显示时,这种调用就会发生。
我们应该编写自己的paint()方法,以使它在任何时候被调用,都能正常地工作。对它的调用是异步产生的,且由Applet的运行环境而不是程序来驱动 。
paint()方法带有一个参数,它是java.awt.Graphics类的一个实例。这个参数总是建立该Applet的panel的图形上下文,我们可以用这个图形上下文在Applet中绘图或写入文本。
(2)AWT绘图更新及方法
更新显示由一种被称为AWT线程的独立的线程来完成。这个线程可用来处理与显示更新相关的两种情况。
第一种情况是显露(exposure),它在首次显示时,或在部分显示已被破坏而必须刷新时出现。显示的破坏可能发生在任何时刻,因此,我们的程序必须能在任意时刻更新显示。
第二种情况是在程序重画带有新内容的画面时。这种重画可能会要求首先擦除原来的图像。
AWT更新方法:
paint(Graphics g)方法 当组件第一次显示,或受损的部分需要修复时被调用。除非必要,更新不会完全覆盖整个图形区域,而是严格限制在被破坏的范围内。
repaint()方法 对repaint()的调用可通知系统:你想改变显示,于是系统将调用paint()。
update(Graphics g)方法 repaint()实际上产生了一个调用另一方法update()的AWT线程。update方法通常清除当前的显示并调用paint()。update()方法可以被修改,例如:为了减少闪烁可不清除显示而直接调用paint()。
Applet简单图片显示程序代码如下:
- package imageTest ;
- import java.applet.Applet;
- import java.awt.Graphics;
- import java.awt.Image;
- //简单的图片显示
- public class ShowImage extends Applet
- {
- private Image[] imgs;
- private int totalImage=10;
- private int currentImage=0;
- public void init()
- {
- imgs=new Image[totalImage];//别忘了分配内存
- //构造图片数组 但此时图片并未加载
- for(int i=0;i<totalImage;++i)
- imgs[i]=getImage(getDocumentBase(),"T"+(i+1)+".gif");
- }
- public void start()
- {
- currentImage=0;
- }
- public void paint(Graphics g)
- {
- g.drawImage(imgs[currentImage],0,0,this);//显示图片到Applet面板
- currentImage=(++currentImage)%totalImage;
- try
- {
- Thread.sleep(500);//暂停
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- repaint();//再次更新后显示下一张图片
- }
- /*
- //ShowImage不可以采用以下方式
- public void update(Graphics g)
- {
- paint(g);
- }
- */
- private static final long serialVersionUID = 1L;
- }
package imageTest ;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
//简单的图片显示
public class ShowImage extends Applet
{
private Image[] imgs;
private int totalImage=10;
private int currentImage=0;
public void init()
{
imgs=new Image[totalImage];//别忘了分配内存
//构造图片数组 但此时图片并未加载
for(int i=0;i<totalImage;++i)
imgs[i]=getImage(getDocumentBase(),"T"+(i+1)+".gif");
}
public void start()
{
currentImage=0;
}
public void paint(Graphics g)
{
g.drawImage(imgs[currentImage],0,0,this);//显示图片到Applet面板
currentImage=(++currentImage)%totalImage;
try
{
Thread.sleep(500);//暂停
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();//再次更新后显示下一张图片
}
/*
//ShowImage不可以采用以下方式
public void update(Graphics g)
{
paint(g);
}
*/
private static final long serialVersionUID = 1L;
}
Applet双缓冲图片显示程序代码如下:
- package imageTest;
- import java.applet.Applet;
- import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.MediaTracker;
- //双缓冲显示图片 减轻图片显示时闪烁
- public class DoubleBufferImage extends Applet
- {
- private Image[] imgs;
- private int totalImage=10;
- private int currentImage=0;
- private Image imgBuf;
- private Graphics gbuf;
- private MediaTracker mt;//跟踪媒体状态
- public void init()
- {
- mt=new MediaTracker(this);
- //屏幕外作图
- imgBuf=createImage(600,400);
- gbuf=imgBuf.getGraphics();
- gbuf.setColor(Color.white);
- gbuf.fillRect(0,0,600,400);
- imgs=new Image[totalImage];//别忘了分配内存
- for(int i=0;i<totalImage;++i)
- {
- imgs[i]=getImage(getDocumentBase(),"T"+(i+1)+".gif");
- mt.addImage(imgs[i], i);
- }
- try
- {
- mt.waitForID(0);//等待图片载入
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public void start()
- {
- currentImage=0;
- gbuf.drawImage(imgs[currentImage],0,0,this);
- currentImage=1;
- }
- public void paint(Graphics g)
- {
- //当前上下文作图
- g.drawImage(imgBuf,0,0,this);
- //屏幕外绘图
- gbuf.fillRect(0,0,600,400);
- //检查图片载入,若为载入则等待载入
- if(mt.checkID(currentImage, true))
- {
- gbuf.drawImage(imgs[currentImage],0,0,this);
- currentImage=(++currentImage)%totalImage;
- }
- try
- {
- Thread.sleep(500);//暂停
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- repaint();
- }
- //因为绘图已在内存中完成,可以采用此方式
- public void update(Graphics g)
- {
- paint(g);
- }
- private static final long serialVersionUID = 1L;
- }
package imageTest;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
//双缓冲显示图片 减轻图片显示时闪烁
public class DoubleBufferImage extends Applet
{
private Image[] imgs;
private int totalImage=10;
private int currentImage=0;
private Image imgBuf;
private Graphics gbuf;
private MediaTracker mt;//跟踪媒体状态
public void init()
{
mt=new MediaTracker(this);
//屏幕外作图
imgBuf=createImage(600,400);
gbuf=imgBuf.getGraphics();
gbuf.setColor(Color.white);
gbuf.fillRect(0,0,600,400);
imgs=new Image[totalImage];//别忘了分配内存
for(int i=0;i<totalImage;++i)
{
imgs[i]=getImage(getDocumentBase(),"T"+(i+1)+".gif");
mt.addImage(imgs[i], i);
}
try
{
mt.waitForID(0);//等待图片载入
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start()
{
currentImage=0;
gbuf.drawImage(imgs[currentImage],0,0,this);
currentImage=1;
}
public void paint(Graphics g)
{
//当前上下文作图
g.drawImage(imgBuf,0,0,this);
//屏幕外绘图
gbuf.fillRect(0,0,600,400);
//检查图片载入,若为载入则等待载入
if(mt.checkID(currentImage, true))
{
gbuf.drawImage(imgs[currentImage],0,0,this);
currentImage=(++currentImage)%totalImage;
}
try
{
Thread.sleep(500);//暂停
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
//因为绘图已在内存中完成,可以采用此方式
public void update(Graphics g)
{
paint(g);
}
private static final long serialVersionUID = 1L;
}
Applet多线程图片显示程序代码如下:
- package imageTest;
- import java.applet.Applet;
- import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.MediaTracker;
- //多线程 双缓冲显示图片
- public class MultiThreadImage extends Applet implements Runnable
- {
- private static final long serialVersionUID = 1L;
- private boolean bstop=false;
- private Image[] imgs;
- private int totalImage=10;
- private int currentImage=0;
- private Image imgBuf;
- private Graphics gbuf;
- private MediaTracker mt;
- public void init()
- {
- mt=new MediaTracker(this);//跟踪媒体状态
- //屏幕外作图
- imgBuf=createImage(600,400);
- gbuf=imgBuf.getGraphics();
- gbuf.setColor(Color.white);
- gbuf.fillRect(0,0,600,400);
- imgs=new Image[totalImage];//别忘了分配内存
- for(int i=0;i<totalImage;++i)
- {
- imgs[i]=getImage(getDocumentBase(),"T"+(i+1)+".gif");
- mt.addImage(imgs[i], i);
- }
- try
- {
- mt.waitForID(0);
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public void start()
- {
- currentImage=0;
- gbuf.drawImage(imgs[currentImage],0,0,this);
- new Thread(this).start();//启动线程
- currentImage=1;
- }
- public void paint(Graphics g)
- {
- //当前上下文作图
- g.drawImage(imgBuf,0,0,this);
- }
- //因为绘图已在内存中完成,可以采用此方式
- public void update(Graphics g)
- {
- paint(g);
- }
- //实现接口方法
- public void run()
- {
- //注意线程退出的处理技巧
- while(!bstop)
- {
- //屏幕外绘图
- gbuf.fillRect(0,0,600,400);
- if(mt.checkID(currentImage, true))
- {
- gbuf.drawImage(imgs[currentImage],0,0,this);
- currentImage=(++currentImage)%totalImage;
- }
- try
- {
- Thread.sleep(500);//暂停
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- repaint();
- }
- }
- //停止线程
- public void stop()
- {
- bstop=true;
- }
- }
package imageTest;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
//多线程 双缓冲显示图片
public class MultiThreadImage extends Applet implements Runnable
{
private static final long serialVersionUID = 1L;
private boolean bstop=false;
private Image[] imgs;
private int totalImage=10;
private int currentImage=0;
private Image imgBuf;
private Graphics gbuf;
private MediaTracker mt;
public void init()
{
mt=new MediaTracker(this);//跟踪媒体状态
//屏幕外作图
imgBuf=createImage(600,400);
gbuf=imgBuf.getGraphics();
gbuf.setColor(Color.white);
gbuf.fillRect(0,0,600,400);
imgs=new Image[totalImage];//别忘了分配内存
for(int i=0;i<totalImage;++i)
{
imgs[i]=getImage(getDocumentBase(),"T"+(i+1)+".gif");
mt.addImage(imgs[i], i);
}
try
{
mt.waitForID(0);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start()
{
currentImage=0;
gbuf.drawImage(imgs[currentImage],0,0,this);
new Thread(this).start();//启动线程
currentImage=1;
}
public void paint(Graphics g)
{
//当前上下文作图
g.drawImage(imgBuf,0,0,this);
}
//因为绘图已在内存中完成,可以采用此方式
public void update(Graphics g)
{
paint(g);
}
//实现接口方法
public void run()
{
//注意线程退出的处理技巧
while(!bstop)
{
//屏幕外绘图
gbuf.fillRect(0,0,600,400);
if(mt.checkID(currentImage, true))
{
gbuf.drawImage(imgs[currentImage],0,0,this);
currentImage=(++currentImage)%totalImage;
}
try
{
Thread.sleep(500);//暂停
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
}
//停止线程
public void stop()
{
bstop=true;
}
}
运行效果如下图所示(因为图片放在这里,本身看不出差别,因此仅放上一张图片):
ShowImage中错误调用update方法,造成图片重叠,如下图所示:
用于定位的applet属性:
(1)width和height:必要的属性,以象素为单位,设定applet的宽度和高度。
(2)align:可选的属性,指定applet对齐的方式。
left: 把applet放在网页左边,后面的文本会移至applet的右边。
right: 把applet放在网页右边,后面的文本会移至applet的左边。
bottom: 把applet的底部与当前行文本底部对齐。
top: 把applet的顶部与当前行顶部对齐。
texttop: 把applet的顶部与当前行文本顶部对齐。
middle: 把applet的中部与当前行基线对齐。
absmiddle: 把applet的中部与当前行中部对齐。
baseline: 把applet的底部与当前行基线对齐。
absbottom: 把applet的底部与当前行底部对齐。
(3)vspace和hspace:可选的属性,指定在applet上/下的象素数目(vspace)和applet两边的象素数目(hspace)。
用于编码的applet属性:
(1)code:指定applet类文件的名字。该名字要么是相对于codebase,那么是相对于当前页面。
(2)codebase:可选的属性,告诉浏览器到哪个目录下去寻找类文件。
(3)archive:可选的属性,列出Java存档文件、包含类文件的文件或者applet需要的其它资源。
(4)object:用来指定applet类文件的另外一个方法。
(5)name:可选的属性,页面脚本编写人员希望赋予applet名字属性,这样,在编写脚本的时候,就可以用为该属性指定的名字来代表这个applet。
补充:
(1)Applet程序和资源文件打包方式如下方式:
F:\java\JavaLesson\Lesson11>jar -cvf imageTest.jar imageTest T*.gif *.html
(2)Audio测试程序代码如下:
- package AudioTest;
- import java.applet.Applet;
- import java.applet.AudioClip;
- public class PlaySound extends Applet
- {
- private static final long serialVersionUID = 1L;
- private AudioClip ac;
- public void init()
- {
- //play(getDocumentBase(), "1.au");
- //连续播放
- ac=getAudioClip(getDocumentBase(), "1.au");
- ac.loop();
- }
- public void stop()
- {
- ac.stop();
- }
- }