/*
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 boolean animating = false;
public abstract void render(Graphics g); //App. defines render method
Image bufferImage = null; //Image for the double buffer
private Graphics bufferGraphics = null; //Canvas for double buffer
private Thread t; //Background thread for rendering
private Rectangle r = new Rectangle(0,0,0,0); //Double buffer bounds
//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 each 30 msecs
}
catch(InterruptedException e){}; //Catch interruptions of sleep().
}
//Update(Graphics) is called by repaint() - the system adds canvas.
//Extend 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(); //Applet size change
r = bounds(); //Make double buffer
damage = true; //Tell application.
}
if (damage)
render(bufferGraphics); //Ask application to render to buffer,
damage = animating; //
paint(g); //paste buffered image onto the applet.
}
//Separate paint method for application to extend if needed.
public void paint(Graphics g) {
if (bufferImage != null) //
g.drawImage(bufferImage,0,0,this); //Paste result of render().
}
}