Flicker Free Graphics
2004-11-11 11:12
330 查看
by Eric Giguere
Release 1.0
July 25, 2001
The Mobile Information Device Profile (MIDP) defines low-level user interface classes for drawing directly on a device's display. The Using the MIDP Low-Level User Interface API tip covered how to use these classes to do basic drawing. This tip builds on that foundation and discusses how to use double buffering to draw flicker-free graphics.
The term "double buffering" refers to a common technique used in computer graphics. If you consider a device's display to be a memory buffer into which drawing primitives write (the drawing primitives are the basic drawing methods such as
It's easy to do double buffering in the context of the Mobile Information Device Profile. You can use the
The first thing you need to do is determine if double buffering is even necessary. On some implementations, double buffering is automatically supported by the system. In other words, when the system calls your
Notice how if
The offscreen buffer is created by calling one of the
Loads images from the MIDlet suite's JAR file
Makes a copy of an existing image
Creates an image from raw binary data
Creates a blank image of a specific height and width
The last of these
Of course, the real work occurs in the
Most
Basically all you're doing is obtaining the
Double buffering is not without its price. If you're only making small changes to the display, it might be slower to use double buffering. In addition, image copying isn't very fast on some systems; on those systems flicker can can happen even with double buffering. And there is a memory penalty to pay for double buffering: the offscreen memory buffer can consume a large amount of memory, memory that you might not be able to spare. Keep the number of offscreen buffers to a minimum. You could free the offscreen buffer whenever the
About the Author: Eric Giguere is a software developer for iAnywhere Solutions, a subsidiary of Sybase, where he works on Java technologies for handheld and wireless computing. He holds BMath and MMath degrees in Computer Science from the University of Waterloo and has written extensively on computing topics.
Release 1.0
July 25, 2001
The Mobile Information Device Profile (MIDP) defines low-level user interface classes for drawing directly on a device's display. The Using the MIDP Low-Level User Interface API tip covered how to use these classes to do basic drawing. This tip builds on that foundation and discusses how to use double buffering to draw flicker-free graphics.
The term "double buffering" refers to a common technique used in computer graphics. If you consider a device's display to be a memory buffer into which drawing primitives write (the drawing primitives are the basic drawing methods such as
drawLineand
drawArc), with double buffering you draw into a second, offscreen memory buffer and then copy the entire contents of the second buffer into the display buffer. Copying from one buffer to another is a very fast operation on most devices, so that the display changes almost instantaneously. By comparison, directly drawing to a display sometimes causes users to see a flicker, as individual parts of the display are updated. Double buffering avoids this flickering by combining multiple individual drawing operations (that is, those to the offscreen buffer) into a single copy operation to the display buffer.
It's easy to do double buffering in the context of the Mobile Information Device Profile. You can use the
Imageclass (all classes mentioned in this tip are in the
javax.microedition.lcduipackage) to create an offscreen memory buffer. You use the
Graphicsclass, the same class used to draw on the display, to draw to the offscreen buffer. You also use the
Graphicsclass to copy the contents of the offscreen buffer onto the display. Double buffering is implemented with just a few adjustments to your painting routines.
The first thing you need to do is determine if double buffering is even necessary. On some implementations, double buffering is automatically supported by the system. In other words, when the system calls your
Canvasobject's
paintmethod, the
Graphicsobject passed to the method is that of an offscreen buffer managed by the system; the object is not from the display buffer. The system then takes care of copying the offscreen buffer to the display. Checking if double buffering is supported is easy -- all you do is call the
isDoubleBufferedmethod, like this:
public class MyCanvas extends Canvas { private Image offscreen = null; private int height; private int width; public MyCanvas(){ height = getHeight(); width = getWidth(); if( !isDoubleBuffered() ){ offscreen = Image.createImage( width, height ); } ..... // other initialization as appropriate } ...... // other code, including paint method } |
isDoubleBufferedreturns false, the constructor creates an offscreen buffer of the same width and height as the
canvas. If the display is double buffered,
isDoubleBufferedreturns true and the offscreen buffer is not created.
The offscreen buffer is created by calling one of the
Image.createImagemethods. There are four such methods, each of which does the following:
Loads images from the MIDlet suite's JAR file
Makes a copy of an existing image
Creates an image from raw binary data
Creates a blank image of a specific height and width
The last of these
createImagemethods is the one used for double buffering. The other three
createImagemethods cannot be used for double buffering because they create images that are immutable, that is, images that cannot be changed. Only the last
createImagemethod, the one that takes width and height parameters, can be used to create mutable images. Once you have a mutable image, you can call its
getGraphicsmethod to obtain a
Graphicsobject that you can use to draw into the image's buffer, just like drawing on the display.
Of course, the real work occurs in the
paintmethod. A simple paint routine might look like this:
protected void paint( Graphics g ){ g.setColor( 255, 255, 255 ); g.fillRect( 0, 0, width, height ); } |
paintroutines are much more complicated, especially if animation is involved. To implement double buffering, add a few lines of code before and after the existing painting code, like this:
protected void paint( Graphics g ){ Graphics saved = g; if( offscreen != null ){ g = offscreen.getGraphics(); } g.setColor( 255, 255, 255 ); g.fillRect( 0, 0, width, height ); if( g != saved ){ saved.drawImage( offscreen, 0, 0, Graphics.LEFT | Graphics.TOP ); } } |
Graphicsobject for the offscreen buffer and using it to do the painting. At the end, the entire content of the offscreen buffer is copied to the display. Notice that this is done only if double buffering is not automatically supported. You can easily determine this by checking to see if an offscreen buffer has been allocated. If double buffering is automatically supported, you simply draw directly onto the display as usual.
Double buffering is not without its price. If you're only making small changes to the display, it might be slower to use double buffering. In addition, image copying isn't very fast on some systems; on those systems flicker can can happen even with double buffering. And there is a memory penalty to pay for double buffering: the offscreen memory buffer can consume a large amount of memory, memory that you might not be able to spare. Keep the number of offscreen buffers to a minimum. You could free the offscreen buffer whenever the
canvasis hidden, for example, and allocate it again when the
canvasis shown again. This is easy to do by overriding the
canvas'
hideNotifyand
showNotifymethods.
相关文章推荐
- 蓝色巨人
- 编程实战:Visual C#实现P2P应用程序
- 数据库连接字符串大全
- 第一章 背景
- Assembly 学习心得
- [TreeView]使用总汇聚
- 以人为本--创建最好的开发团队
- 交叉表应用一 (报表动态表头)
- 用IFRAME实现网页的内嵌和预载
- SQL 在查询中插入行号--自定义分页的另外一种实现方式
- 自动建站.实现虚拟二级目录
- F: 关于dropdownlist,postback问题
- 模式的分类
- samba unix风格的配置文件配置信息读取C代码.
- C#下的webservcie 实现代码和 在vc和python下的调用实现(原创)
- C#一个OleDb获取FoxPro关键字的问题。
- 二级联动菜单数据库版
- 观察报告:中国经济700天 宏观调控掀起震荡波[转载]
- 关于.text中AdvancedPanel中展开按钮在页面执行时有时会出错的问题
- 走出黑盒子:CIO需学会在公司里售卖IT