/** ** SchellingSpaceWithUI.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.schellingspace; 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.geo.GeomVectorFieldPortrayal; import sim.util.media.chart.HistogramGenerator; import sim.util.media.chart.TimeSeriesChartGenerator; @SuppressWarnings("restriction") public class SchellingSpaceWithUI extends GUIState { Display2D display; JFrame displayFrame; // portrayal info GeomVectorFieldPortrayal polyPortrayal = new GeomVectorFieldPortrayal(); GeomVectorFieldPortrayal peoplePortrayal = new GeomVectorFieldPortrayal(); // chart info TimeSeriesChartGenerator happinessChart; XYSeries happyReds; XYSeries happyBlues; // histogram info HistogramGenerator numMovesHisto; double[] peoplesMoves; protected SchellingSpaceWithUI(SimState state) { super(state); } public SchellingSpaceWithUI() { super(new SchellingSpace(System.currentTimeMillis())); } /** return the name of the simulation */ public static String getName() { return "SpaceSchelling"; } /** initialize the simulation */ public void init(Controller controller) { super.init(controller); display = new Display2D(600, 600, this); display.attach(polyPortrayal, "Polys"); display.attach(peoplePortrayal, "People"); displayFrame = display.createFrame(); controller.registerFrame(displayFrame); displayFrame.setVisible(true); // the happiness chart setup happinessChart = new TimeSeriesChartGenerator(); happinessChart.setTitle("Percent of Happy Persons in Simulation"); happinessChart.setYAxisLabel("Percent Happy"); happinessChart.setXAxisLabel("Opportunities to Move"); JFrame chartFrame = happinessChart.createFrame(this); chartFrame.pack(); controller.registerFrame(chartFrame); // the # moves histogram setup numMovesHisto = new HistogramGenerator(); numMovesHisto.setTitle("Number of Moves People Have Made"); numMovesHisto.setYAxisLabel("Number of Moves"); numMovesHisto.setXAxisLabel("number"); JFrame histoFrame = numMovesHisto.createFrame(this); histoFrame.pack(); controller.registerFrame(histoFrame); } /** quit the simulation, cleaning up after itself*/ public void quit() { super.quit(); if (displayFrame != null) { displayFrame.dispose(); } displayFrame = null; display = null; } /** start the simulation, setting up the portrayals and charts for a new run */ public void start() { super.start(); setupPortrayals(); } /** * Sets up the portrayals and charts for the simulation */ private void setupPortrayals() { SchellingSpace world = (SchellingSpace) state; // reset the chart info happyReds = new XYSeries("Happy Reds"); happyBlues = new XYSeries("Happy Blues"); happinessChart.removeAllSeries(); happinessChart.addSeries(happyReds, null); happinessChart.addSeries(happyBlues, null); // schedule the chart to take data state.schedule.scheduleRepeating(new HappyTracker()); // reset the histogram info peoplesMoves = new double[((SchellingSpace) state).people.size()]; numMovesHisto.removeAllSeries(); numMovesHisto.addSeries(peoplesMoves, 10, "HistoMoves", null); // schedule the histogram to take data state.schedule.scheduleRepeating(new MoveTracker()); // the polygon portrayal polyPortrayal.setField(world.world); polyPortrayal.setPortrayalForAll(new WardPortrayal()); peoplePortrayal.setField(world.agents); peoplePortrayal.setPortrayalForAll(new PersonPortrayal()); // peoplePortrayal.setPortrayalForAll(new GeomPortrayal(Color.RED)); display.reset(); display.repaint(); } /** Keeps track of the rates of happy Reds and happy Blues in the simulation */ class HappyTracker implements Steppable { public void step(SimState state) { SchellingSpace ps = (SchellingSpace) state; double hReds = 0, hBlues = 0; // query all Persons whether their position is acceptable for (Person p : ps.people) { if (p.acceptable(ps)) { if (p.getAffiliation().equals(Person.Affiliation.RED)) { hReds++; } else { hBlues++; } } } // add this data to the chart happyReds.add(state.schedule.time(), hReds / ps.totalReds, true); happyBlues.add(state.schedule.time(), hBlues / ps.totalBlues, true); } } /** Keeps track of the number of moves agents have made */ class MoveTracker implements Steppable { public void step(SimState state) { SchellingSpace ps = (SchellingSpace) state; int numPeople = ps.people.size(); peoplesMoves = new double[numPeople]; for (int i = 0; i < numPeople; i++) { Person p = ps.people.get(i); peoplesMoves[i] = p.numMoves; } numMovesHisto.updateSeries(0, peoplesMoves); } } public static void main(String[] args) { SchellingSpaceWithUI worldGUI = new SchellingSpaceWithUI(); Console console = new Console(worldGUI); console.setVisible(true); } }