import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import static java.lang.Math.*;

public class Circle extends Applet implements Runnable { // need Runnable to use Thread()
  Thread thr;
  int delay = 30;
  int step = 0;

  public void init() {}

  // start a new thread for animation
  public void start() {
    thr = new Thread(this);
    thr.start();
  }

  // kill the thread
  public void stop() { thr = null; }

  // job done by the thread, from Runnable
  public void run() {
    long tm = System.currentTimeMillis();
    while (Thread.currentThread() == thr) {
      repaint();
      try {
        tm += delay;
        Thread.sleep( max(0, tm - System.currentTimeMillis()) );
      } catch (InterruptedException e) {
        break;
      }
      if (++step >= 255) break;
    }
  }

  // graphics
  Image img; // buffered image
  Graphics gi; // context associated with the image
  Dimension sz; // size of the image

  // specific drawing goes here
  public void drawStuff(Graphics g) {
    double d = max(sz.width - step, 0.0);
    double x0 = (sz.width - d + step * .4)*.5;
    double y0 = (sz.height - d - step * .4)*.5;
    Color color = new Color(
        min(step*2/5, 255),
        min(step*4/5, 255),
        min(40 + step*4/5, 255)
        );

    Shape circle = new Ellipse2D.Double(x0, y0, d, d);
    Graphics2D g2 = (Graphics2D) g;
    g2.draw(circle);
    g2.setPaint(color);
    g2.fill(circle);
  }

  public void paint(Graphics g) {
    if (img != null) // draw a prepared image
      g.drawImage(img, 0, 0, null);
  }

  public void update(Graphics g) {
    Dimension szn = getSize();

    // create a off-screen context gi,
    if (gi == null || szn.width != sz.width || szn.height != sz.height) {
      sz = szn;
      img = createImage(sz.width, sz.height);
      gi  = img.getGraphics();
      gi.setColor(getBackground()); // clear the image
      gi.fillRect(0, 0, sz.width, sz.height);
    }

    // draw on gi instead of directly on g
    drawStuff(gi);

    // put image to screen
    g.drawImage(img, 0, 0, null);
  }
}

