Recursive Porus Agent Simulation Toolkit
java MyClass.class to start an
application, must implement the main method. The main method has
the following signature public static void main(String[]
args). If you wish your model to be executable then you
need to implement this method in your code. The method itself
will look something like:
public static void main(String[] args) {
SimInit init = new SimInit();
HeatBugsModel model = new HeatBugsModel();
init.loadModel(model, null, false);
}
This code creates an instance of the SimInit class (the same
class with which you can load your models on the command line),
and instance of the model itself. It then uses SimInit to load
the model via the loadModel method. The second and third
parameters of the loadModel method specify a parameter file and
whether or not the model is a batch model. You can either pass
values to these parameters via the args array or if you know
that this model is a batch model, you can specify the method
parameters directly. The following is an example of the later.
public static void main(String[] args) {
SimInit init = new SimInit();
EnnBatchModel model = new EnnBatchModel();
init.loadModel(model, "./EnnParams.txt", true);
}
This code snippet is from EnnBatchModel.java in the enn demo
(see repast/demo/enn). Here we create an instance of SimInit and
the model as above. We then pass a parameter file path and a
value of true to the second and third arguments of the loadModel
method. With these parameters SimInit would load EnnBatchModel
in batch mode, and read the parameters from the EnnParams.txt
file.
If you wish to parse the arguments in the args parameter of the main method and pass them to the loadModel, the following shoudl help. For a command line of:
java -cp c:\repast\lib\repast.jar;. MyModel param.pf true
args[0] = param.pf and args[1] = true. And knowing this it
should not be hard to parse args[] and extract the appropriate
values to pass to the loadModel method.
Main-Class: uchicago.src.sim.heatBugs.HeatBugsModel
Class-Path: ../../lib/repast.jar ../../lib/trove.jar ../../lib/colt.jar
../../lib/jgl3.1.0.jar ../../lib/excelaccessor_Runtime.jar ../../lib/jmf.jar
../../lib/jcchart.jar ../../lib/junit.jar ../../lib/plot.jar
../../lib/xerces.jar
The Class-Path:entries should all be one line. Here
the main class is uchicago.src.sim.heatBugs.HeatBugsModel and it
requires the specified classpath in order to execute correctly.
The class path is space delimited here, and the paths of the jar
files are defined relative to the bugs.jar file. In this case
two directories above the repast/demo/bugs directory in the
repast/lib directory. With this manifest file in the bugs.jar
archive, we execute the heatbugs simulation with java -jar
bugs.jar. This has the added benefit of making the jar
file executable when double click under windows. Given the above
manifest file, this is directly equivalent to:
java -cp ./bugs.jar;../../lib/repast.jar;../../lib/trove.jar;
../../lib/colt.jar; ../../lib/jgl3.1.0.jar;
../../lib/excelaccessor_Runtime.jar;../../lib/jmf.jar;
../../lib/jcchart.jar;../../lib/junit.jar;../../lib/plot.jar;
../../lib/xerces.jar uchicago.src.sim.heatBugs.HeatBugsModel
(Note that as of Repast v.1.3, you no longer start models this
way. repast.jar itself contains a manifest file that specifies a
classpath containing all the other required jar files. So
instead of the above, you can do java -cp
./bugs.jar;../../lib/repast.jar
uchicago.src.sim.heatBugs.HeatBugsModel.)
Once you've written your manifest file, you need to include it in your jar. If you haven't yet created your jar file, you can do this all in one step with the 'jar' utility that comes with the java development kit.
jar cfvm my_model.jar mymanifest my_model_dir
where my_model.jar is the name of the jar file you are creating,
mymanifest is the manifest file you've created and
my_model_dir is the directory for your actual model. So for
heatbugs this looks like:
jar cfvm bugs.jar bugs_manifest uchicago/src/sim/heatBugs
If your model is in a package (as it should be) its important to
jar it from the directory above the first package directory. In
the heatbugs case I would run the jar command from the directory
in which the uchicago directory resided.
If you already have your classes in a jar file and just want to add the manifest file, replace the 'c' in the above command with a 'u'.
You can inspect the contents of your jar file with jar
-tf name_of_jar_file. Your manifest won't be
included in the jar itself as its contents are actually
copied into the MANIFEST.MF file.
For more information run the jar utility with no arguments and see Sun's jar tutorial
public void
stop()and public void pause. You can call
these methods from within the model to stop or pause it. Like
any other public method, this methods are schedulable so you can
schedule your model to pause (or stop) at particular intervals
or at specified ticks. For example,
int pauseTick = -1;
...
private void buildSchedule() {
schedule.scheduleActionAt(pauseTick, this, "pause", Schedule.LAST);
...
}
public void setPauseTick(int val) {
pauseTick = val;
schedule.scheduleActionAt(pauseTick, this, "pause", Schedule.LAST);
}
public int getPauseTick() {
return pauseTick;
}
will allow you to schedule pauses through the gui.
CustomProbeableinterface only those parameters
whose names are returned in the String[] from
CustomProbeable.getProbedProperties()will be
displayed. For example,
public class MyAgent implements CustomProbeable {
private int age;
...
public int getAge() {
return age;
}
public void setAge(int val) {
age = val;
}
public String[] getProbedProperties() {
return new String[] {"Age"};
}
}
When probed MyAgent classes will now only display the
"Age" parameter.
public void setup() {
...
Controller c = (Controller)this.getController();
c.addButton("Help", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
showHelp();
}
});
}
Controller has three new methods for adding custom buttons to
the toolbar. Using the addButton methods you can add a JButton
directly, specify a label and an ActionListener, or specify the
path to an Icon and an ActionListener. The above code snippet
will add new a JButton with the label "Help" to the
toolbar and call the showHelp method whenever it is clicked. You
must add new buttons in your model's setup() method
otherwise they will not appear in the toolbar.
If you don't understand how to work with JButtons, and ActionListeners, you should learn a bit about the Java's Swing gui toolkit before adding custom buttons to the toolbar.
Controller c = (Controller)this.getController();
c.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_K) {
System.out.println("k key typed");
}
}
});
will print "k key typed" to the console whenever the
toolbar (i.e. the Controller) has focus and the "k"
key is pressed. To perform the same action when a DisplaySurface
has focus, you'd replace the reference to the Controller
with one to your DisplaySurface. So,
myDisplaySurface.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_K) {
System.out.println("k key typed");
}
}
});
Typically you place this sort code to the setup() method in your
model. This ensures that you can listener for key events before
your simluation begins to run. Note that KeyAdapter and KeyEvent
are in the java.awt.event package, so you'll have to import
them into your model. Adding KeyListeners in this way is
standard Java and any Java book can provide more details.
Controller c = (Controller)this.getController();
c.addStartListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("start");
}
});
This code listens for start button clicks and prints
"start" to the console whenever a start button click
occurs. Each button has its own add listener method so
addStopListener will add code for execution on stop button
clicks, addPauseListener for pause button clicks and so on. If
you wish to know which button has been clicked (assuming
you've got the same listener listening to more than one
button), the button's actionCommand reports the buttons
name. For example, the code
Controller c = (Controller)this.getController();
c.addStartListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
javax.swing.JButton b = (javax.swing.JButton)evt.getSource();
System.out.println(b.getActionCommand());
}
});
will print "start", the Start button's action
command, to the console. The exit button's action command is
"exit", pause is "pause" and so on. Adding
listeners to buttons in this way is standard Java and any good
book on Java can tell you more.
You can update an Object's probe panel using ProbeUtilities.updateProbePanel(Object object) method. The object here is the object whose probe panel you wish to update. So, for example, we could implement the above scenario where a change to parameter X, changed the value of parameter y and we want the parameter (probe) window to display the new value of y, as follows:
public void setX(int val) {
x = val;
setY(val / 2);
ProbeUtilities.updateProbePanel(this);
}
public void setY(int val) {
y = val;
}
...
This is also useful for turning various exclusive boolean
switches on and off in response to others being set on.
See the API documentation for the ProbeUtilities class for more.
Controller.UPDATE_PROBES = true;
This will update all probes except for that on the model. To
update the model probe, you'll have to call
ProbeUtilities.updateModelProbePanel. Updating the
model's probe is computationally expensive.
Note that updating probes will slow down your model although considerably less in java 1.4 vs. previous version of java.
System.out) and stderr
(errors written to System.err) can be redirected to
The Repast Console. The Repast Console can be turned on or off
via the GUI and in code. To turn it on/off via the GUI, switch
to the Repast actions tab panel and click on "Stdout to
Console" or "Stderr to Console" to either one on
or off. Note that if they are both off then the Repast Console
will not appear. To do this in code, you need to set the flags
AbstractGUIController.CONSOLE_OUT and
AbstractGUIController.CONSOLE_ERR. For example,
AbstractGUIController.CONSOLE_ERR = false;
AbstractGUIController.CONSOLE_OUT = false;
You can do this in the constructor of your model.