/** ** SleuthWorldWithUI.java ** ** Copyright 2011 by Sarah Wise, Mark Coletti, Andrew Crooks, and ** George Mason University. ** ** Licensed under the Academic Free License version 3.0 ** ** See the file "LICENSE" for more information ** ** $Id$ **/ package sim.app.geo.sleuth; import java.awt.Color; import javax.swing.JFrame; import org.jfree.data.xy.XYSeries; import sim.display.Console; import sim.display.Controller; import sim.display.Display2D; import sim.display.GUIState; import sim.engine.SimState; import sim.engine.Steppable; import sim.portrayal.grid.ObjectGridPortrayal2D; import sim.util.gui.ColorMap; import sim.util.media.chart.TimeSeriesChartGenerator; /** * the GUIState that visualizes the simulation defined in SleuthWorld.java * */ public class SleuthWorldWithUI extends GUIState { SleuthWorld sleuthworld; private Display2D display; private JFrame displayFrame; // portrayal data ObjectGridPortrayal2D slope = new ObjectGridPortrayal2D(); ObjectGridPortrayal2D landuse = new ObjectGridPortrayal2D(); ObjectGridPortrayal2D excluded = new ObjectGridPortrayal2D(); ObjectGridPortrayal2D urban = new ObjectGridPortrayal2D(); ObjectGridPortrayal2D urbanOverTime = new ObjectGridPortrayal2D(); ObjectGridPortrayal2D transport = new ObjectGridPortrayal2D(); ObjectGridPortrayal2D hillshade = new ObjectGridPortrayal2D(); // chart information TimeSeriesChartGenerator urbanChart; XYSeries numUrban; // This must be included to have model tab, which allows mid-simulation // modification of the coefficients public Object getSimulationInspectedObject() { return state; } // non-volatile /** * Constructor * @param state */ protected SleuthWorldWithUI(SimState state) { super(state); sleuthworld = (SleuthWorld) state; } /** * Main function * @param args */ public static void main(String[] args) { SleuthWorldWithUI simple = new SleuthWorldWithUI(new SleuthWorld(System.currentTimeMillis())); Console c = new Console(simple); c.setVisible(true); } /** * @return name of the simulation */ public static String getName() { return "SleuthWorld"; } /** * Called when starting a new run of the simulation. Sets up the portrayals * and chart data. */ @Override public void start() { super.start(); // set up the chart info numUrban = new XYSeries("Number of Urban Tiles"); urbanChart.removeAllSeries(); urbanChart.addSeries(numUrban, null); // schedule the chart to take data state.schedule.scheduleRepeating(new Steppable() { public void step(SimState state) { SleuthWorld sw = (SleuthWorld) state; numUrban.add(state.schedule.getTime(), sw.numUrban / (double) (sw.numUrban + sw.numNonUrban)); } }); // set up the portrayals slope.setField(sleuthworld.landscape); slope.setPortrayalForAll(new SlopePortrayal()); landuse.setField(sleuthworld.landscape); landuse.setPortrayalForAll(new LandusePortrayal()); excluded.setField(sleuthworld.landscape); excluded.setPortrayalForAll(new ExcludedPortrayal()); urban.setField(sleuthworld.landscape); urban.setPortrayalForAll(new OriginalUrbanPortrayal()); urbanOverTime.setField(sleuthworld.landscape); urbanOverTime.setPortrayalForAll(new GrowingUrbanZonesPortrayal()); transport.setField(sleuthworld.landscape); transport.setPortrayalForAll(new TransportPortrayal()); hillshade.setField(sleuthworld.landscape); hillshade.setPortrayalForAll(new HillshadePortrayal()); // reschedule the displayer display.reset(); display.setBackdrop(Color.white); // redraw the display display.repaint(); } /** * Called when first beginning a SleuthWorldWithUI. Sets up the display window, * the JFrames, and the chart structure. */ @Override public void init(Controller c) { super.init(c); // make the displayer display = new Display2D(600, 600, this); // turn off clipping display.setClipping(false); displayFrame = display.createFrame(); displayFrame.setTitle("SleuthWorld Display"); c.registerFrame(displayFrame); // register the frame so it appears in // the "Display" list displayFrame.setVisible(true); display.attach(slope, "Slope"); display.attach(landuse, "Landuse"); display.attach(excluded, "Excluded"); display.attach(urbanOverTime, "Current Urban"); display.attach(urban, "Initial Urban"); display.attach(transport, "Transport"); display.attach(hillshade, "Hillshade"); // chart! urbanChart = new TimeSeriesChartGenerator(); urbanChart.setTitle("Percent of Urban Tiles in Simulation"); urbanChart.setYAxisLabel("Percent of Urban Tiles"); urbanChart.setXAxisLabel("Time"); JFrame chartFrame = urbanChart.createFrame(this); chartFrame.setVisible(true); chartFrame.pack(); c.registerFrame(chartFrame); } /** called when quitting a simulation. Does appropriate garbage collection. */ public void quit() { super.quit(); if (displayFrame != null) { displayFrame.dispose(); } displayFrame = null; // let gc display = null; // let gc } // COLORMAPS FOR PORTRAYALS // colormap for slope, which is assumed to be between 0 and 255. private static ColorMap slopeColor = new sim.util.gui.SimpleColorMap( 0, 100, new Color(250, 250, 250), new Color(0, 0, 0)); private static ColorMap hillshadeColor = new sim.util.gui.SimpleColorMap( 0, 255, new Color(250, 250, 250, 100), new Color(0, 0, 0, 100)); public static ColorMap getHillshadeColor() { return hillshadeColor; } public static ColorMap getSlopeColor() { return slopeColor; } }