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

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

Source for Exercise 3d

All Exercises 3x use Logo and ASquareLogo, which you can find following the links.

In addition to Banner3d, we need IEEELogo for this exercise

Banner3d.java

This code has been purged from the comments that relate to the other 3x exercises.
The source for Banner3a with the comments retained can be found on Banner3-source.html

>
/*
 * @Banner3d    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.*;
import java.awt.image.*;

/**
 * A simple Rart universe

 * @version 2.0  030105
 *
 * @author Jan Aminoff
 */

final public class Banner3d 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 "Banner3d 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" +
         "A uParameter determines the number of Logos. Also, we have now \n"+
		 "imported a gif-file with an IEEE Logo.";
           
   public String getRartist(){ return "Jan Aminoff 2002";}
   // -------------------------------------------------------------------------       
   
   // Section 2   What the universe does
   // -------------------------------------------------------------------------
   // Variables
   private int maxv = 8;         // Max speed of logo
   private int size = 35;        // Size of logo
   
   // We have an array of Logos
   private Logo logoarray[]= new Logo[10];
   private Image ieeelogo;	     // Special for Banner3d
   private Image ieeelogo1;	     // Special for Banner3d
   private Debug dB;  // Not absolutely necessary, but this is difficult 
   			// enough that you may want to have the Debug available.
   
   // init(), implementation of abstract method in Universe.
   public void init(){
   		// Following establishes a pattern for setting and use of Debug.
		dB=new Debug();
		// debugLevel may be set on the following line overriding the setting
		// provided in HTML or command line for the RartRunner or commented 
		// out to accept the setting for the RartRunner
		debugLevel =2;				// Overrides setting in RartRunner 
		dB.setLevel(debugLevel);
		dB.dbg(2,"Banner3e: Debug Level now set to "+debugLevel);
		// Requesting specific resources in he case of Banner3d the IEEE logo.
		// We have in this case an array of only one element.
		String[] logoFilename = {"num3blu.gif"};
		resourceObjects = rartrunner.getResourceObjects(logoFilename);
		// If we had more then one element, we would use a loop as follows
		// for (int i=0; i<resourceObjects.length; i++){.....} 
		// but in Banner3d only one:
		ieeelogo = (Image)resourceObjects[0];
		// The IEEE comes on a square white rectangle that we here make
		// tansparent
		ieeelogo = getRidOfWhite(ieeelogo);
		
      	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.

       // The current number of Logos are given by number.getCur()
        int nn = number.getCur();
        int ne = (int)(nn/2);    // Almost 50% IEEE Logo, 50% ASquare Logo!
       for (int i=0; i< nn ; i++){     
          int s =  20+RND(size);
          if (i<ne)logoarray[i] = new IEEELogo(xm, ym, 2*s, ieeelogo);
            else logoarray[i] = new ASquareLogo(xm, ym, s);
				  logoarray[i].setMaxSpeed(maxv);
       }                
   
   }  // end of reset
   
   // cycle(g), implementation of abstract method in Universe.
   public void cycle(Graphics g){
   
       // We reset the whole rectangle (0,0, xm, ym) 
        g.setColor(background);   
        g.fillRect(0, 0, xm, ym);    // Paint the screen white   
      for (int i=0; i< number.getCur(); i++){   
         logoarray[i].drawLogo(g);        
         logoarray[i].moveLogo();         
      }                             
      
       String s1 = "Welcome to Introductory Java";
       printString(g, s1, 50, 45, 20);
       s1 = "Jan Aminoff, Instructor";
      printString(g, s1, 120, 80 ,14);
      s1 = "Also inventor of Rart, random Art for the Internet.";
      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);
   
  }   // end of cycle(g)

  private Image getRidOfWhite(Image im1){
	int w = size*2;
	int h = size*2;
	Image im = im1.getScaledInstance(w, h, Image.SCALE_FAST);
	  	try{
			//grab the pixels
			int[] pgPixels = new int [w * h];
			PixelGrabber pg = new PixelGrabber
					(im, 0, 0, w, h, pgPixels, 0, w);
			if (pg.grabPixels() && 
					((pg.status() & ImageObserver.ALLBITS) !=0)){
			// Change the white bits
				for (int y=0; y<h; y++){
					for (int x=0; x<w; x++){
						int i = y*w+x;
						int a = (pgPixels[i] & 0xff000000)>>24;
						int r = (pgPixels[i] & 0x00ff0000)>>16;
						int g = (pgPixels[i] & 0x0000ff00)>>8;
						int b = (pgPixels[i] & 0x000000ff);
						if ((r>230) && (g>230) && (b>230)){
							pgPixels[i] = 0;
						}
					}
				}
			}
			im = createImage(new MemoryImageSource (w, h, pgPixels, 0, w));
		}catch(Exception e){e.printStackTrace();}
		return im;
  } //end getRidOfWhite
   
   // manageChange(uP), implementation of abstract method in Universe
   public void manageChange(uParameter uP){
   /*
    * The Banner3 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 Banner3d()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 Banner3d

>

IEEELogo.java

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

import java.awt.*;

public class IEEELogo 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 IEEELogo(int xmax, int ymax, int size, Image logo1){
		  super(xmax , ymax, size);
		  // The Image logo is provided in the constructor and must 
		  // be generated in the universe. However, we here scale it to size.
		  logo = logo1.getScaledInstance(2*s, 2*s, Image.SCALE_FAST);
	  }
     
     public void drawLogo(Graphics g){
        int w=s;    //half width
        int h=s;    //half height         
        g.drawImage(logo, p.x-w, p.y-h, this);
        
    }
    public void eraseLogo(Graphics g, Color c){
        // Erases the IEEE logo by drawing a rectangle of size
        // 2*s by 2*s centered at p
            int w=s;
            int h=s;
            g.setColor(c);
            g.fillRect(p.x-w,p.y-h,2*w,2*h);
    }
    private Image logo;
}
>