Double-buffering


Prerequisites

To perform smooth screen updates for drawing and animation, a technique called double-buffering is often used. Double-buffering provides a means of performing redraws in a background buffer (thus hiding it from the viewer), which is then in one smooth motion, copied to the visible drawing buffer. This technique is used extensively in the animations for the Thread Magercises.

In this Magercise, we are going to use double-buffering for another, important reason--the background buffer will record the set of elements we have drawn (recall that Java erases the applet drawing region each time it repaints unless you modify the definition of method update). We will combine the previous Rubberbanding Magercise so that rectangles are drawn on the visible screen during rubberbanding, but copied to the background "save" buffer.

How do we rubberband on top of an already-present image without erasing part of it as we drag across? Exclusive OR mode. XOR mode allows you to draw once (perturbing the background very slightly) and draw again, erasing without affecting the background.

An OS/2 C version of this Magercise exists in this directory. Note that the behavior of the C program may not be the same as the Magercise -- it is presented here for comparision against the Java application you will write in this Magercise. One of the major differences is that the C version does not support layout managers, so resizing a window will not resize the contents of that window.

Work Location

Perform all work for this magercise in VisualAge project MageLang Magercises, package magercises.doublebuffer.

If this project does not appear in your Workspace add it from the repository (if it exists there) or create a new project using this name.

Tasks

Perform the following tasks:

  1. Modify class SimpleDrawingRegion. Define a background buffer and graphics context for it as instance variables buffer and bufferGr. In the constructor, create an image according to the width and height passed in and then obtain the graphics context. See Image and Graphics.

  2. Define update so that it simply calls paint. Normally it clears the graphics region before calling paint. Because we will copy over the entire graphics region in our paint, it is a waste of time and a source of flicker to have update erase the screen.

  3. Define paint so that it copies the background buffer on the canvas. Draw a border around the canvas 0,0,width-1,height-1.

  4. Define mouse down to set the upper-left corner of the rectangle (downX, downY). Just like in the rubberbanding Magercise. Reset width and height (w, h).

  5. Define mouseDrag so that it erases the old image on the visible canvas and draws an updated image at new location. Use XOR mode so the background image is not disturbed. Use method clip to restrict the dragging to the region of the canvas. Draw the rubberbanding rectangle in red, but draw final rectangle in black.

  6. Define mouseUp to draw a rectangle on the background buffer and call repaint to schedule a canvas repaint.

The task numbers above are linked to the step-by-step help page. Also available is a complete solution to the problem, and expected behavior, to demonstrate it.

Copyright © 1996-1997 MageLang Institute. All Rights Reserved.