IIntroduction to Java. A tutorial from A-SQUARE, Inc. January 2003

© 2000-2003 A-Square, Inc. Cambridge, MA

Source Code for Exercise 3

We have provided the final working sourcecode for Banner3a-d for all four exercises in the EX3a, EX3b, EX3c, EX3d folders. In addition sourcecode for the classes Logo and ASquareLogo is unchanged in all four exercises. We provide a version of Banner3a below for the purpose of reference when discussing this exercise. This version has comments to single out modifications for the various exercises, but comletness is not guaranteed. We also provide the source for Logo and ASquareLogo. Finally IEEELogo is used only in EX3d and provided in the EX3d folder.

Banner3a.java

Logo.java

ASquareLogo.java

As always you get the sourcecode by selecting and copying any text between the two > that separate the source text from the rest of this HTML document.

Banner3a.java with comments relevant to EX3a, EX3b, EX3c, and EX3d

Note the three main sections of a Rart Universe:

Section 1 Identifying the universe

Section 2 What the universe does

Section 3 uParameters as used in the universe

>

/*
 * @Banner3a    2.0  030105
 *
 * © A-Square, Inc.  
 * 175 Richdale Ave, Cambridge MA 02140 
 */

import java.awt.*;
import java.applet.Applet;
import java.util.Date;
import rartbase.*;

/**
 * A simple Rart universe
 * @version 2.0  000928
 *
 * @author Jan Aminoff
 */

final public class Banner3a extends Universe {
   /*
    * This source file is provided in sections corresponding to sections
    * with the the same name and order of the Universe.java source file.
    */

   // Section 1   Identifying the universe
   // -------------------------------------------------------------------------
   public String getName(){return "Banner3a, a Rart Universe";}
   
   public String getDescription(){ return descr;  } 
   public String descr=  
         "This universe is used to demonstrate the basic Rart framework \n"+
         "in the Introduction to Java Tutorial. It should be compared \n"+ 
         "to the Banner2a applet of the same tutorial. \n" +
      // Following line is for Ex2b - d
      //    "A uParameter now determines the number of Logos. \n"+
      /* Following 3 lines are for Ex2c only
         *  "In Banner3a one counter steps the number of frames and another \n"+
         *  "is used to check the uParameter mechanism. \n"+
         *  "We are also timing 100 executions with and without overhead. " +
         */
            " ";          // NEVER FORGET THE SEMICOLON!
                       
     
   public String getRartist(){ return "Jan Aminoff 2000";}
   // -------------------------------------------------------------------------       
   
   // Section 2   What the universe does
   // -------------------------------------------------------------------------
   // Variables
   private int maxv = 8;         // Max speed of logo
   private int size = 35;        // Size of logo
   // Following is specific to Ex3a
   private ASquareLogo logo;
   // Following line is specific to Ex3b-d , where we have an array of Logos
   // private Logo logoarray[] = new Logo[10];      //Commented out for Ex3a.
   
  /* The following are used for timing and are for Ex2c only
   * private long t0,t1,t2; // Timers for measuring cycle lengths
   * private int ndt;     // 100 cycles, absolute time
   * private int sdt;     // accumulates lengths of 100 cycles, with overhead
   * private int ssdt;    // accumulates lengths of 100 cycles, no overhead
   * private int ns;      // number of cycles modulo 100.
   */
   
   // init(), implementation of abstract method in Universe.
   public void init(){
   	  // See Banner3d where we here provide the signal to the rartrunner
	  // to import a certain gif-file. We then process it here.
      setParams();  //See Section 3 
      // We collect all reactions to changes in a reset method
      reset();
      
   }

   private void reset(){
      // Note: The two variables xm and ym are available in the parent class
      // Universe. They give the size of the available window at all times.
      // Following is specific to Ex3a
      logo = new ASquareLogo(xm, ym, size);
      logo.setMaxSpeed(maxv);
   // Following five lines are specific to Ex3b , where we have an array
   // The max number of Logos are given by number.getMax()
   // for (int i=0; i< number.getMax(); i++){       // Commented out for Ex3a.
   //    int s =  10+RND(size);                     // Commented out for Ex3a.
   //    logoarray[i] = new ASquareLogo(xm, ym, s); // Commented out for Ex3a.
   //    logoarray[i].setMaxSpeed(maxv);            // Commented out for Ex3a.
   // }                 // Commented out for Ex3a.
   /*
    * The following is for Ex3c only
    * t1 = System.currentTimeMillis();  // Initiates timing
    */
        }  // end of reset
   
   // cycle(g), implementation of abstract method in Universe.
   public void cycle(Graphics g){
   /* The following lines are for Ex3c only
    * //The first part deals with the measuring of cycle time.
    * t0=System.currentTimeMillis(); // t0 gives time at beginning of cycle.
    * if (ns == 0)                   // Is this the first of 100 cycles?
    * {
    *    t2=System.currentTimeMillis();
    *    ndt=(int)(t2-t1);             // ndt absolute time
    *    t1=t2;
    *    ssdt=sdt;
    *    sdt=0;
    * }     // end of Ex3c portion
    */

      // Compare with the update method of Banner2a!
      // We reset the whole rectangle (0,0, maxx, maxy) 
        g.setColor(Color.lightGray);   
        g.fillRect(0, 0, xm, ym);    // Paint the screen light gray    
      // Following two lines are specific to EX3a only
      logo.drawLogo(g);       // Draw the logo 
      logo.moveLogo();        // Move the logo
      // Following three lines are specific to Ex3b - d
   // for (int i=0; i< number.getCur(); i++){ // Commented out for Ex3a.
   //    logoarray[i].drawLogo(g);            // Commented out for Ex3a.
   //    logoarray[i].moveLogo();             // Commented out for Ex3a.
   // }                                 	  // Commented out for Ex3a.
   
      String s1 = "Welcome to Introductory Java";
    /* The following line is for Ex3c only
     * s1 = "RART®";
     */
     printString(g, s1, 50, 45, 20);
     s1 = "Jan Aminoff, Instructor";
     /* The following line is for Ex3c only
      * s1 =  "Counter of Frames mod 100: "+ns;
      */
      printString(g, s1, 120, 80 ,14);
     /* The following lines are for Ex3c only
      * printString(g,"Width by height: "+xm+" x "+ym,120,100,14);
      * printString(g,"Time of 100 cycles(with overhead): "+ndt+" ms",120,120,14);
      * printString(g,"Time of 100 cycles(no overhead): "+ssdt+" ms",120,140,14);
      */
      int nn=number.getCur();
      s1 = "Also inventor of Rart, random Art for the Internet.";
     /* The following line is for Ex3c only
      * s1 = "The present value of the parameter NUMBER: "+ nn;
      */
      printString(g, s1,xm-250,ym-5,10);
	  s1 = "Java Environment: "+
		    System.getProperty("java.vendor")+"..."+
		    System.getProperty("java.version");
		printString(g, s1, 5, 15 ,12);
   
      // This has to do with timing at the end of the cycle.
      // nc, from Universe, is actual number of cycles. ns is nc modulo 100
      /* The following lines are for Ex3c only
       * ns = nc % 100;
       * sdt += (int)(System.currentTimeMillis()-t0);
       */
  }   // end of cycle(g)
   
   // manageChange(uP), implementation of abstract method in Universe
   public void manageChange(uParameter uP){
   /*
    * The Banner3a universe has three parameters, with
    * index VIEWSIZE, CYCLETIME, and NUMBER respectively
    * Section 3 gives the definitions. Here we have to program what to
    * do if any of these parameters is modified.
    */
    int type = uP.getIndex();
    if (type == VIEWSIZE){      // If the size of the screen has changed.
        reset();                // Just start all over
    }else if (type == CYCLETIME){   // If the cycletime is modified
        cycletime = uP;         // Make sure cycletime has right value        
    }else if (type == NUMBER){
        number = uP;            // number has right value
        reset();                // Just start all over.
    }
   }    // end of manageChange(uP)
   
   // getBackground(), overriding method in Universe
   public Color getBackground(){return background;}
   private Color background = Color.lightGray;
   // -------------------------------------------------------------------------

   // Section 3   uParameters as used in the universe
   // -------------------------------------------------------------------------
   
   // There are two uParameters defined here: cycletime defined almost always,
   // and number which is specific to this universe.
   private uParameter cycletime;
   private uParameter number;
   
   // The setParams() method is called only once, in init(), it is defined here
   // in Section 3, so all parameter related stuff is together
   private void setParams(){
        // First cycletime
        // Since "Cycle Time" is a compulsory parameter, the description is
        // provided in Universe as CycleTimeDescr.
        cycletime = new uParameter
                (CYCLETIME,"Cycle Time", 10,50,100, CycleTimeDescr);
        // we now have to add the parameter to the array of uParameters
        // associated with this universe
        adduParameter(cycletime);
        
        // Second number
        String ndescr = "In EX2b, EX2c, and EX2d Double click \n"+
				"to see this parameter change!"; 
        number= new uParameter
                (NUMBER, "Number of objects",0,5,10, ndescr);
         adduParameter(number); 
   }  // end of setParams()
   // ------------------------------------------------------------------------- 

   // Section 4   Utility Methods
   // -------------------------------------------------------------------------   
   // All provided in Universe, include  int RND(int x), printString, etc
   
   // Section 5 Useful Variables
   // -------------------------------------------------------------------------
   // Provided in Universe, include xm, ym, for width and height of window and
   // nc for number of frames.
   
   // Section 6 Security related methods
   // Provided in Universe, except for the following constructor.
   
   public Banner3a()throws InstantiationException
   {
      // Empty statement. This will activate the constructor of Universe
      // which only allows the activation of one universe at a time in
      // order to preclude bogging down the system by mistake or intent.
   }
   
}  //end of definition of Banner3a

>

Logo.java

>
/**
 * Logo.java        version 2.0   030105
 * 
 * This is an example of an abstract class. We prescribe a behavior common to
 * all concrete implementations  of this class, which prescribe the way Logo 
 * objects float on the screen. We leave the specifics on how an actual Logo
 * looks to the programmer who uses the class.
 *
 * Used in EX3 in the Introduction to Java Tutorial
 * Compared to Version 1.0, we have eliminated the getRartImage method,
 * which is now handled in Universe. Not a major revision, but with
 * clean result!
 * 
 * Copyright (c) A-Square Inc., 
 * 175 Richdale Ave. Cambridge MA 02140
 * All Rights Reserved.
 * 
 */
 import java.awt.*;

public abstract class Logo extends Component{
/* In an abstract class some items are left for the extending classes to
 * define. In this case the extending classes will define the look of the
 * floating objects.
 * Movement is defined in the moveLogo() method and can be influenced by the
 * MouseDown() method.
 * Jan Aminoff, A-Square, September 2000.
 */

    
    public Logo(int xm, int ym, int size){
    /**
     * This constructor initiates a Logo of size size floating within
     * the rectangle with (0.0) as the upper right and (xm, ym) at lower left.
     */
        maxx = xm;
        maxy = ym;
        p= new Point( RND(maxx), RND(maxy));
        // d.dbg("Point : "+p.x+ ", "+p.y);
        s = size;  
        maxv = 2+(maxx+maxy)/100;
        dx=setSpeed(maxv);
        dy=setSpeed(maxv);
    }
    
    
    
   
    public abstract void drawLogo(Graphics g);
    /* Abstract method draw
     * Draws a Logo of size s pixels at Point p (Coordinates p.x and p.y)
     * using the Graphics Context g
     */
    
    public abstract void eraseLogo(Graphics g, Color c);
    /* Abstract method erase
     * erases a Logo of size s pixels centered at p by drawing
     * it using the Color c, for example the background color, using g
     */
    
    public void moveLogo(){
    /*  This is NOT an abstract method! It encapsulates the moving of a 
     *  point bouncing as we have seen a number of times.
     */
      int x = p.x;
      int y = p.y;      
      x += dx;
      y += dy;    
      // check to see if point  hit the edge    
      if (x < 0 || x > maxx ){          // Check to see if the point hit the edge in x-direction
         dx = (x < 0)? ABS(dx) : - ABS(dx);     //Ensure point always moving toward center
         x += 2*dx;                 //Double back
         dy = setSpeed(maxv);        //change speed in y-direction
      }
      
      if (y < 0 || y > maxy ){
         dy = (y < 0)?  ABS(dy) : - ABS(dy); 
         y += 2*dy;
         dx = setSpeed(maxv);       //change speed in x-direction
      }
      p = new Point(x,y);   
   }
   
   public void setMaxSpeed( int vmax){
      maxv = vmax;
   }

   public void stopMove(){
      dx1=dx;
      dx=0;
      dy1=dy;
      dy=0;
   }


   public void resumeMove(){
      dx=dx1;
      dy=dy1;      
   }
    
    
    private int setSpeed(int mv){
   // We will also define a method to generate a change of speed based on 
   // a maximum speed mv
        int v;
        do v = mv/2- RND(mv); 
        while (v ==0);
        return v;
    }

   // The following methods are protected. This means the methods are available
   //  to methods extending the Logo class but not elsewhere.
    
    // RND generates any of the integers in the interval 0 to max - 1.
   protected static int RND(int max){
      return (int)(java.lang.Math.random() * max);
   }

   // ABS(x) returns the absolute value of the integer x
   protected static int ABS(int x){
      return ((x>0)? x: -x);
   }

   // The following two variables are protected, that is their values are
   // at any time available to any class extending the Logo class.
   // In particular the values are used to draw the object in the draw 
   // method
   protected Point p;         // The center of the object. 
                                // A point with coordinates p.x and p.y
   protected int s;            // A measure of the size of the object

    //Here we list the private variables used by the class
    
    private int maxx;   //Windowsize in x-direction
    private int maxy;   //Windowsize in y-direction
    private int maxv;   //Maximum sped in any direction, pixels per frame
    private int dx;     //Current speed in x-direction
    private int dy;     //Current speed in y-direction

    private int dx1;    //Keeper for speed in x-direction
    private int dy1;    //Keeper for speed in y-direction
   
}
>

ASquareLogo.java

>
/* ASquareLogo.java    Version 1.0  000910
 *
 * This class is used to provide a floating A-Square logo. 
 * It is used in the Banner2 applet,and Banner 3 universe. 
 *
 * Copyright (c) A-Square Inc., 
 * 1648 Waters Edge Lane, Reston, VA 20190
 * All Rights Reserved.
 */

import java.awt.*;

public class ASquareLogo extends Logo{
    /** In this class we only need to define the two methods
     * declared abstract in Logo:
     * drawLogo(Graphics g)which draws the object of size s centered at point p
     * eraseLogo(Graphics g, Color c) which erases the object by drawing a 
     * rectangle of size s and the color c centered at point p
     *
     */

     // The following constructor invokes the super constructor, that is the
     // constructor of the class this class extends
     public ASquareLogo(int xmax, int ymax, int size){
        super(xmax,ymax,size);
     }
     
     public void drawLogo(Graphics g){
       //Draws the A-Square logo of size 2*s by 2.4*s centered at p
            int w=s;
            int h=(int) (1.2*s);
            int x=p.x;
            int y=p.y;          
            g.setColor(Color.darkGray);
            g.fillRect(x-w,y-h,2*w,2*h);
            w=(int) (0.8*w);
            h=(int) (0.8*h);
            g.setColor(Color.yellow);
            g.fillRect(x-w,y-h,2*w,2*h);
            g.setColor(Color.red);
            g.fillRect(x-w,y-h,w,h);
            g.fillRect(x,y,w,h);
    }

    public void eraseLogo(Graphics g, Color c){
        // Erases the A-Square logo by drawing a rectangle of size
        // 2*s by 2.4*s centered at p
            int w=s;
            int h=(int) (1.2*s);
            int x=p.x;
            int y=p.y;
            g.setColor(c);
            g.fillRect(x-w,y-h,2*w,2*h);
    }
}
>