CS 4773 Object Oriented Systems


The Java Language (continued)


A Ping Pong Applet

The file PrintApp.java
package threadtests;

import java.awt.*;
import java.applet.*;

public abstract class PrintApp extends Applet {

   protected abstract void write_string(String str);

   public synchronized void printit(String str) {
      write_string(str);
   }
}

The file PingPongA.java is a modification of PingPong.java which sends output to an applet.
package threadtests;

public class PingPongA extends Thread {
   String word;                 // what word to print
   int delay;                   // how long to pause
   int count;                   // number of iterations
   PrintApp caller;

   PingPongA(PrintApp caller, String What, int Time, int number) {
      word = What;
      delay = Time;
      count = number;
      this.caller = caller;
      setName(What);
   }

   public void run() {
      try {
         for(int i=0;i < count;i++) {
            caller.printit(i+": "+word);
            sleep(delay);    // wait until next time
         }
      }  catch (InterruptedException e) {
         return;                 // end this thread
      }
   }
}

Here is the actual applet. We do not use join because you are not allowed to suspend the applet itself.
/*
  < applet code="threadtests.test3a" width=600 height = 400 >
  < /applet >
*/
package threadtests;
import java.awt.*;
import java.applet.*;

public class test3a extends PrintApp {

   Graphics tempGC;
   Graphics foreGC;
   Image tempimage;
   Image foreground;
   int sizex;
   int sizey;
   int strnum;

   public void paint(Graphics g) {
      g.drawImage(foreground,0,0,this);
   }

   public void update(Graphics g) {
      paint(g);
   }

   public void init() {
      Thread current;
      sizex = bounds().width;
      sizey = bounds().height;
      foreground = createImage(sizex,sizey);
      tempimage = createImage(sizex,sizey);
      foreGC = foreground.getGraphics();
      tempGC = tempimage.getGraphics();
      strnum = 0;
      foreGC.setColor(Color.red);
      current = Thread.currentThread();
      current.setName("test3a-main");
      show_threads("init");
   }

   private int pos_x(int num) {
      return (num/20);
   }

   private int pos_y(int num) {
      return (num%20);
   }

   protected void write_string(String str) {
      foreGC.drawString(str,300*pos_x(strnum)+10,15*pos_y(strnum)+15);
      strnum++;
      repaint(1);
   }

   public void start() {
      repaint(1);
      start_ping_pong();
   }

   public void show_threads(String msg) {
      String str;
      Thread[] tlist = new Thread[50];
      int count;
      count = Thread.enumerate(tlist);
      str = msg + ": Th:("+count+"):";
      for (int I=0;i < count;i++) 
         str = str + " " + tlist[i].getName() + ",";
      printit(str);
   }

  private void start_ping_pong(){
     PingPongA ping;
     PingPongA pong;

     show_threads("Start of main");
     ping = new PingPongA(this,"ping", 1000, 20);
     show_threads("ping created");
     pong = new PingPongA(this,"PONG", 3000, 10);
     show_threads("pong created");
     ping.start();
     pong.start();
     show_threads("started");
  }
}
Click Here to run this applet.

An Animation Example

The file Animation.java:
package animations;
import java.awt.*;
import java.applet.*;

abstract class Animation {
   protected Applet app;

   protected void init (Applet app) {
      this.app = app;
   }

   public abstract void advance ();

   public abstract void paintFrame(Graphics g,
            Graphics g1, Image im1, Image im2);
}
An Abstract class is one in which not all of the methods are implemented. A class which extends an abstract class must override all of these unimplemented methods.


Rectangle Animation

The file RectangleAnimation.java
package animations;
import java.awt.*;
import java.applet.*;

class RectangleAnimation extends Animation {
   private int cx = 0;
   private int cy = 0;

   public void advance () {
      cx = cx + 1;
      cy = cy + 1;
   }

   public void paintFrame(Graphics dispGC, Graphics bufGC,
                          Image bufImage, Image backImage) {
      bufGC.drawImage(backImage,0,0,app);
      bufGC.fillRect(cx,cy,50,20);
      dispGC.drawImage(bufImage,0,0,app);
   }
}

The Applet

The file AnimationApplet.java
/* < Applet code = "animations.AnimationApplet" 
           width = 200 height = 200 >
   < PARAM NAME = SLEEPTIME VALUE = 50 >
   < /applet > */

package animations;
import java.awt.*;
import java.awt.*;
import java.applet.*;

public class AnimationApplet extends Applet 
                             implements Runnable {

    int sleep_time;
    Thread mythread;
    Animation animation;
    Graphics bufferGC;
    Graphics backGC;
    Image bufferimage;
    Image backgroundimage;

    public void init() {
        set_layout();
        sleep_time = 
           Integer.parseInt(getParameter("SLEEPTIME"));
        backgroundimage = 
           createImage(bounds().width,bounds().height);
        backGC = backgroundimage.getGraphics();
        backGC.setColor(Color.blue);
        backGC.drawString("This is the background ("+
           sleep_time+")",5,50);
        bufferimage = 
           createImage(bounds().width,bounds().height);
        bufferGC = bufferimage.getGraphics();
        bufferGC.setColor(Color.red);
    }

    private void set_layout() {
       setLayout(new BorderLayout());
       add("South", new Button("Start"));
    }

    public void start() {
       if (mythread == null)
          return;
       if (mythread.isAlive())
          mythread.resume();
       else
          mythread.start();
    }

    public void stop() {
       if (mythread == null) return;
       mythread.suspend();
    }

    void slow_it_down(int ms) {
       try {
          Thread.sleep(ms);
       } catch (InterruptedException e) {}
    }

    public void run() {
       for (int i=0; i<100;i++) {
          repaint(1);
          slow_it_down(sleep_time);
          animation.advance();
       }
    }

   public void update (Graphics g) {
      paint(g);
   }

   public void paint (Graphics g) {
      if (animation == null) return;
      animation.paintFrame(g, bufferGC, 
         bufferimage, backgroundimage);
   }

   public boolean action(Event e, Object arg) {
      if ("Start".equals(arg)) {
         showStatus("Start button pushed");
         animation = new RectangleAnimation();
         animation.init(this);
         mythread = new Thread(this);
         mythread.start();
         repaint(1);
         return true;
      }  
      return super.action(e,arg);
   }

}

About AnimationApplet.java:

Click Here to run this applet.

More About Threads

Why a thread is needed for animation: Thread groups: Threads of the animation example:

A Function that lists threads

   public void show_threads(String msg) {
      Thread current;
      Thread[] tlist = new Thread[50];
      int count;
      current = Thread.currentThread();
      count = Thread.enumerate(tlist);
      System.out.println("\n"+msg+" :Current thread: "+
        current+" total:"+count);
      for (int i=0;i


Thread Scheduling


Creating an Animation Library