GUIModel.java
From Santa Fe Institute Events Wiki
/*
* GUIModel.java * * Created on January 30, 2005, 12:21 PM * Modified June 14, 2006 * This runs the graphical interface for the CoopNetBlue model */
package CoopNetBlue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Formatter; import java.util.HashSet;
import uchicago.src.sim.engine.Schedule; import uchicago.src.sim.engine.SimModelImpl; import uchicago.src.sim.engine.*; import uchicago.src.sim.util.*; import uchicago.src.sim.gui.*; import uchicago.src.sim.gui.ColorMap; import uchicago.src.sim.gui.DisplaySurface; import uchicago.src.sim.gui.Object2DDisplay; import uchicago.src.sim.gui.Value2DDisplay; import uchicago.src.sim.space.Object2DTorus; import uchicago.src.sim.engine.AbstractGUIController; import uchicago.src.sim.analysis.*;
/**
* * @author Jack Waddell */
public class GUIModel extends CoopNetBlue{
//******************************************************* // Instance Parameters
// The actual display surface, where things are put on the screen private DisplaySurface surface; // A layout, which tells the surface where to put nodes and edges private AbstractGraphLayout layout;
// A graph private OpenSequenceGraph utilityGraph;
// A plot private Plot histPlot;
// A Histogram private OpenHistogram wealthHist;
// A Histogram private OpenHistogram degreeHist; //******************************************************************* // Methods ///////////////////////////////////////////////////////////////////// // setup // // This runs automatically when the model starts // and when you click the reload button, to "tear down" any // existing display objects, and get ready to initialize // them at the start of the next 'run'. // public void setup() {
// the super class does conceptual-model setup (CoopNetBlue) super.setup();
if ( rDebug > 0 ) System.out.printf( "<== GUIModel setup() begin.\n" );
// NOTE: you may want to set these next two to 'true' // if you are on a windows machine. that would tell repast // to by default send System.out and .err output to // a special repast output window. AbstractGUIController.CONSOLE_ERR = false; AbstractGUIController.CONSOLE_OUT = false;
// For restart purposes, dispose of any displays
if ( surface != null ) surface.dispose();
if ( utilityGraph != null ) utilityGraph.dispose();
if ( wealthHist != null) wealthHist.dispose();
if ( degreeHist != null) degreeHist.dispose();
// Create and register the abstract surface surface = null; surface = new DisplaySurface( this, "Network Display" ); registerDisplaySurface( "Main Display", surface );
// Add Custom Buttons
modelManipulator.init();
modelManipulator.addButton("Layout - Circular",
new ActionListener(){
public void actionPerformed(ActionEvent evt){
changeLayoutCircular();
}
}
);
modelManipulator.addButton("Layout - Kamada",
new ActionListener(){
public void actionPerformed(ActionEvent evt){
changeLayoutKamada();
}
}
);
modelManipulator.addButton("Print Nodes",
new ActionListener(){
public void actionPerformed(ActionEvent evt){
printNodes();
}
}
);
modelManipulator.addButton("Kill All Edges", new ActionListener(){ public void actionPerformed(ActionEvent evt){ killAllEdges(); } } );
if ( rDebug > 0 )
System.out.printf( "<== GUIModel setup() done.\n" );
}
///////////////////////////////////////////////////////////////////// // begin // // This runs when you click the "initialize" button // (the button with the single arrow that goes around in a circle) // or at the first step public void begin() {
DMSG(1, "==> enter GUIModel-begin()" ); // Set up drawables CustomNode.setUpNodeDrawing(this); CustomEdge.setUpEdgeDrawing(this);
buildModel(); // Calls in the base model (CoopNetBlue)
buildDisplay(); // Constructs the displays if (rDebug > 0) System.out.printf("Display Built Successfully. \n");
// Constructs the schedule; If defined in GUIModel, ignores buildSchedule in base model buildSchedule();
surface.display(); // displays the surface on the display
writeHeaderCommentsToReportFile();
DMSG(1, "<== leave GUIModel-begin() done." );
} ///////////////////////////////////////////////////////////////////// // buildDisplay // // builds the display and display related things // public void buildDisplay() {
if ( rDebug > 0 ) System.out.printf( "==> GUIModel buildDisplay...\n" );
// Layout specifies the arrangement of nodes and edges // This specifically uses the Kamada-Kawai method layout = new KamadaGraphLayout(agentList, worldXSize, worldYSize); Network2DDisplay display = new Network2DDisplay(layout);
layout.updateLayout(); // actually execute the laying out
// Register the layout with the display surface for drawing surface.addDisplayableProbeable(display, "Network Display"); surface.addZoomable (display); surface.setBackground (java.awt.Color.black);
addSimEventListener (surface);
// Makes a graph utilityGraph = new OpenSequenceGraph("Utility", this); // constructs graph utilityGraph.setXRange(0, 200000); // sets ranges utilityGraph.setYRange(-1.1, 1.1); utilityGraph.setAxisTitles("time", "utility"); // sets axis lables
// This generates a sequence, which is read into the graph // To generalize, change sequence class name, and what it returns class utilitySequence implements Sequence { public double getSValue(){ return calcAvgUtility(); } }
// Add the above sequence to the graph. // You can add several sequences to plot simultaneously utilityGraph.addSequence("Ave Utility", new utilitySequence()); // Display the graph. It will need to be updated in Step utilityGraph.display();
// Generate a histogram of agent wealth
wealthHist = new OpenHistogram("Agent Wealth Distribution", 10, 0);
wealthHist.setYRange(0, 100.0);
BinDataSource histSource = new BinDataSource(){
public double getBinValue(Object o){
CustomNode node = (CustomNode) o;
return node.getUtility();
}
};
wealthHist.createHistogramItem("Wealth", agentList, histSource); wealthHist.display();
// Generate a histogram of agent degree
degreeHist = new OpenHistogram("Agent Degree Distribution", 10, 0);
degreeHist.setYRange(0, 100.0);
BinDataSource degreeSource = new BinDataSource(){
public double getBinValue(Object o){
CustomNode node = (CustomNode) o;
return node.getDegree();
}
};
degreeHist.createHistogramItem("Degree", agentList, degreeSource); degreeHist.display();
} //////////////////////////////////////////////////////////////// // buildSchedule // Adds to buildSchedule in main model // Note, model-type changes should also be included in // batchmodel's buildSchedule if one wants to ever run in batch public void buildSchedule() {
schedule = new Schedule(1); super.buildSchedule(); // Get base model schedule
schedule.scheduleActionAtInterval(evolveUpdateInterval, new BasicAction() { public void execute() { degreeHist.step(); // evolve agents } }, Schedule.LAST);
}
////////////////////////////////////////////////////////////////// // step // // Ask the super-class (CoopNetBlue) to do its step() method, // and then this does display related activities. public void step() {
super.step(); // the base model does whatever it does
// add things after this for all displays (graphs, etc) surface.updateDisplay(); utilityGraph.step(); wealthHist.step();
} ////////////////////////////////////////////////////////////////// // processEndOfRun // called once, at end of run. public void processEndOfRun ( ) {
long finalStep = (long) schedule.getCurrentTime(); if ( rDebug > 0 ) System.out.printf("\n\n===== GUIModel processEndOfRun =====\n\n" ); applyAnyStoredChanges(); endReportFile(finalStep); this.fireStopSim();
}
///////////////////////////////////////////////////////////// // addAgent // Input: CustomNode agent // Output: none // Adds a new agent to the agent list public void addAgent(CustomNode agent){
super.addAgent(agent); updateLayoutAgentList();
}
///////////////////////////////////////////////////////////// // delAgent // Input: CustomNode agent // Output: none // Deletes an agent from the agent list public void delAgent(CustomNode agent){
super.delAgent(agent); updateLayoutAgentList();
}
//////////////////////////////////////////////////////////// // updateLayoutAgentList // Input: none // Output: none // Update layout's agentList. Model's agentlist // is updated with gm's (since they both point to // the same object). Layout is dumb, and evidently // re-stores pointers to objects in list, rather than // the list. public void updateLayoutAgentList(){
layout.setList(agentList); // update the layout, re-executing layout method (e.g. Kamada) layout.updateLayout();
}
/////////////////////////////////////////////////////////////////// // changeLayoutCircular // Uses circular rather than Kamada layout public void changeLayoutCircular(){ layout = new CircularGraphLayout(agentList, worldXSize, worldYSize);
layout.updateLayout();
} /////////////////////////////////////////////////////////////////// // changeLayoutKamada // Uses kamada-kawai layout, rather than circular public void changeLayoutKamada(){
layout = new KamadaGraphLayout(agentList, worldXSize, worldYSize); layout.updateLayout();
} /////////////////////////////////////////////////////////////////// // printNodes // print node properties to terminal window // Mainly used for debugging public void printNodes(){
System.out.printf("\nAt time = %f\n", schedule.getCurrentTimeDouble()); for(int i = 0; i < agentList.size(); i++){ CustomNode aNode = (CustomNode) agentList.get(i); String s = String.format("#%d has %d bucks with strategy %1.3f.\n", aNode.getID(), aNode.getUtility(), aNode.getStrategy());
System.out.printf(s); } System.out.printf("\n");
}
////////////////////////////////////////////////////////////////////// // killAllEdges // deletes all edges // Mainly used for debugging, or being a bastard public void killAllEdges(){
for(int i = 0; i < agentList.size(); i++){ CustomNode node = (CustomNode) agentList.get(i); node.clearInEdges(); node.clearOutEdges(); }
} ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// // **** NO NEEd TO CHANGE THE REST OF THIS ***** //////////////////////////////////////////////////////////////////// // main entry point public static void main( String[] args ) {
uchicago.src.sim.engine.SimInit init = new uchicago.src.sim.engine.SimInit(); GUIModel model = new GUIModel();
//System.out.printf("==> GUIMOdel main...\n" );
// set the type of model class, this is necessary // so the parameters object knows whether or not // to do GUI related updates of panels,etc when a // parameter is changed model.setModelType("GUIModel");
// Do this to set the Update Probes option to true in the // Repast Actions panel Controller.UPDATE_PROBES = true;
model.setCommandLineArgs( args ); init.loadModel( model, null, false ); // does setup()
// this new function calls ProbeUtilities.updateProbePanels() and // ProbeUtilities.updateModelProbePanel() model.updateAllProbePanels();
} /** Creates a new instance of GUIModel */ public GUIModel() { }
}