使用MediaTracker加载及显示图像
如果我们采用采用异步的方式加载显示图像,即程序在后台完成图像的加载和显示,而主进程继续执行,那么可能在图像还未被完全加载完毕时造成不完整的显示。在某些情况下,我们需要在图像完全加载完毕后再进行显示,那么就需要了解另外一种加载图像的方法:调用媒体跟踪器(MediaTracker)来加载图像。
媒体跟踪器是MediaTracker类型的对象,专门用来跟踪图像的加载。这个类在java.awt包中定义,媒体对象可以包括音频剪辑和图像,但目前仅支持图像的管理。MediaTracker只有一个构造器,需要一个组件引用的参数,这个组件对象就是装入图像的组件:
public MediaTracker(Component comp) // 创建媒体跟踪器以跟踪给定组件的图像
常用方法:
// 把Image类的对象image添加到当前媒体跟踪器要追踪的图像列表中,整型对象id表示该image的标识
// 我们所给的id是给每个图像一个标识,实际上是用一组ID来把不同的图像组成一个图像组
public void addImage(Image image, int id)
// 开始加载由此媒体跟踪器跟踪的所有图像。在完成加载正在跟踪的全部图像之前,此方法一直等待
public void waitForAll()
// 在完成加载正在跟踪的所有图像之前,或在 ms 参数(以毫秒为单位)指定的时间到期之前,此方法将一直等待
public boolean waitForAll(long ms)
// 检查所有被跟踪的Image对象是否加载完毕,如果已经加载完毕,则返回true
public boolean checkAll()
// 检查此媒体跟踪器正在跟踪的所有图像是否都已完成加载。
// 如果此 load 标志的值为 true,则此方法将开始加载任何尚未加载的图像
public boolean checkAll(boolean load)
// 检查指定的标识为id的Image对象是否加载完毕,如果已经加载完毕,则返回true
public boolean checkID(int id)
// 检查由此媒体跟踪器跟踪且使用指定标识符标记的所有图像是否已完成加载。
// 如果此 load 标志的值为 true,则此方法将开始加载任何尚未加载的图像
public boolean checkID(int id, boolean load)
// 检查所有被跟踪的Image对象的错误状况,有错误返回true,没有错误则返回false
public boolean isErrorAny()
// 检查指定的标识为id的Image对象在加载过程中是否发生错误,有错误返回true
public boolean isErrorID(int id)
// 计算并返回此媒体跟踪器跟踪的所有媒体状态的按位或,load 如果为 true,则开始加载任何尚未加载的图像
public int statusAll(boolean load)
在使用图像之前可以用checkID()来查看图像是否已经准备好,我们可以调用waitForID()来强制加载图像。注意:addImage()方法并不加载图像,checkID(ID),checkAll()也都不加载图像,只是查看图像的状态。当调用checkID(ID,true),checkAll(true)的时候,如果返回false,会加载未完成加载的图像,还会加载图像的方法是waitForID()和wairForAll()方法。调用这四个方法的时候,开始加载图像,调用线程将被阻塞等待图像的加载,如果不希望程序阻塞,我们一般可以在独立线程内部调用这些方法。
演示MediaTracker的作用
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JFrame;
/**
* 演示MediaTracker的作用
*
* @author 小明
*
*/
public class MediaTrackerTest extends JFrame implements Runnable {
private static final long serialVersionUID = -8673989501696637724L;
// MediaTracker对象
private MediaTracker mediaTracker;
// 添加到MediaTracker的图像对象个数
private int tracked = 0;
// 图片显示速率
private int speed = 5;
// 当前显示的图片索引
private int currentImgIndex = 0;
// 最大图片显示数量常量值
private static final int MAX_IMAGES = 8;
// 存放图片的数组
private Image[] imgs = new Image[MAX_IMAGES];
public MediaTrackerTest() {
setSize(1000, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
// 创建MediaTracker对象
mediaTracker = new MediaTracker(this);
// 图片名称数组
String[] pics = "Freedom1 Freedom2 Freedom3 Freedom4 Freedom5 Freedom6 Freedom7 Freedom8"
.split("\\s+");
// 循环添加图片到媒体追踪器列表中
for (int i = 0; i < pics.length && tracked < MAX_IMAGES; i++) {
String pic = pics[i];
imgs[tracked] = Toolkit.getDefaultToolkit().getImage(
"images/" + pic + ".gif");
// 第二个参数是控制取图优先次序的一个整数id。载入图像时,小id具有较高优先。
// 这个id可以被用来询问mediaTracker关于注册图像的状态
mediaTracker.addImage(imgs[tracked], tracked);
// 图像个数增加
tracked++;
}
// 显示窗体
setVisible(true);
}
@Override
public void paint(Graphics g) {
// 已加载图像数量
int doneCount = 0;
for (int i = 0; i < tracked; i++) {
// 检查由此媒体跟踪器跟踪且使用指定标识符标记的所有图像是否已完成加载。
// load 标志的值为 true,则开始加载任何尚未加载的图像
if (mediaTracker.checkID(i, true)) {
doneCount++; // 加载完成,数量自增
}
}
// 获取窗体大小
Dimension d = getSize();
int width = d.width;
int height = d.height;
if (doneCount == tracked) { // 所有图像加载完毕
Image img = imgs[currentImgIndex++]; // 获取当前待显示图像
// 获取图像大小
int imgWidth = img.getWidth(null);
int imgHeight = img.getHeight(null);
// 绘制图像,在窗体中央绘制
g.drawImage(img, (width - imgWidth) / 2, (height - imgHeight) / 2,
null);
// 若下一个待显示图像超出所有已知图像范围,则下一个显示第一张图像
if (currentImgIndex >= tracked)
currentImgIndex = 0;
}
}
@Override
public void run() {
while (true) {
repaint(); // 重绘
try {
// 休眠,休眠时间根据图像显示速度计算
Thread.sleep(1000 / speed);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
// 启动测试线程
new Thread(new MediaTrackerTest()).start();
}
}
测试图像可自己更改为系统中已有图片。