/*
You have my permission to use freely, as long as you keep the attribution. - Ken Perlin
Note: this BufferedApplet.html file also works as a legal BufferedApplet.java file. If you save the source under that name, you can just run javac on it.
*/ import java.awt.*; public abstract class BufferedApplet extends java.applet.Applet implements Runnable { public boolean damage = true; //Flag advising app. program to rerender public abstract void render(Graphics g); //App. program must define render method Image bufferImage = null; //Image for the double buffer protected Graphics bufferGraphics = null;//Graphics context for double buffer private Thread t; //Background thread for rendering private Rectangle r = new Rectangle(0,0,0,0); //Bounding box for double buffer //Extend the start,stop,run methods to implement double buffering. public void start() { if (t == null) { t = new Thread(this); t.start(); } } public void stop() { if (t != null) { t.stop(); t = null; } } public void run() { try { while (true) { repaint(); t.sleep(30); } //Repaint every 30 milliseconds. } catch(InterruptedException e){}; //We must catch any interruptions of sleep(). } //Update(Graphics) is called by repaint() - the system adds a Graphics context. //We extend the update method to create a double buffer whenever necessary. public void update(Graphics g) { if (r.width != bounds().width || r.height != bounds().height) { bufferImage = createImage(bounds().width, bounds().height); bufferGraphics = bufferImage.getGraphics(); //Whenever applet changes size r = bounds(); //we create a new double buffer damage = true; //and tell application. } render(bufferGraphics); //We ask application program to render to the buffer, damage = false; // paint(g); //and we paste the buffered image onto the applet. } //Make a separate paint method in case application program wants to extend it. public void paint(Graphics g) { //To paint when double buffering, if (bufferImage != null) // g.drawImage(bufferImage,0,0,this); //we just paste in result of render(). } }