Uploaded to www.rart.com/j2me-presentation/html_Source/ March 19, 2002
This class provides the template for a Rart universe in the AWT environment
This version will be part of the RDK 2.0 release, Spring 2002. It requires JDK 1.1, and has been tested with JDK 1.1.8.
/*
* @Universe 1.5 011201
*
* © A-Square, Inc.
* 1648 Waters Edge Lane, Reston Virginia, 20190, USA
*/
package rartbase;
import java.awt.*;
import java.util.*;
import java.awt.image.*;
/**
* Universe
* An abstract class defining the common properties of all Rart universes
*
* @version 1.5 011201
*
* @author Jan Aminoff
*
* This abstract class allows the RartRunners to control the execution of any
* universe extending Universe. It is the key to the Rart concept as
* implemented in Java and forms an integral part of the Rart Development Kit.
*
* In July: Changed Set extents and commented out (Temporarily?) throwing an
* exception when instantiated more than once. It caused problems when NN is
* the default browser and you try to start by doubleclicking the HTML startup.
*
* Version 1.5
* - Reinstated the constructor throwing an exception when more than
* one universe invoked.
* - The Demo RR uses the uPs directly to generate random current values for
* the uParameters defined for the universe. This violates the OO
* methodology. The array is protected private as of now.
* - Comments adjusted to fit the 1.5 release of Lines
* - Generalized the import of resources which now in a unified way deals
* with text (txt), image (gif), and sound (au) files. this uses
* the getResource method of the class Class, which was introduced with
* JDK 1.1 making the class and its progeny not executable under
* JDK 1.0.2. (unless RR was compiled under 1.1+ and the universe
* under execution does not request any resources).
* See methods getReFileNames,
* Released as part of RDK 1.5
*
*/
public abstract class Universe extends Component{
// Section 1 Identifying the universe
// Three simple public abstract methods getName, getDescription, getRartist
// ------------------------------------------------------------------------
/**
* Provides the name of the univese as an arbitrary string (not to be
* confused with the name of the class extending Universe).
*
* @return String. Name of the universe using no more than 20 characters.
*/
public abstract String getName();
/* Sample code for getName:
public String getName() {return("Lines");}
*/
/**
* Provides a description of the universe as a textstring.
*
* @return String. Description of the universe using no more than 400
* characters.
*/
public abstract String getDescription();
/* The description will be presented in the About dialog in 12 point
* sansserif on 360 pixel wide lines broken at nearest space.
* Explicit line breaks, '\n', are eliminated.
* Sample code for getDescription:
public String getDescription()
{return(sd);}
private String sd= // Description
" See the Lines Universe where two end points go straight, "+
"stepped in discrete steps until they bounce randomly "+
"against the edge of the window. Lines join the two end "+
"points for each step and the resulting patterns can be "+
"quite beautiful. ";
*/
/**
* Provides the name of the creator of the Universe as well as possibly
* the year of creation or other supplemental information.
*
* @return String. Name of Rartist, using no more than 24 characters.
*/
public abstract String getRartist();
/* Sample code for getRartist:
public String getRartist() {return("Jan Aminoff 1989");}
*/
// Section 2 What the universe does
// public abstract methods init, cycle, manageChange, and
// public getBackground
// ------------------------------------------------------------------------
/**
* Method used by the RartRunner class to initialize the universe.
* It is executed when the universe is executed the first time.
*/
public abstract void init();
/*
* The sample universes all have init() methods that allow restart using a
* reset() method, that follows a setParam() method taking care of
* of uParameters using default values or values given as HTML Applet tag
* parameters when run as applet or as command line parameters when run as
* an application.
* The reset() method may also be used if some parameter has changed and
* the reasonable way to manage the change is to restart the universe.
*/
/**
* The main cycle that is executed over and over to provide the animation.
* It uses the graphics context g to draw and redraw the screen.
*
* @param Graphics g The graphics context
*/
public abstract void cycle(Graphics g);
/*
* Normally, it is expected that g would be associated with an
* off screen image for double buffering. This results in the animation being
* smooth but requires some additional memory. If the redrawing is local
* and complex it may be preferrable to forgo double buffering and do the
* updating locally. The variable public boolean doublebuffer is set to
* true (see below) to request double buffering but has to be set to false
* if double buffering is not desired.
*
* cycle(g) is invoked periodically with the priod determined by the
* uParameter with the index CYCLETIME by the RartRunners.
* The Rartist provides anything that shows on the screen in the
* cycle(g) method. See the examples.
*/
/**
* Unified way of handling any observer initiated modifications through
* uParameters. The uParameter p provides the new current value.
*
* @param uParameter p The uParameter modified by the observer.
*/
public abstract void manageChange(uParameter p);
/* This is the method invoked by the RartRunners to inform the universe
* that the value of a uParameter has changed. p provides the new value.
* The following sample code from the Lines universe deals with change in
* the size of the window (uParameter index VIEWSIZE)and changes in the
* two parameters, "Number of Lines" (uParameter index NUMBER)and
* "Size/Speed" (uParameter index PARA4). The user can reset the color
* combinatins of forground background (uParameter index PARA5).
* Any changes to "Cycletime" (uParameter index CYCLETIME) in this case,
* and probably most cases, are handled by the RartRunner program.
* See also Section 3 below for the definition of the uParameters.
* See sample code from Lines for manageChange:
public void manageChange(uParameter uP){
int idx=uP.getIndex();
if (uPs[idx]!=null) uPs[idx]=uP; //ensures that uPs, the list of
// current parameters is up to date
switch (idx){
case VIEWSIZE:
//no problem since the points gravitate toward the middle
// but need to reset the screen and reinitialize
reset();
break;
case NUMBER:
number=uP;
reset();
break;
case PARA4: //used for speed or actually density
// do not need to reset here but need to reset max speed in
// the two EndPoint p1 and p2.
speed=uP;
vv=speed.getCur();
p1.setMaxSpeed(vv);
p2.setMaxSpeed(vv);
break;
case PARA5: // for new colorcombinations
colorcomb=uP;
reset();
break;
}
} // end manageChange
*/
/**
* Provides the default background color.
*
* @return Color background color
*
* NOTE: This method is provided for compatibility with some older
* universes. As of V 1.4 the universe provides any background
* color.
*/
public Color getBackground(){return Color.white;};
/* Provides your default background color. This method was changed from
* abstract to this one returning white, 000928. It maintains compatibility
* with existing older universes which overrides it when needed.
*
* The RartRunners were modified 000928 so that they do not color the back-
* ground. As of 000928 that responsibility has moved to the cycle() method
* of the universe.
*/
/* Section 3 uParameters as used in the universe
*
* The uParameters are the mechanism whereby the observer changes the
* universe within the limits set by the Rartist. There are up to 10
* parameters in a Rart universe. They are indexed with a parameter
* index from 1 through 10. (Parameter index UNIV is used
* within the RartRunners only)
*/
// ------------------------------------------------------------------------
public static final int NUMBER_OF_PARAMETERS = 10;
// uParameter indicies are named according to anticipated use:
public static final int UNIV=0; // Used to communicate within RRs
public static final int VIEWSIZE=1; // Used for size of window
public static final int CYCLETIME=2; // Used for cycletime
public static final int NUMBER=3; // Used for number of objects
public static final int PARA4=4;
public static final int PARA5=5;
public static final int PARA6=6;
public static final int PARA7=7;
public static final int PARA8=8;
public static final int PARA9=9;
// to allow setting of the parameters we also need the index as string
public static final String indexes[]={"UNIV","VIEWSIZE","CYCLETIME",
"NUMBER","PARA4","PARA5","PARA6","PARA7","PARA8","PARA9"};
/**
* used to get the string associated with the uParameter index
*
* @param index One of the indeces UNIV . . . PARA9
* @return String The string coresponding to the index "UNIV" . . . "PARA9"
*/
public static String getIndex(int index){
return indexes[index];
}
/*
* The array of all uParameters, the value of undefined uParameters is NULL
*/
public uParameter uPs[] = new uParameter[NUMBER_OF_PARAMETERS];
/**
* The array of all uParameters for the universe is available to the
* RartRunners thhrough this method.
*
* @return uParameter[] the array of uParameters
*/
public uParameter[] getuParameters(){
return uPs;
}
/*
*
* Sample code about parameters: Each uParameter has to be declared and set.
* The sample code includes the initial declaration of the parameters,
* and the code to set or reset them in init(). The sample code is from the
* Lines universe where the settings are collected in the setParam() method.
*
private uParameter number; // Number of lines requested - PARAMETER
private int nn_min=2,nn_cur=150; // nn_max is a static variable
private int nn=nn_cur; //actual number of lines
private String ndescr=
"This parameter indicates the number of 'Lines' on the "+
"screen at any one time. The number of visible lines remains "+
"constant after initial growth to the maximum.";
// max speed of any EndPoint in x or y direction - PARAMETER
private uParameter speed;
private int vv=12,vv_max=20,vv_min=1;
private String sdescr=
"The 'Speed' is the maximum speed in pixels in the x or the y "+
"directions. Higher speeds tend to give a clutterd look.";
// colorcombinations of linecolor on background color - PARAMETER
private uParameter colorcomb;
private String ccdescr=
"Select line colors against a background from one of the following: "+
"Black lines on white background, white lines on black, or lines "+
"whose color is stepped through 26 shades of color against a "+
"background selected from the thirteen primary Java colors.";
static String colornames[]={ " Black on White", " White on Black",
" Black background"," Blue background"," Cyan background",
" Dark grey background", " Grey background",
" Green background"," Light grey background"," Magenta background",
" Orange background", " Pink background"," Red background",
" White background"," Yellow background"};
static Color colors[]= // Standard Java Colors
{Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,
Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,
Color.red,Color.white,Color.yellow };
// cycletime is set here but otherwise handled in the rartrunners
private uParameter cycletime;
private void setParams(){
number= new uParameter
(NUMBER,"Number of Lines",nn_min,nn_cur,nn_max,ndescr);
// The adduParameter() method is defined in Universe
adduParameter(number);
speed=new uParameter(PARA4,"Speed",vv_min,vv, vv_max, sdescr);
adduParameter(speed);
colorcomb = new uParameter
(PARA5,"Color Combination",cc,colornames, ccdescr);
adduParameter(colorcomb);
// Since "Cycle Time" is a compulsory parameter, Universe actually
// provides the description
cycletime= new uParameter(CYCLETIME,"Cycle Time", 10,25,100, CycleTimeDescr);
adduParameter(cycletime);
} // end of setParams
*/
protected static final String CycleTimeDescr =
"If you have a really fast computer/browser/Java combination "+
"you can let the universe execute at the higest speed or, which is "+
"the same thing, the shortest cycle time. But if your equipment/ "+
"software is slow, you may not see much difference. Try it out! ";
public void adduParameter( uParameter p){
if (p.getIndex()<uPs.length)
uPs[p.getIndex()]=p;
}
// Section 4 Utility Methods
/* The following methods are useful in developing Rart universes
* The simple forms occuring here can be overridden or replaced by
* more complex forms if desired.
* RND, SIGN, and ABS provide a unified way to describe randomness
* printString is used for standardized output of text
* getImageFileName and getSoundFileName are used to provide the names
* of the files of images or sounds to be displayed
*/
/**
* RND - returns a pseudorandom value noless than 0 and less than
* x if x is non negative and a pseudorandom value greater than x
* and no greater than 0 if x is non postitive (CF Quickbasic RND)
*
* @param x any integer
* @return pseudorandom value
*/
public static int RND(int x){
/* See an excellent discussion of random number generators in
* JDC Tech Tips September 25, 2001.
*/
return (SIGN(x)*((int)( Math.random()*ABS(x))));
}
/**
* returns signum(x)
*
* @param x any integer
* @return 1 if x>0, -1 if x<0 and 0 if x equals 0
*/
public static int SIGN(int x){
return ((x>0)? 1:(x<0)? -1:0);
}
/**
* returns absolute value of x
*
* @param x any integer
* @return -x if x<0, otherwise x
*/
public static int ABS(int x){
return ((x>0)? x: -x);
}
/**
* The printString method is used to provide text output within a universe.
* The text is rendered on the screen in blue bold proportional sans serif
* font stating at x,y and in fontsize as desired. The method assumes that
* you do your own partitioning of a multiline string by providing
* explicit line breaks "\n". It may be invoked in the cycle method to
* provide output in a standardized way.
*
* @param Graphics g presumably the g provided in the cycle metod
* @param String st the string to be output; can be multiline with
* explicit line breaks "\n"
* @param x,y starting coordinates for the rendered string
* @param fontSize size of font in points
*/
public static void printString
(Graphics g, String st, int x, int y, int fontSize){
String s=st;
int i=1, ln=0;
Font font = new Font("SansSerif", Font.BOLD, fontSize);
g.setFont(font);
g.setColor(Color.blue);
while (i>0){
i=s.indexOf("\n",0);
if (i>1){
g.drawString(s.substring(0,i), x, y+ln*(fontSize+2));
s=s.substring(i+1,s.length());
ln++;
}else g.drawString( s, x, y+ln*(fontSize+2) );
}
} // end printString
// Handling of resources
/*
* When a universe is executing in an applet environment, the RartRunner
* has to request any files that are needed. Accordingly the universe
* itself has to inform the RartRunner by giving the filenames of all
* resource files by redefining the reFileNames array of filenames which
* is initiated in Universe as a one element array with the value null.
* The RartRunner calls getreFileNames and works through the array of
* resource files, each one of which may be either a textfile, an image,
* or a soundclip, identified for now by file extensions txt, gif, or au,
* respectively. The loaded resources are made available to the universe
* by the RartRunner executing the setResourceObject method which provides
* the loaded resources as an array of objects. It is up to the universe
* to deal with each object appropriately, which includes casting the
* the object to the resource actually used.
*/
/**
* This method is invoked by the RartRunner immidiatly after the execution
* of the init method of the universe. If the universe
* requires one ore more resource files, the protected String array
* reFileNames should be set by the universe to the names of the required
* resourcefiles. Otherwise and as soon as the files have been sucessfully
* loaded, the imageFileNames should be set to contain only one element with
* the value null.
*
* @return String reFileNames set in init
*/
public String[] getreFileNames(){
return reFileNames;
}
protected String[] reFileNames = null;
/**
* This method is used by the RartRunner to make resources, requested
* by the universe in getreFileNAmes available in the resourseObjects
* array. Note that the universe has to process the resource, in
* particular, casting it to the actual resource (text, image etc).
* The requsted objects loaded in the order indicated by the reFileNames
* array. If the loading was unsucessful for any reason, the corresponding
* object has the value null.
*
* Note: The loading of the resources takes place after the execution of
* the init method of universe. This means that the processing of the
* resource has to take place in the cycle method as a second initiation
* probably unrelated to any reset. See examples, in particular the Three
* Balls universe.
*
* @param Object[] os the requested resource objects loaded from the file
* reFileNames if successful, otherwise null
*/
public void setResourceObjects( Object[] os){
resourceObjects = os;
reFileNames =null;
}
protected Object[] resourceObjects = null;
// Section 5 Useful variables related to the execution of a universe
// -------------------------------------------------------------------------
/*
* The number of executions as public int nc, (nc is stepped
* after each cycle up to 2000000 when it is reset to avoid overflow).
* The size of the display window is available to the universe as
* protected Dimension dimDisplay, and as the public xm, for width,
* and ym, for height.
*
*/
public static int nc; // Set in the RartRunner. Used to vary the
// universe according to the number of cycles executed.
public static boolean doubleBuffer=true; //set this false in your universe
// overriding this setting if you don't want double buffering.
public static boolean needSound=false; //This variable set to true when a
// universe needs a sound. Soundclip file reference has to be
// provided in HTML startup. Only one sound in this realease.
public static int debugLevel; // Set by the RartRunner to the value of the
// parameter DEBUG_LEVEL provided as either a command-line
// parameter (for a RartRunner application) or as an HTML
// parameter (for a RartRunner applet). Override if necessary.
/**
* The simplest way for the universe to get access to the resources of
* the RartRunner is to provide the invoking RartRunner instance. This
* is done immidiately before the RartRunner initiates the universe
* using the init of the Universe, which means that init has available
* whatever the RartRunner can provide.
*
* Introduced in Nov 2001 to allow direct access to the awt peer of the
* RartRunner for the purpose of Image processiong.
*
* Since Nov 2001,
*/
public final void setRartRunner(RR rr){
rartrunner = rr;
System.out.println("setRartRunner rartrunner "+rr);
}
protected RR rartrunner = null;
/**
* This method is used by the RartRunners to communicate the current size
* of the display, either as Dimension dimDisplay or the two variables xm, ym.
*
* @param Dimension d the current size of the display
*/
public final void setExtents(Dimension d){
xm=d.width;
ym=d.height;
if (dimDisplay.width == 0){
//dB= new Debug(); requires "private Debug dB;"
//dB.setLevel(2);
dimDisplay.width = xm;
dimDisplay.height = ym;
//dB.dbg( 2,"In Universe.setExtent(Initially):xm,ym "+xm+", "+ym );
}else{
uParameter sizeUP = new uParameter(VIEWSIZE, "VIEWSIZE", xm, ym, 0);
//dB.dbg( 2,"In Universe.setExtent(Running):xm,ym "+xm+", "+ym );
manageChange(sizeUP);
}
} // end setExtents
protected Dimension dimDisplay = new Dimension(0,0);
public static int xm,ym; // Width and height of window; reset as needed
//by the RartRunner. uParameter, index VIEWSIZE, announces change.
// Section 6 Methods related to security.
// The following methods should normally be of no concern to programmers of
// a Rart universes.
/**
* Constructor with only function to avoid having more than one instantiation
* at a time. Compare Finalizer Method
*/
public Universe() throws InstantiationException{
if (true == instantiated)
throw new InstantiationException("A Universe exists alreay.");
instantiated = true;
System.out.println("Universe Version 1.4 instantiated");
}
private static boolean instantiated = false;
public boolean equals(Object o) {
return false;
}
protected Object clone()
throws CloneNotSupportedException{
throw new CloneNotSupportedException("A Universe exists already.");
}
public void finalize(){
instantiated = false;
}
} // End of abstract class Universe