注意
画笔风格不影响填充、文本和图像的绘制操作。
解决办法是在内存中开辟一片区域作为后台画面,程序对它更新、修改,完成后再显示它。这样被显示的图像永远是 已经完全画好的图像,程序修改的将不是正在被显示的图像。当然还有其他方法可以解决屏幕闪烁问题,但使用双缓冲技术是一种值得推荐的解决方案。
有些设备本身就支持双缓冲,每次都是先把屏幕重画在缓冲之中,然后再绘制在显示屏幕上,而不是直接绘制在显示 屏幕上。可以使用Canvas类的isDoubleBuffer方法判断设备是否具有双缓冲。
可变图像可以很容易地用作屏幕外缓冲。改写前面绘制不变图像的代码,将所有的绘制都放在可变图像中,然后一次 性地将可变图像绘制到屏幕上去。
package doublebufferdemo;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.io.*;
public class ImageCanvas extends Canvas
{
private Image buffer; //可变图像,作为绘制缓冲
private Image image; //不变图像,用来加载图片文件
public ImageCanvas()
{
try
{
image = Image.createImage("/tree.png"); //加载图片文件
}catch(java.io.IOException e)
{
System.out.println(e.getMessage()); //处理I/O异常
}
buffer = Image.createImage(this.getWidth(), this.getHeight());
//用一个可变图像作为绘制缓冲
Graphics bg = buffer.getGraphics(); //获取缓冲的Graphics对象
bg.setColor(0xFFFFFF);
bg.fillRect(0, 0, getWidth(), getHeight()); //填充整个屏幕
bg.drawImage(image,this.getWidth()/2,this.getHeight()/2, Graphics.VCENTER|Graphics.HCENTER);
}
public void paint(Graphics g)
{
g.drawImage(buffer,0,0,g.TOP|g.LEFT); //将缓冲区上的内容绘制到屏幕上
}
}
编译、运行程序,其结果和前面完全相同,但是却采用了双缓冲技术。对于双缓冲的使用,可以总结出以下几点。
n 定义一个Graphics对象bg和一个Image对象buffer,按屏幕大小建立一个缓冲对象赋给buffer,然后取得buffer的 Graphics对象赋给bg。在这里,Graphics对象可以理解为缓冲的屏幕,Image对象则可当成缓冲屏幕上的图片。
n 在bg(缓冲屏幕)上用drawImage()和drawString()等语句画图,相当于在缓冲屏幕上画图。
n 调用repaint()语句,它的功能是告知系统调用paint()来完成真实屏幕的显示。这里需要注意的是,paint()是一个系统调用语句,不能手 工调用,只能通过paint()语句来调用。
n 在paint(Graphics g)函数里,将buffer(缓冲屏幕上的图片)画到真实屏幕上。
以上的步骤虽然看似繁琐,但是效果还是很不错的。如果想在屏幕上显示什么东西,只要画在bg上,然后调用 repaint()将其显示出来就可以了。