图像的异步加载
图像的加载和显示是异步进行的,图像的生产者(ImageProducer)传递给图像的消费者(ImageConsumer)一个与图像相关的位,因为图像的生产过程是一个异步行为,所以 AWT 也提供一个图像观察(ImageObserver),用来监视图像生产者的图像生产过程。
因为 java.awt.Component 实现 ImageObserver 接口,所以 AWT 中每个构件都是ImageObserver ,当一个给定的 ImageProducer 采取异步操作时,这个 ImageObserver 可以选择是否被更新。
现在看一个例子:
import java.net.URL;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
publicclassImageTestAppletSimple2
extends Applet
{
privateImage im;
publicvoidinit()
{
im=getImage(getCodeBase(),"lena.jpg");
}
publicvoidpaint(Graphics g)
{
System.out.println("drawing image
");
System.out.println(g.drawImage(im,0,0,this));
}
}
当这个 Applet 第一次被调用时,将打印出下面的结果:
drawing image...falsedrawing image...falsedrawing image...falsedrawing image...true执行结果说明 drawImage() 在第一次被调用时,没有图像被加载,drawImage() 只是向和图像相关的 ImageProducer 注册 ImageObserver,图像被完全加载前 drawImage() 方法返回 false 直到图像被完全加载返回 true。
当 drawImage() 返回之后,只要有图像的新的部分被加载,ImageObserver 中的 imageUpdate() 方法就会被调用。当 ImageObserver 是 AWT 构件时,Component.imageUpdate() 调用 repaint() 方法清除构件背景并调用 paint() 方法重绘刚刚得到的图像位。重复循环,ImageProducer 加载图像的下一块,调用 ImageObserver 的 imageUpdate()。当图像被完全加载时,ImageProducer 停止调用 ImageObserver 的 imageUpdate(),循环中断。
load -> imageUpdate() -> repaint() -> update() -> paint()
等待图像的完全加载上面的例子介绍了图像的异步加载,现在介绍2个方法使图像完全加载前不显示。
·重载 ImageObserver 中的 imageUpdate() 方法,使其在图像完全加载前不调用 repaint()。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
publicclassImageTestAppletWithUpdate
extends Applet
{
privateImage im;
publicvoidinit()
{
im=getImage(getCodeBase(),"lena.jpg");
}
publicvoidpaint(Graphics g)
{
g.drawImage(im,0,0,this);
}
publicboolean imageUpdate(Image image,intflags,intx,inty,intw,inth)
{
System.out.println("imageUpdate():x="+x+",y="+y+",w="+w+",h="+
h);
if( (flags&ALLBITS)==0)
{
returntrue;//need more updates
}
else
{
repaint();
returnfalse;//image is fully loaded
}
}
}
·使用 java.awt.MediaTracker 类跟踪图像的加载,不必重载 imageUpdate() 方法。
import java.net.URL;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
publicclassImageTestAppletWithMediaTracker
extends Applet
{
privateImage im;
publicvoidinit()
{
im=getImage(getCodeBase(),"lena.jpg");
MediaTracker tracker=newMediaTracker(this);
tracker.addImage(im,0);
try
{
tracker.waitForID(0);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.print("Image width ="+im.getWidth(this));
System.out.println("height ="+im.getHeight(this));
}
publicvoidpaint(Graphics g)
{
g.drawImage(im,0,0,this);
}
}
我们可以把使用 java.awt.MediaTracker 类将图像完全加载的方法包装成一个实用方法
/** *//**
* 使用 java.awt.MediaTracker 将图像完全加载。
*@paramcomponent Component
*@paramimg Image
*/
publicstaticvoidwaitForImage(Component component, Image img)
{
MediaTracker tracker=newMediaTracker(component);
try
{
tracker.addImage(img,0);
tracker.waitForID(0);
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
posted on 2005-07-11 13:47 leon 阅读(444) 评论(0) 编辑 收藏 所属分类: JFC