import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.MemoryImageSource;
import java.awt.image.DirectColorModel;
import java.awt.Frame;
import java.awt.BorderLayout;


public class JavaImage extends java.applet.Applet
   implements Runnable {

   static final int NPTS = 100;
   static final int NSTEPS = 40;
   static final int NGRAYS=255;
   Thread T;
   Image I;
   MemoryImageSource mis;
   int imgdata[] = new int[NPTS*NPTS];     
   Graphics G;

   public static void main(String args[]) {
      Frame F = new Frame("JavaImage");
      F.resize(NPTS,NPTS);
      F.show();
      JavaImage J = new JavaImage();
      F.setLayout(new BorderLayout());
      F.add("Center",J); 
      J.init();
      J.start();
      F.layout();
      }

   public void init() {
      int i,gray;
      mis = new MemoryImageSource(NPTS, NPTS,       
				  new DirectColorModel(8, 255, 255, 255),
				  imgdata, 0, NPTS);
      mis.setAnimated(true);
      I = createImage(mis);
      }
   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() {
      double r, xr, yr;
      int gray, i, j, step;
      while (true) {
	 for (step = 1; step < NSTEPS; ++step) {
	    for (i = 0; i < NPTS; ++i) {
	       for (j = 0; j < NPTS; ++j) {
		  xr = (2.0*i + 1.0 - NPTS)/NPTS;
		  yr = (2.0*j + 1.0 - NPTS)/NPTS;
		  r = step * 20.0 * Math.sqrt(xr*xr + yr*yr)/NSTEPS;
		  gray = (int) (NGRAYS*(0.5+Math.sin(r)/r)/1.5);
		  imgdata[i*NPTS+j] = gray;
		  }
	       }
	    repaint();
	    try {Thread.sleep(10);}
	    catch (InterruptedException e) { }
	    Thread.yield();
	    mis.newPixels(0,0,NPTS,NPTS);
	 }
      }
      }
   public synchronized void paint(Graphics g) {
      g.drawImage(I,0,0,this);
      }
   public void update(Graphics g) {
      paint(g);
      }
   }
