// base class for double buffered applets. Drawing is done to imageBuffer, // an offscreen buffer that's BLTed to the frame as need be. This gives // you less flashies and some measure of image persistence across exposes. // (it'd be nice if we could do this for arbitrary components, but that // would require changing the root Component class) // Draw model: // When drawing, don't use this.getGraphics() or paint()'s argument- // use imageBuffer.getGraphics() // override paint() as expected to paint, but make sure to // call super.paint() to actually render your changes // call this.repaint() to actually cause the drawing to show up // (or wait for something else to call this.update()) // use this.setBackground() as you would normally // call clearImageBuffer() to reset the entire drawing to background color import java.applet.*; import java.awt.*; public class DoubleBufferApplet extends Applet { protected Image imageBuffer; protected Dimension imageBufferSize; // paint - just call update. Subclass can override this, be sure to call // super.paint() as the last step. public void paint(Graphics g) { this.update(g); } // clear the image buffer to whatever the background colour is. public void clearImageBuffer() { Graphics ig = imageBuffer.getGraphics(); Color oldColor = ig.getColor(); ig.setColor(this.getBackground()); // clear the buffer ig.fillRect(0, 0, imageBufferSize.width, imageBufferSize.height); ig.setColor(oldColor); } // update - render the buffer onto the screen // also handles lazy creation of the offscreen buffer public void update (Graphics g) { Dimension appletSize = this.size(); // read the current size // check that the buffer is valid - if not, build one if (imageBuffer == null || appletSize.width != imageBufferSize.width || appletSize.height != imageBufferSize.height) { // System.out.println("Building a buffer of size " + appletSize); imageBuffer = createImage(appletSize.width, appletSize.height); imageBufferSize = appletSize; this.clearImageBuffer(); } g.drawImage(imageBuffer, 0, 0, this); } }