AWT中图像的异步加载和等待图像的完全加载

AWT中图像的异步加载和等待图像的完全加载

图像的异步加载

图像的加载和显示是异步进行的,图像 的生产者(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;

public   class  ImageTestAppletSimple2
    
extends  Applet {
  
private  Image im;

  
public   void  init() {
    im 
=  getImage(getCodeBase(),  " lena.jpg " );
  }

  
public   void  paint(Graphics g) {
    System.out.println(
" drawing image " );
    System.out.println(g.drawImage(im, 
0 0 this ));
  }
}

当这个 Applet 第一次被调用时,将打印出下面的结果:
drawing image...
false
drawing image...
false
drawing image...
false
drawing 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;

public   class  ImageTestAppletWithUpdate
    
extends  Applet {
  
private  Image im;

  
public   void  init() {
    im 
=  getImage(getCodeBase(),  " lena.jpg " );
  }

  
public   void  paint(Graphics g) {
    g.drawImage(im, 
0 0 this );
  }

  
public   boolean  imageUpdate(Image image,  int  flags,  int  x,  int  y,  int  w,  int  h) {
    System.out.println(
" imageUpdate():x= "   +  x  +   " ,y= "   +  y  +   " ,w= "   +  w  +   " ,h= "   +
                       h);

    
if  ( (flags  &  ALLBITS)  ==   0 ) {
      
return   true //  need more updates
    }
    
else  {
      repaint();
      
return   false //  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;

public   class  ImageTestAppletWithMediaTracker
    
extends  Applet {
  
private  Image im;

  
public   void  init() {
    im 
=  getImage(getCodeBase(),  " lena.jpg " );

    MediaTracker tracker 
=   new  MediaTracker( 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 ));
  }

  
public   void  paint(Graphics g) {
    g.drawImage(im, 
0 0 this );
  }
}

我们可以把使用 java.awt.MediaTracker 类将图像完全加载的方法包装成一个实用方法

/**   *//**
   * 使用 java.awt.MediaTracker 将图像完全加载。
   * 
@param  component Component
   * 
@param  img Image
   
*/
  
public   static   void  waitForImage(Component component, Image img) {
    MediaTracker tracker 
=   new  MediaTracker(component);
    
try  {
      tracker.addImage(img, 
0 );
      tracker.waitForID(
0 );
    }
    
catch  (InterruptedException ex) {
      ex.printStackTrace();
    }
  }

你可能感兴趣的:(AWT中图像的异步加载和等待图像的完全加载)