first commit
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A graphical view of the simulation grid.
|
||||
* The view displays a colored rectangle for each location representing its contents.
|
||||
* Colors for each type of species can be defined using the setColor method.
|
||||
*
|
||||
* @author Michael Kölling and David J. Barnes
|
||||
* @version 2016.03.18
|
||||
*/
|
||||
public class GridView extends JFrame implements SimulatorView
|
||||
{
|
||||
// Colors used for empty locations.
|
||||
private static final Color EMPTY_COLOR = Color.white;
|
||||
|
||||
// Color used for objects that have no defined color.
|
||||
private static final Color UNKNOWN_COLOR = Color.gray;
|
||||
|
||||
private final String STEP_PREFIX = "Step: ";
|
||||
private final String POPULATION_PREFIX = "Population: ";
|
||||
private JLabel stepLabel, population;
|
||||
private FieldView fieldView;
|
||||
|
||||
// A map for storing colors for participants in the simulation
|
||||
private Map<Class<?>, Color> colors;
|
||||
// A statistics object computing and storing simulation information
|
||||
private FieldStats stats;
|
||||
|
||||
/**
|
||||
* Create a view of the given width and height.
|
||||
* @param height The simulation's height.
|
||||
* @param width The simulation's width.
|
||||
*/
|
||||
public GridView(int height, int width)
|
||||
{
|
||||
stats = new FieldStats();
|
||||
colors = new HashMap<>();
|
||||
|
||||
setTitle("Fox and Rabbit Simulation");
|
||||
stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);
|
||||
population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);
|
||||
|
||||
setLocation(20, 50);
|
||||
|
||||
fieldView = new FieldView(height, width);
|
||||
|
||||
Container contents = getContentPane();
|
||||
contents.add(stepLabel, BorderLayout.NORTH);
|
||||
contents.add(fieldView, BorderLayout.CENTER);
|
||||
contents.add(population, BorderLayout.SOUTH);
|
||||
pack();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a color to be used for a given class of animal.
|
||||
* @param animalClass The animal's Class object.
|
||||
* @param color The color to be used for the given class.
|
||||
*/
|
||||
public void setColor(Class<?> animalClass, Color color)
|
||||
{
|
||||
colors.put(animalClass, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The color to be used for a given class of animal.
|
||||
*/
|
||||
private Color getColor(Class<?> animalClass)
|
||||
{
|
||||
Color col = colors.get(animalClass);
|
||||
if(col == null) {
|
||||
// no color defined for this class
|
||||
return UNKNOWN_COLOR;
|
||||
}
|
||||
else {
|
||||
return col;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the current status of the field.
|
||||
* @param step Which iteration step it is.
|
||||
* @param field The field whose status is to be displayed.
|
||||
*/
|
||||
public void showStatus(int step, Field field)
|
||||
{
|
||||
if(!isVisible()) {
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
stepLabel.setText(STEP_PREFIX + step);
|
||||
stats.reset();
|
||||
|
||||
fieldView.preparePaint();
|
||||
|
||||
for(int row = 0; row < field.getDepth(); row++) {
|
||||
for(int col = 0; col < field.getWidth(); col++) {
|
||||
Object animal = field.getObjectAt(row, col);
|
||||
if(animal != null) {
|
||||
Class<?> cls = animal.getClass();
|
||||
stats.incrementCount(cls);
|
||||
fieldView.drawMark(col, row, getColor(cls));
|
||||
}
|
||||
else {
|
||||
fieldView.drawMark(col, row, EMPTY_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
stats.countFinished();
|
||||
|
||||
population.setText(POPULATION_PREFIX + stats.getPopulationDetails(field));
|
||||
fieldView.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the simulation should continue to run.
|
||||
* @return true If there is more than one species alive.
|
||||
*/
|
||||
public boolean isViable(Field field)
|
||||
{
|
||||
return stats.isViable(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for a new run.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
stats.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a graphical view of a rectangular field. This is
|
||||
* a nested class (a class defined inside a class) which
|
||||
* defines a custom component for the user interface. This
|
||||
* component displays the field.
|
||||
* This is rather advanced GUI stuff - you can ignore this
|
||||
* for your project if you like.
|
||||
*/
|
||||
private class FieldView extends JPanel
|
||||
{
|
||||
private final int GRID_VIEW_SCALING_FACTOR = 6;
|
||||
|
||||
private int gridWidth, gridHeight;
|
||||
private int xScale, yScale;
|
||||
Dimension size;
|
||||
private Graphics g;
|
||||
private Image fieldImage;
|
||||
|
||||
/**
|
||||
* Create a new FieldView component.
|
||||
*/
|
||||
public FieldView(int height, int width)
|
||||
{
|
||||
gridHeight = height;
|
||||
gridWidth = width;
|
||||
size = new Dimension(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the GUI manager how big we would like to be.
|
||||
*/
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,
|
||||
gridHeight * GRID_VIEW_SCALING_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for a new round of painting. Since the component
|
||||
* may be resized, compute the scaling factor again.
|
||||
*/
|
||||
public void preparePaint()
|
||||
{
|
||||
if(! size.equals(getSize())) { // if the size has changed...
|
||||
size = getSize();
|
||||
fieldImage = fieldView.createImage(size.width, size.height);
|
||||
g = fieldImage.getGraphics();
|
||||
|
||||
xScale = size.width / gridWidth;
|
||||
if(xScale < 1) {
|
||||
xScale = GRID_VIEW_SCALING_FACTOR;
|
||||
}
|
||||
yScale = size.height / gridHeight;
|
||||
if(yScale < 1) {
|
||||
yScale = GRID_VIEW_SCALING_FACTOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paint on grid location on this field in a given color.
|
||||
*/
|
||||
public void drawMark(int x, int y, Color color)
|
||||
{
|
||||
g.setColor(color);
|
||||
g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* The field view component needs to be redisplayed. Copy the
|
||||
* internal image to screen.
|
||||
*/
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
if(fieldImage != null) {
|
||||
Dimension currentSize = getSize();
|
||||
if(size.equals(currentSize)) {
|
||||
g.drawImage(fieldImage, 0, 0, null);
|
||||
}
|
||||
else {
|
||||
// Rescale the previous image.
|
||||
g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user