This document explains how to create
and extend existing classes in the Grid Package. It is
recommended that you read the general overview document, Using
the Grid Package before reading this
document.
You may also wish to read Understanding the Display Component Classes if
you plan to implement your own display classes.
Sections:
A GridObject
is the basis for any object that
can be placed in the
Grid
. A diagram of the structure of the GridObject
hierarchy can
be found in the Components
for modeling objects in a grid section of
Using the Grid Package.
The standard
GridObject
has very little internal
information and
may be of limited use. It contains only the location of the
object.
The three subclasses of GridObject
provided with the
package, TextCell
ColorBlock
, and
PictureBlock
, have some
additional functionality. If further functionality is desired
it is
very simple to subclass GridObject
. It is
important to
remember
that a new GridObject
subclass is not needed just to
change
the image that
is displayed in the grid, because that information is handled by the
DisplayMap
and the display classes as described in the two
previous documents.
If you were want to run a model of people you could simply use a
GridObject
and associate an image of a generic person for
the
display, however
this would not be very useful for an interesting simulation. It
would
make more sense to subclass GridObject
to create a Person.
The
Person
class could then keep track of properties such as age, name, etc.
The following code is the partial implementation of a simple person
object:
// Class: Person /** Construcs a new Person object } Code
Sample 1 |
bodyColor
will be the
most important aspect of the Person.GridFish
,
SlowFish
, and
DarterFish
classes which
are implementations of the corresponding classes from the AP®
Marine Biology Simulation (MBS) case study.
The
source for the fish and three running simulations are located here: GridFish.java
,
SlowFish.java
,
DarterFish.java
,
MBS.java
,
SimpleMBSDemo1.java
,
SimpleMBSDemo2.java
.ScaledImageDisplay
, but that
would not allow us to take advantage ot the bodyColor of the Person.
// Class:
PersonDisplay// // Author: Joel Booth // based on the PatientDisplay class written by Alyce Brady // // // Created on 9 November 2004 // // License Information: // This class is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation. // // This class is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. import java.awt.Color; import java.awt.Component; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import edu.kzoo.grid.GridObject; import edu.kzoo.grid.display.ScaledDisplay; /** * @author Joel Booth * @version 9 November 2004 **/ public class PersonDisplay extends ScaledDisplay { private static final double HEAD_DIAMETER = .20; private Shape head; private Shape body; private Shape arms; private Shape leftLeg; private Shape rightLeg; /** Constructs an object that knows how to draw a patient. **/ public PersonDisplay() { buildPaths(HEAD_DIAMETER); } /** Sets up the paths used for the patient body, head, arms, and legs. * The various parameters should be specified assuming the patient * will occupy a cell of size (1, 1). * @param headDiameter circumference of the head **/ protected void buildPaths(double headDiameter) { // Build a set of paths for a patient standing in a unit-length cell. // We will scale as needed later. // The head is a circle (ellipse, actually) of the given diameter. head = new Ellipse2D.Double(-headDiameter/2, -3 * headDiameter/2, headDiameter, headDiameter); // The patient body starts below the head. double bodyLength = 3 * headDiameter; double combinedArmLength = 2 * bodyLength / 3; body = new Line2D.Double(0, -bodyLength/6, 0, bodyLength/6); arms = new Line2D.Double(-combinedArmLength/2, 0, combinedArmLength/2, 0); leftLeg = new Line2D.Double(0, bodyLength/6, -bodyLength/4, bodyLength/2); rightLeg = new Line2D.Double(0, bodyLength/6, bodyLength/4, bodyLength/2); } /** Draws the given object as a stick figure; the object must be of * the Patient class. * (Precondition: <code>obj</code> is a <code>Patient</code> object.) * @param p patient we want to draw * @param comp component on which to draw * @param g2 drawing surface **/ public void draw(GridObject p, Component comp, Graphics2D g2) { Person person = (Person) p; // Set the color based on the person's body color Color color = person.getBodyColor(); g2.setPaint(color); // Draw head g2.draw(head); g2.fill(head); // Stroke stick figure in slightly darker color. g2.setPaint(color.darker()); g2.draw(body); g2.draw(arms); g2.draw(leftLeg); g2.draw(rightLeg); } }
|
/** Constructs an object that knows how to draw a patient.
**/ public PersonDisplay() { buildPaths(HEAD_DIAMETER); }
|
...
import java.awt.Shape; ... private Shape head; private Shape body; private Shape arms; private Shape leftLeg; private Shape rightLeg; ...
Code
Sample 4 |
/** Sets up the paths used for the patient body, head, arms, and legs.
* The various parameters should be specified assuming the patient * will occupy a cell of size (1, 1). * @param headDiameter circumference of the head **/ protected void buildPaths(double headDiameter) { // Build a set of paths for a patient standing in a unit-length cell. // We will scale as needed later. // The head is a circle (ellipse, actually) of the given diameter. head = new Ellipse2D.Double(-headDiameter/2, -3 * headDiameter/2, headDiameter, headDiameter); // The patient body starts below the head. double bodyLength = 3 * headDiameter; double combinedArmLength = 2 * bodyLength / 3; body = new Line2D.Double(0, -bodyLength/6, 0, bodyLength/6); arms = new Line2D.Double(-combinedArmLength/2, 0, combinedArmLength/2, 0); leftLeg = new Line2D.Double(0, bodyLength/6, -bodyLength/4, bodyLength/2); rightLeg = new Line2D.Double(0, bodyLength/6, bodyLength/4, bodyLength/2); }
|
/** Draws the given object as a stick figure; the object must be of * the Patient class. * (Precondition: <code>obj</code> is a <code>Patient</code> object.) * @param p patient we want to draw * @param comp component on which to draw * @param g2 drawing surface **/ public void draw(GridObject p, Component comp, Graphics2D g2) { Person person = (Person) p; // Set the color based on the person's body color Color color = person.getBodyColor(); g2.setPaint(color); // Draw head g2.draw(head); g2.fill(head); // Stroke stick figure in slightly darker color. g2.setPaint(color.darker()); g2.draw(body); g2.draw(arms); g2.draw(leftLeg); g2.draw(rightLeg); }
|
PersonDisplay
can be found here: PersonDisplay.java
// Class:
PersonTest
// // Author: Joel Booth // // License Information: // This class is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation. // // This class is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. import java.awt.Color; import edu.kzoo.grid.ColorBlock; import edu.kzoo.grid.BoundedGrid; import edu.kzoo.grid.Grid; import edu.kzoo.grid.Location; import edu.kzoo.grid.TextCell; import edu.kzoo.grid.display.DisplayMap; import edu.kzoo.grid.gui.GridAppFrame; import edu.kzoo.util.NamedColor; /** * @author Joel Booth * @version 9 November 2004 **/ public class PersonTest { /** * Start the Test program. * The String arguments (args) are not used in this application. **/ public static void main(String[] args) { String TITLE = "Person Test"; Color BACKGROUND_COLOR = Color.WHITE; int MAX_WIDTH = 500; // in pixels int MAX_HEIGHT = 500; // in pixels int MIN_CELL_SIZE = 50; // in pixels // Construct a window to display a grid. GridAppFrame gui = new GridAppFrame(); gui.constructWindowContents(TITLE, BACKGROUND_COLOR, MAX_WIDTH, MAX_HEIGHT, MIN_CELL_SIZE); // Specify how to display color blocks. DisplayMap.associate("Person", new PersonDisplay()); // Construct a grid in which to draw. Grid grid = new BoundedGrid(10, 10); gui.setGrid(grid); // Add 3 people to the grid grid.add(new Person(), new Location(2, 2)); grid.add(new Person(NamedColor.MIDNIGHT), new Location(3, 5)); grid.add(new Person(NamedColor.MAGENTA), new Location(7, 7)); // Display the grid. gui.showGrid(); } }
Code
Sample 7 |
Figure 1 |