Java Reference
In-Depth Information
You override the
paint
method to actually perform drawing. The caller passes this
method a single argument: an instance of
Graphics
that you use to actually perform draw-
ing. Your
paint
operation should repaint every pixel within the region defined by the
Graphics
object's clipping, because it may have resulted from multiple
repaint
calls. Note
that the
Graphics
instance is only valid within your
paint
method; you definitely should
not
cache aside the
Graphics
instance you receive to use after exiting the
paint
method.
GRAPHICS OPERATIONS AND DOUBLE BUFFERING
On early Java ME devices, graphics operations to the screen were slow, and applications that did a lot
of painting showed visible artifacts such as flickering or tearing of the image as the platform inter-
leaved drawing operations with screen refreshes. Although a much rarer problem today, this can still be
a challenge, especially if you're implementing a fast-paced game or similarly demanding application.
To avoid visual artifacts from display updates while drawing, you use a technique called
double
buffering
or
ping-pong buffering
, in which you perform all of your drawing operations on an offscreen
bitmap, and then when you're done with all of the drawing operations, you transfer that image to the
display. Newer versions of the MIDP support double buffering; you can query the
Canvas
directly by
invoking
Canvas.isDoubleBuffered
. If this method returns
true
, the MIDP implementation will ren-
der the results of your
paint
operation into an offscreen bitmap and transfer the bitmap at appropriate
times to the display's framebuffer, preventing visual artifacts.
If the platform does not support double buffering, you can implement double buffering yourself.
Instead of drawing with the
Graphics
object that the platform passes to your item's
paint
method,
create an instance of
javax.microedition.lcdui.Image
to buffer all of your drawing operations.
Then, invoke the new image's
getGraphics
method to obtain the
Graphics
object associated with the
image, and do all the drawing with that
Graphics
object. When you're done, render the image directly
to the screen using the
Graphics
object passed to your
paint
method, like this:
void paint(Graphics g) {
int w = getWidth();
int h = getHeight();
Image buffer = Image.createImage(w, h);
Graphics bg = buffer.getGraphics();
bg.drawRect(0, 0, 10, 10);
g.drawImage( buffer, 0, 0 );
}
If you're only doing simple graphics updates or updating a small region of the screen, the memory
overhead imposed by double buffering may be more expensive than it's worth and cause performance
penalties of its own. As a result, you should test your code carefully to determine if double buffering is
actually necessary.