Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import javax.swing.*;
  4. import java.util.LinkedHashMap;
  5. import java.util.Map;
  6. /**
  7. * A graphical view of the simulation grid.
  8. * The view displays a colored rectangle for each location
  9. * representing its contents. It uses a default background color.
  10. * Colors for each type of species can be defined using the
  11. * setColor method.
  12. *
  13. * @author Yemima Sutanto
  14. * @version 1.0 (22 November 2018)
  15. */
  16. public class SimulatorView extends JFrame
  17. {
  18. // Colors used for empty locations.
  19. private static final Color EMPTY_COLOR = Color.white;
  20. // Color used for objects that have no defined color.
  21. private static final Color UNKNOWN_COLOR = Color.gray;
  22. private final String STEP_PREFIX = "Step: ";
  23. private final String POPULATION_PREFIX = "Population: ";
  24. private JLabel stepLabel, population;
  25. private FieldView fieldView;
  26. // A map for storing colors for participants in the simulation
  27. private Map<Class, Color> colors;
  28. // A statistics object computing and storing simulation information
  29. private FieldStats stats;
  30. /**
  31. * Create a view of the given width and height.
  32. * @param height The simulation's height.
  33. * @param width The simulation's width.
  34. */
  35. public SimulatorView(int height, int width)
  36. {
  37. stats = new FieldStats();
  38. colors = new LinkedHashMap<Class, Color>();
  39. setTitle("Fox and Rabbit Simulation");
  40. stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);
  41. population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);
  42. setLocation(100, 50);
  43. fieldView = new FieldView(height, width);
  44. Container contents = getContentPane();
  45. contents.add(stepLabel, BorderLayout.NORTH);
  46. contents.add(fieldView, BorderLayout.CENTER);
  47. contents.add(population, BorderLayout.SOUTH);
  48. pack();
  49. setVisible(true);
  50. }
  51. /**
  52. * Define a color to be used for a given class of animal.
  53. * @param animalClass The animal's Class object.
  54. * @param color The color to be used for the given class.
  55. */
  56. public void setColor(Class animalClass, Color color)
  57. {
  58. colors.put(animalClass, color);
  59. }
  60. /**
  61. * @return The color to be used for a given class of animal.
  62. */
  63. private Color getColor(Class animalClass)
  64. {
  65. Color col = colors.get(animalClass);
  66. if(col == null) {
  67. // no color defined for this class
  68. return UNKNOWN_COLOR;
  69. }
  70. else {
  71. return col;
  72. }
  73. }
  74. /**
  75. * Show the current status of the field.
  76. * @param step Which iteration step it is.
  77. * @param field The field whose status is to be displayed.
  78. */
  79. public void showStatus(int step, Field field)
  80. {
  81. if(!isVisible()) {
  82. setVisible(true);
  83. }
  84. stepLabel.setText(STEP_PREFIX + step);
  85. stats.reset();
  86. fieldView.preparePaint();
  87. for(int row = 0; row < field.getDepth(); row++) {
  88. for(int col = 0; col < field.getWidth(); col++) {
  89. Object animal = field.getObjectAt(row, col);
  90. if(animal != null) {
  91. stats.incrementCount(animal.getClass());
  92. fieldView.drawMark(col, row, getColor(animal.getClass()));
  93. }
  94. else {
  95. fieldView.drawMark(col, row, EMPTY_COLOR);
  96. }
  97. }
  98. }
  99. stats.countFinished();
  100. population.setText(POPULATION_PREFIX + stats.getPopulationDetails(field));
  101. fieldView.repaint();
  102. }
  103. /**
  104. * Determine whether the simulation should continue to run.
  105. * @return true If there is more than one species alive.
  106. */
  107. public boolean isViable(Field field)
  108. {
  109. return stats.isViable(field);
  110. }
  111. /**
  112. * Provide a graphical view of a rectangular field. This is
  113. * a nested class (a class defined inside a class) which
  114. * defines a custom component for the user interface. This
  115. * component displays the field.
  116. * This is rather advanced GUI stuff - you can ignore this
  117. * for your project if you like.
  118. */
  119. private class FieldView extends JPanel
  120. {
  121. private final int GRID_VIEW_SCALING_FACTOR = 6;
  122. private int gridWidth, gridHeight;
  123. private int xScale, yScale;
  124. Dimension size;
  125. private Graphics g;
  126. private Image fieldImage;
  127. /**
  128. * Create a new FieldView component.
  129. */
  130. public FieldView(int height, int width)
  131. {
  132. gridHeight = height;
  133. gridWidth = width;
  134. size = new Dimension(0, 0);
  135. }
  136. /**
  137. * Tell the GUI manager how big we would like to be.
  138. */
  139. public Dimension getPreferredSize()
  140. {
  141. return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,
  142. gridHeight * GRID_VIEW_SCALING_FACTOR);
  143. }
  144. /**
  145. * Prepare for a new round of painting. Since the component
  146. * may be resized, compute the scaling factor again.
  147. */
  148. public void preparePaint()
  149. {
  150. if(! size.equals(getSize())) { // if the size has changed...
  151. size = getSize();
  152. fieldImage = fieldView.createImage(size.width, size.height);
  153. g = fieldImage.getGraphics();
  154. xScale = size.width / gridWidth;
  155. if(xScale < 1) {
  156. xScale = GRID_VIEW_SCALING_FACTOR;
  157. }
  158. yScale = size.height / gridHeight;
  159. if(yScale < 1) {
  160. yScale = GRID_VIEW_SCALING_FACTOR;
  161. }
  162. }
  163. }
  164. /**
  165. * Paint on grid location on this field in a given color.
  166. */
  167. public void drawMark(int x, int y, Color color)
  168. {
  169. g.setColor(color);
  170. g.fillRect(x * xScale, y * yScale, xScale-1, yScale-1);
  171. }
  172. /**
  173. * The field view component needs to be redisplayed. Copy the
  174. * internal image to screen.
  175. */
  176. public void paintComponent(Graphics g)
  177. {
  178. if(fieldImage != null) {
  179. Dimension currentSize = getSize();
  180. if(size.equals(currentSize)) {
  181. g.drawImage(fieldImage, 0, 0, null);
  182. }
  183. else {
  184. // Rescale the previous image.
  185. g.drawImage(fieldImage, 0, 0, currentSize.width, currentSize.height, null);
  186. }
  187. }
  188. }
  189. }
  190. }