Back to July Calendar 

Previous Entry Next Entry→

July 30, 2005

 

The applets we've seen so far here all inherit their basic properties from Applet through the use of the word  extends, for example in the line

public class Mondrian2 extends Applet {

which means that the derived class Mondrian2 will inherit the parent class Applet's public variables and methods, such as paint(). Since Mondrian2 "is an" Applet, the use of inheritance is appropriate.  In java, all classes are derivative of the mother class, Object.  Even if the "extends" keyword is omitted, the public and protected methods of Object are inherited by default. 

 

I'll try to annotate this as best I can.  Here's what I've got for today:

 



import java.applet.*;
import java.awt.*;
import java.util.*; //This is for the Random() function
public class Mondrian4 extends Applet implements Runnable {
  Thread animation;
  Graphics offscreen;
  Image image;
  static final int NUM_RECTS = 9;      //in ms
  static final int REFRESH_RATE = 100; //in ms
  MovingRect rek[];
  public void init() {
    System.out.println(">> init <<");
    setBackground(Color.black);
    initRectangles();
    image = createImage(bounds().width,bounds().height);
    offscreen = image.getGraphics();
  }
  public void initRectangles() {
    // allocate memory for Moving rectangles
    rek = new MovingRect[NUM_RECTS];
    rek[0] = new MovingRect(0,0,90,90,Color.yellow);
    rek[1] = new BoogieRect(250,0,40,190,Color.yellow);
    rek[2] = new WaltzRect(200,55,60,135,Color.yellow);
    rek[3] = new BoogieRect(80,200,220,90,Color.blue);
    rek[4] = new WaltzRect(100,10,90,80,Color.blue);
    rek[5] = new BoogieRect(80,100,110,90,Color.lightGray);
    rek[6] = new WaltzRect(200,0,45,45,Color.red);
    rek[7] = new WaltzRect(0,100,70,200,Color.red);
    rek[8] = new BoogieRect(200,55,60,135,Color.magenta);
  }
  public void start() {
    System.out.println(">> start <<");
    animation = new Thread(this);
    if (animation != null) {
      animation.start();
    }
  }
  // update each rectangle's position.
  // This is the dynamic method binding--Movement() is over-ridden
  // for individual choreography!
  public void updateRectangles() {
    for (int i=0; i<NUM_RECTS; i++) {
      rek[i].Movement(); // each rectangle's Movement
    }
  }
  // override update so it doesn't erase screen
  public void update(Graphics g) {
    paint(g);
  }
  public void paint(Graphics g) {
    offscreen.setColor(Color.black);
    offscreen.fillRect(0,0,300,300); // clear buffer
    for (int i=0; i<NUM_RECTS; i++) {
      rek[i].paint(offscreen); // paint each rectangle
    }
    g.drawImage(image,0,0,this);
  }
  public void run() {
    while (true) {
      repaint();
      updateRectangles();
      try {
        Thread.sleep (REFRESH_RATE);
      } catch (Exception exc) { };
    }
  }
  public void stop() {
    System.out.println(">> stop <<");
    if (animation != null) {
      animation.stop();
      animation = null;
    }
  }
}
/////////////////////////////////////////////////////////////////
class MovingRect {
  int ulCornx, ulCorny; // (ulCornx,ulCornyy) are coordinates of upper
                        // left corner of rectangle
  int width, height; // width and height of rectangle
  Color rectColor; // color of rectangle
  /////////////////////////////////////////////////////////////////
  public MovingRect(int x,int y,int w,int h,Color c) {
    ulCornx = x;
    ulCorny = y;
    width = w;
    height = h;
    rectColor = c;
  }
  public void Movement() {
    // this is just a placeholder for dynamic binding
  }
  public void paint(Graphics g) {
    g.setColor(rectColor);
    g.fillRect(ulCornx,ulCorny,width,height);
  }
}
/////////////////////////////////////////////////////////////////
class BoogieRect extends MovingRect {
  Random r1 = new Random(); //add a touch of unpredictability to motion
  // BoogieRect inherits all instance variables and
  // methods from MovingRect

  static final byte UP = 0; // direction of motion
  static final byte DOWN = 1;
  static final byte LEFT = 2;
  static final byte RIGHT = 3;
  byte state; // state of rectangle
  int max_x; // max x value
  int min_x; // min x value
  int max_y; // max y value
  int min_y; // min y value
  /////////////////////////////////////////////////////////////////
  public BoogieRect(int x,int y,int w,int h,Color c) {
    super(x,y,w,h,c); // call superclass constructor
    int i = r1.nextInt()%4;
    int j = r1.nextInt()%8;
    max_x = ulCornx + 13 + i;
    min_x = ulCornx - 13;
    max_y = ulCorny + 13+j;
    min_y = ulCorny - 13;
  }
  // override MoveStep()
  public void Movement() {
    switch (state) {
      case DOWN:
        ulCorny += 2;
        if (ulCorny >= max_y) {
          state = UP;
        }
        break;
      case UP:
        ulCorny -= 2;
        if (ulCorny <= min_y) {
          state = RIGHT;
        }
        break;
      case RIGHT:
       ulCornx += 2;
       if (ulCornx >= max_x) {
          state = LEFT;
       }
       break;
     case LEFT:
       ulCornx -= 2;
       if (ulCornx <= min_x) {
         state = DOWN;
       }
       break;
    }
  }
}
/////////////////////////////////////////////////////////////////
// WaltzRect also inherits from MovingRect

class WaltzRect extends MovingRect {
  byte state;
  static final byte SE = 0; // going southeast
  static final byte NE = 1; // going northeast
  static final byte W = 2; // going west
  int bottom_x; // the x coordinate of
  // bottom pt of the waltz

  int right_x; // the x coordinate of
               // right pt of the waltz

  int left_x; // the x coordinate of
              // left pt of the waltz

  /////////////////////////////////////////////////////////////////

  public WaltzRect(int x,int y,int w,int h,Color c) {
    super(x,y,w,h,c); // call superclass constructor
    bottom_x = ulCornx + 17;
    right_x = bottom_x + 17;
    left_x = ulCornx;
  }


  // override Movement()
  public void Movement() {
    switch (state) {
      case SE:
        ulCornx++;
        ulCorny++;
        if (ulCornx == bottom_x) {
          state = NE;
        }
        break;
      case NE:
        ulCornx++;
        ulCorny--;
        if (ulCornx == right_x) {
          state = W;
        }
        break;
      case W:
        ulCornx-- ;
        if (ulCornx == left_x) {
          state = SE;
        }
        break;
      }
   }
}

It's odd: when I compile and run stand-alone, the rectangles go flying around, but when I try to access the Applet via the internet using IE5, they're stuck still in the solid mud...do they move for you?  To be sure, I used my son's Windows 2000/Firefox set up and (after long interlude downloading and installing the java runtime environment), lo and behold, the rectangles are moving!  Hmmm.  After a reboot, they're moving again on my computer, so go figure...