/*
This is the support code that implements a frame buffer in a Java Applet, by using a Memory Image Source. You can probably use this class without ever needing to change it. */ import java.applet.*; import java.awt.*; import java.awt.image.*; public class MISApplet extends Applet implements Runnable { public int W, H; // YOUR APPLET CAN OVERRIDE THE FOLLOWING TWO METHODS: public void initialize() {} public void initFrame(double time) { } // INITIALIZE EACH FRAME public void setPixel(int x, int y, int rgb[]) { } // SET COLOR AT EACH PIXEL // INITIALIZE THINGS WHEN APPLET STARTS UP public void init() { setLayout(new BorderLayout()); createBuffers(); initialize(); startTime = clockTime(); // FETCH CLOCK TIME WHEN APPLET STARTS new Thread(this).start(); // START THE BACKGROUND RENDERING THREAD } // UPDATE DISPLAY AT EACH FRAME, BY DRAWING FROM MEMORY IMAGE SOURCE public void update(Graphics g) { if (W != getBounds().width || H != getBounds().height) createBuffers(); g.drawImage(im, 0, 0, null); } // BACKGROUND THREAD: COMPUTE AND DRAW FRAME, EVERY 30 MILLISEC public void run() { while(true) { computeImage(clockTime() - startTime); mis.newPixels(0, 0, W, H, true); repaint(); try { Thread.sleep(30); } catch(InterruptedException ie) {} if (W != getBounds().width || H != getBounds().height) createBuffers(); } } // INITIALIZE ALL RESOLUTION-DEPENDENT IMAGE DATA void createBuffers() { W = getBounds().width; // FIND THE RESOLUTION OF THE JAVA APPLET H = getBounds().height; pix = new int[W*H]; // ALLOCATE A FRAME BUFFER IMAGE mis = new MemoryImageSource(W, H, pix, 0, W); mis.setAnimated(true); im = createImage(mis); // MAKE MEMORY IMAGE SOURCE FOR FRAME BUFFER } // COMPUTE IMAGE, GIVEN ANIMATION TIME private int rgb[] = new int[3]; public void computeImage(double time) { initFrame(time); // INITIALIZE COMPUTATION FOR FRAME int i = 0; for(int y = 0; y < H; y++) for(int x = 0; x < W; x++) { // COMPUTE COLOR FOR EACH PIXEL setPixel(x, y, rgb); pix[i++] = pack(rgb[0],rgb[1],rgb[2]); } } public int pack(int red, int grn, int blu) { return 255<<24 | clip(red,0,255)<<16 | clip(grn,0,255)<< 8 | clip(blu,0,255) ; } public int unpack(int packedRGB, int component) { return packedRGB >> 8*(2-component) & 255; } public int xy2i(int x, int y) { return x + W * y; } int clip(int t, int lo, int hi) { return thi ? hi : t; } // RETURN THE TIME, IN SECONDS, ON THE CLOCK double clockTime() { return System.currentTimeMillis() / 1000.; } // PRIVATE DATA public int[] pix; // THE FRAME BUFFER ARRAY private MemoryImageSource mis; // MEMORY IMAGE SOURCE CONTAINING FRAME BUFFER private Image im; // IMAGE CONTAINING THE MEMORY IMAGE SOURCE private double startTime; // CLOCK TIME THAT THE APPLET STARTED }