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() {
}
}
