/**
** WaterWorldWithUI.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.waterworld;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
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.DrawInfo2D;
import sim.portrayal.grid.ObjectGridPortrayal2D;
import sim.portrayal.simple.RectanglePortrayal2D;
import sim.util.gui.ColorMap;
import sim.util.media.chart.TimeSeriesChartGenerator;
/**
* the GUIState that visualizes the simulation defined in WaterWorld.java
*
*/
public class WaterWorldWithUI extends GUIState
{
WaterWorld waterworld;
public Display2D display;
public JFrame displayFrame;
// portrayal data
ObjectGridPortrayal2D ground = new ObjectGridPortrayal2D();
ObjectGridPortrayal2D water = new ObjectGridPortrayal2D();
// chart information
TimeSeriesChartGenerator raindropChart;
XYSeries numRaindrops;
/**
* Constructor
* @param state
*/
protected WaterWorldWithUI(SimState state)
{
super(state);
waterworld = (WaterWorld) state;
}
/**
* Main function
* @param args
*/
public static void main(String[] args)
{
WaterWorldWithUI simple = new WaterWorldWithUI(new WaterWorld(System.currentTimeMillis()));
Console c = new Console(simple);
c.setVisible(true);
}
/**
* @return name of the simulation
*/
public static String getName()
{
return "WaterWorld";
}
/**
* Called when starting a new run of the simulation. Sets up the portrayals
* and chart data.
*/
public void start()
{
super.start();
// set up the chart info
numRaindrops = new XYSeries("Raindrops");
raindropChart.removeAllSeries();
raindropChart.addSeries(numRaindrops, null);
// schedule the chart to take data
state.schedule.scheduleRepeating(new Steppable()
{
public void step(SimState state)
{
numRaindrops.add(state.schedule.getTime(),
((WaterWorld) state).drops.size(),
true);
}
});
// set up the portrayals
ground.setField(waterworld.landscape);
ground.setPortrayalForAll(new GroundPortrayal());
water.setField(waterworld.landscape);
water.setPortrayalForAll(new WaterPortrayal());
// reschedule the displayer
display.reset();
display.setBackdrop(new Color(250, 246, 237));
// redraw the display
display.repaint();
}
/**
* Called when first beginning a WaterWorldWithUI. Sets up the display window,
* the JFrames, and the chart structure.
*/
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("WaterWorld Display");
c.registerFrame(displayFrame); // register the frame so it appears in
// the "Display" list
displayFrame.setVisible(true);
display.attach(ground, "Ground");
display.attach(water, "Water");
// chart!
raindropChart = new TimeSeriesChartGenerator();
raindropChart.setTitle("Number of Raindrops in Simulation");
raindropChart.setYAxisLabel("Number of Raindrops");
raindropChart.setXAxisLabel("Time");
JFrame chartFrame = raindropChart.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
}
/////////////////////
// PORTRAYALS
/////////////////////
// colormap for ground height, which is assumed to be between 0 and 300.
ColorMap elevation = new sim.util.gui.SimpleColorMap(
0, 300, new Color(250, 246, 237), new Color(53, 44, 36));
// elevation-based portrayal
class GroundPortrayal extends RectanglePortrayal2D
{
public void draw(Object object, Graphics2D graphics, DrawInfo2D info)
{
Rectangle2D.Double draw = info.draw;
final double width = draw.width * scale;
final double height = draw.height * scale;
final int x = (int) (draw.x - width / 2.0);
final int y = (int) (draw.y - height / 2.0);
final int w = (int) (width);
final int h = (int) (height);
Basin b = (Basin) object;
graphics.setColor(elevation.getColor(b.baseheight));
graphics.fillRect(x, y, w, h);
}
}
// colormap for water depth
ColorMap depth = new sim.util.gui.SimpleColorMap(
0, 10, new Color(70, 100, 200, 0), new Color(70, 100, 200, 255));
// water depth-based portrayal
class WaterPortrayal extends RectanglePortrayal2D
{
public void draw(Object object, Graphics2D graphics, DrawInfo2D info)
{
Rectangle2D.Double draw = info.draw;
final double width = draw.width * scale;
final double height = draw.height * scale;
final int x = (int) (draw.x - width / 2.0);
final int y = (int) (draw.y - height / 2.0);
final int w = (int) (width);
final int h = (int) (height);
Basin b = (Basin) object;
graphics.setColor(depth.getColor(b.drops.size()));
graphics.fillRect(x, y, w, h);
}
}
}