
/* 
   This file defines an applet that displays a red square that
   jumps when the user clicks it.  It also displays the number
   seconds that have elapsed since the applet was started.

   David J. Eck (eck@hws.edu),  17 January 1998
*/

import java.awt.*;     // Make classes from the packages java.awt and
import java.applet.*;  //        java.applet available for use in this applet.


public class JumpingSquare extends Applet implements Runnable {

   Thread runner = null;  // A separat thread to execute the applet's run() method
                          //   The null value indicats that it has not yet been created
   int threadDelay = 25;  // The length of time, in milliseconds, that the thread will
                          //   "sleep" between its active periods.

   int topOfSquare;   // The location of the top-left corner of the red square.
   int leftOfSquare;

   long startTime;         // Time read from the system clock when the thread starts.
   long elapsedTime = -1;  // Time, in seconds, since the thread started running.
                           //   The -1 value indicates that it has not yet started.
                           //   This is used in the paint() method to avoid displaying
                           //   information that has not yet been computed.


   public void init() {
        // This method is called when the applet is first created, to give
        // it a chance to do any necesary initialization.  Here, I just set
        // the applets background color.
      setBackground(Color.lightGray);
   }


   public void paint(Graphics g) {
        // This method is called whenever the applet needs to be redrawn.
        // The graphics object, g, can be used to draw in the applet.
        // Here the the square and the elapsed time is displayed, but
        // only if elapsedTime has been changed from its initial value of -1.
      if (elapsedTime >= 0) {
        g.setColor(Color.red);
        g.fillRect(leftOfSquare, topOfSquare, 50, 50);
        g.setColor(Color.black);
        g.drawString("Elapsed time: " + elapsedTime + " seconds", 5, 15);
      }
   }


   void doJump() {
         // This is a subroutine that I have provided to set a random location
         // for the square.  This just sets the variables topOfSquare and
         // leftOfSqaure; repaint() should be called to make sure that the
         // changes become visible.
      int appletWidth = size().width;
      int appletHeight = size().height;
      topOfSquare = (int)( (appletHeight - 50)*Math.random() );
      leftOfSquare = (int)( (appletWidth - 50)*Math.random() );
   }


   public boolean mouseDown(Event evt, int x, int y) {
         // This method is called when the user has clicked the mouse at
         // the point (x,y) in the applet.  Here, the square jumps to a
         // new location. 
      if ( x > leftOfSquare && x < leftOfSquare + 50 && 
           y > topOfSquare && y < topOfSquare + 50 ) {
         doJump();   // Change square's location coordinates.
         repaint();  // Tell the system that the applet needs to be redrawn.
      }
      return true;  // (required to tell the system that the mouse click
                    //  has been processed)
   }


   public void start() {
        // This method is called when the applet first starts running.
        // (It might also be called if the applet is stopped and restarted.)
        // Here, the thread named runner is created and started running.
      if (runner == null || !runner.isAlive()) {
         runner = new Thread(this);
         runner.start();
      }
   }


   public void stop() {
        // This method is called when the applet first starts running.
        // (It might also be called if the applet is stopped and restarted.)
        // Here, the thread named runner is stopped, and runner is set to
        // null as a signal that a new thread must be created if the applet
        // is ever restarted.
      if (runner != null && runner.isAlive()) {
         runner.stop();
         runner = null;
      }
   }


   public void run() {

      startTime = System.currentTimeMillis();  // Record time when thread starts running.

      elapsedTime = 0;  // Time since thread started is zero seconds.

      doJump();   // Set random location for square.  
      repaint();  // Tell system that applet should be redrawn.

      while (true) {  // Loop forever, i.e. until thread is stopped

         try { Thread.sleep(threadDelay); }  // Funny sytax to make the thread
         catch (InterruptedException e) { }  //    sleep for >= threadDelay milliseconds.
                                             //    This is essential so that other
                                             //    threads have a chance to execute.

         // After thread wakes up, compute elapsed time since thread started.
         // To avoid unnecessary repainting, check if the number of seconds
         // elapsed has actually changed.  If so, set elapsedTime and call repaint().
         long newElapsedTime = (System.currentTimeMillis() - startTime) / 1000;
         if (newElapsedTime != elapsedTime) {
            elapsedTime = newElapsedTime;
            repaint();
         }

      }

   } // end of run()


} // end of class JumpingSqaure

