Double-buffering

Also more info here and the newest info on Sun tutorial (but here it is using Swing which automatically does double buffering)

Displaying graphics with standard techniques often result in chunks of the image appearing on screen in spurts. However, graphical applications in Java can allow your program to draw an image in the background, then smoothly display it in total on screen.

This process, known as double-buffering, has two distinct advantages over the ordinary process of drawing directly to the screen:

To understand double-buffering, you first need to understand graphics contexts. A graphics context is simply a data structure the system knows how to use as a drawing board. You already have seen and used a graphics context in the paint() method declaration.

public void paint (Graphics g) {

Graphics object g is in our graphics context. We use g to do all the drawing in our applet space:

Java then translates what we draw in g into images on the screen. To perform double-buffering, we need to create a graphics context that is not immediately displayed on the screen.

Creating a graphics context involves two basic steps:

  1. Creating a blank image that has the correct dimensions

  2. Deriving a Graphics object from that image

The Graphics object we build in step 2 serves as our graphics context.

We now use myGC to execute any necessary drawing. Images will be rendered in doublebuffer. When we are ready, we can display our doublebuffer to the screen. g.drawImage(doubleBuffer, 0, 0, this);

It's not necessary that the update() method call the paint() method. All that's necessary is that the update() method somehow draw its offscreen buffer to the screen, and that the paint() method be able to draw the proper image when it's called directly by the AWT.

I have seen update call paint and paint call update. Here is paint calling update. Here is the API saying update can call paint

You might wonder why the offscreen image and graphics context are created in the update() method, instead of in (for example) the start() method. The reason is that the image and graphics context depend on the size of the applet Panel's drawing area, and the size of any Component's drawing area is not valid until the Component is just about to be drawn to the screen for the first time.

Once we define the graphics context, we can use it anywhere throughout our program. For example, we could spread our drawing responsibilities across several methods:

Canvas
Could define a class MyCanvas extends Canvas which has IV's of buffer and graphicContexts which are passed in ...then define a paint method in it like this one

(where doubleBuffer is an image, 0's are ints and this is an imageObserver)

If you tried to use a canvas and double-buffering and got a null pointer exception

Create the buffer in an update() method rather than the init or constructor. See Eliminating Flashing

and also Working with Graphics