PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/mona/projects/mox/src/GameOfLifeApplication.java

#
Java | 347 lines | 255 code | 52 blank | 40 comment | 34 complexity | 0e6dbdeaeb6144c05a070ba464613f34 MD5 | raw file
  1. /*
  2. *
  3. * Game of Life application.
  4. *
  5. * Usage:
  6. *
  7. * java GameOfLifeApplication [-gridSize <width> <height>]
  8. * [-screenSize <width> <height>]
  9. *
  10. */
  11. import java.awt.*;
  12. import java.awt.event.*;
  13. import java.io.*;
  14. import javax.swing.*;
  15. import javax.swing.event.*;
  16. // Game of Life application.
  17. public class GameOfLifeApplication implements Runnable
  18. {
  19. // Update frequency (ms).
  20. static final int MIN_DELAY = 5;
  21. static final int MAX_DELAY = 500;
  22. static final int MAX_SLEEP = 100;
  23. // Game of Life automaton.
  24. GameOfLife gameOfLife;
  25. static final Dimension DEFAULT_GRID_SIZE = new Dimension(50, 50);
  26. Dimension gridSize = DEFAULT_GRID_SIZE;
  27. int delay = MAX_DELAY;
  28. Thread updateThread;
  29. // Display.
  30. static final Dimension DEFAULT_SCREEN_SIZE = new Dimension(600, 700);
  31. JFrame screen;
  32. Dimension screenSize = DEFAULT_SCREEN_SIZE;
  33. Dimension displaySize;
  34. GameOfLifeCanvas gameOfLifeCanvas;
  35. // Controls.
  36. Controls controls;
  37. // Constructor.
  38. public GameOfLifeApplication(Dimension gridSize, Dimension screenSize)
  39. {
  40. this.gridSize = new Dimension(gridSize);
  41. this.screenSize = new Dimension(screenSize);
  42. // Set up screen.
  43. screen = new JFrame("Game of Life");
  44. screen.addWindowListener(new WindowAdapter()
  45. {
  46. public void windowClosing(WindowEvent e)
  47. {
  48. System.exit(0);
  49. }
  50. }
  51. );
  52. screen.setSize(screenSize);
  53. screen.getContentPane().setLayout(new BorderLayout());
  54. // Create automaton.
  55. gameOfLife = new GameOfLife(gridSize);
  56. // Create display.
  57. displaySize = new Dimension((int)((double)screenSize.width * .99),
  58. (int)((double)screenSize.height * .75));
  59. gameOfLifeCanvas = new GameOfLifeCanvas(gameOfLife, displaySize);
  60. screen.getContentPane().add(gameOfLifeCanvas, BorderLayout.NORTH);
  61. // Create controls.
  62. controls = new Controls();
  63. screen.getContentPane().add(controls);
  64. // Make screen visible.
  65. screen.setVisible(true);
  66. // Start update thread.
  67. updateThread = new Thread(this);
  68. updateThread.start();
  69. }
  70. // Run.
  71. public void run()
  72. {
  73. int timer = 0;
  74. // Lower thread's priority.
  75. if (Thread.currentThread() == updateThread)
  76. {
  77. Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
  78. }
  79. // Update loop.
  80. while ((Thread.currentThread() == updateThread) &&
  81. !updateThread.isInterrupted())
  82. {
  83. if ((delay < MAX_DELAY) && (timer >= delay))
  84. {
  85. gameOfLife.step();
  86. timer = 0;
  87. }
  88. gameOfLifeCanvas.display();
  89. try
  90. {
  91. if (delay < MAX_SLEEP)
  92. {
  93. Thread.sleep(delay);
  94. if (timer < MAX_DELAY)
  95. {
  96. timer += delay;
  97. }
  98. }
  99. else
  100. {
  101. Thread.sleep(MAX_SLEEP);
  102. if (timer < MAX_DELAY)
  103. {
  104. timer += MAX_SLEEP;
  105. }
  106. }
  107. }
  108. catch (InterruptedException e) {
  109. break;
  110. }
  111. }
  112. }
  113. // Main.
  114. public static void main(String[] args)
  115. {
  116. Dimension gridSize = new Dimension(DEFAULT_GRID_SIZE);
  117. Dimension screenSize = new Dimension(DEFAULT_SCREEN_SIZE);
  118. // Get sizes.
  119. for (int i = 0; i < args.length; )
  120. {
  121. if (args[i].equals("-gridSize"))
  122. {
  123. i++;
  124. gridSize.width = gridSize.height = -1;
  125. if (i < args.length)
  126. {
  127. gridSize.width = Integer.parseInt(args[i]);
  128. i++;
  129. }
  130. if (i < args.length)
  131. {
  132. gridSize.height = Integer.parseInt(args[i]);
  133. i++;
  134. }
  135. if ((gridSize.width <= 0) || (gridSize.height <= 0))
  136. {
  137. System.err.println("Invalid grid size");
  138. System.exit(1);
  139. }
  140. }
  141. else if (args[i].equals("-screenSize"))
  142. {
  143. i++;
  144. screenSize.width = screenSize.height = -1;
  145. if (i < args.length)
  146. {
  147. screenSize.width = Integer.parseInt(args[i]);
  148. i++;
  149. }
  150. if (i < args.length)
  151. {
  152. screenSize.height = Integer.parseInt(args[i]);
  153. i++;
  154. }
  155. if ((screenSize.width <= 0) || (screenSize.height <= 0))
  156. {
  157. System.err.println("Invalid screen size");
  158. System.exit(1);
  159. }
  160. }
  161. else
  162. {
  163. System.err.println(
  164. "java GameOfLifeApplication [-gridSize <width> <height>] [-screenSize <width> <height>]");
  165. System.exit(1);
  166. }
  167. }
  168. // Create the application.
  169. new GameOfLifeApplication(gridSize, screenSize);
  170. }
  171. // Control panel.
  172. class Controls extends JPanel implements ActionListener, ChangeListener
  173. {
  174. // Components.
  175. JSlider speedSlider;
  176. JButton stepButton;
  177. JButton clearButton;
  178. JButton checkpointButton;
  179. JButton restoreButton;
  180. JButton loadButton;
  181. JButton saveButton;
  182. JTextField inputText;
  183. JTextField outputText;
  184. // Constructor.
  185. Controls()
  186. {
  187. setLayout(new GridLayout(4, 1));
  188. setBorder(BorderFactory.createRaisedBevelBorder());
  189. JPanel panel = new JPanel();
  190. panel.add(new JLabel("Speed: Fast", Label.RIGHT));
  191. speedSlider = new JSlider(JSlider.HORIZONTAL, MIN_DELAY, MAX_DELAY,
  192. MAX_DELAY);
  193. speedSlider.addChangeListener(this);
  194. panel.add(speedSlider);
  195. panel.add(new JLabel("Stop", Label.LEFT));
  196. stepButton = new JButton("Step");
  197. stepButton.addActionListener(this);
  198. panel.add(stepButton);
  199. add(panel);
  200. panel = new JPanel();
  201. clearButton = new JButton("Clear");
  202. clearButton.addActionListener(this);
  203. panel.add(clearButton);
  204. checkpointButton = new JButton("Checkpoint");
  205. checkpointButton.addActionListener(this);
  206. panel.add(checkpointButton);
  207. restoreButton = new JButton("Restore");
  208. restoreButton.addActionListener(this);
  209. panel.add(restoreButton);
  210. add(panel);
  211. panel = new JPanel();
  212. panel.add(new JLabel("File: "));
  213. inputText = new JTextField("", 25);
  214. panel.add(inputText);
  215. loadButton = new JButton("Load");
  216. loadButton.addActionListener(this);
  217. panel.add(loadButton);
  218. saveButton = new JButton("Save");
  219. saveButton.addActionListener(this);
  220. panel.add(saveButton);
  221. add(panel);
  222. panel = new JPanel();
  223. panel.add(new JLabel("Status: "));
  224. outputText = new JTextField("", 40);
  225. outputText.setEditable(false);
  226. panel.add(outputText);
  227. add(panel);
  228. }
  229. // Speed slider listener.
  230. public void stateChanged(ChangeEvent evt)
  231. {
  232. outputText.setText("");
  233. delay = speedSlider.getValue();
  234. }
  235. // Input text listener.
  236. public void actionPerformed(ActionEvent evt)
  237. {
  238. outputText.setText("");
  239. // Step?
  240. if (evt.getSource() == (Object)stepButton)
  241. {
  242. speedSlider.setValue(MAX_DELAY);
  243. gameOfLife.step();
  244. gameOfLifeCanvas.display();
  245. return;
  246. }
  247. // Clear?
  248. if (evt.getSource() == (Object)clearButton)
  249. {
  250. gameOfLife.clear();
  251. return;
  252. }
  253. // Checkpoint?
  254. if (evt.getSource() == (Object)checkpointButton)
  255. {
  256. gameOfLife.checkpoint();
  257. return;
  258. }
  259. // Restore?
  260. if (evt.getSource() == (Object)restoreButton)
  261. {
  262. gameOfLife.restore();
  263. return;
  264. }
  265. // Load/save.
  266. String fileName = inputText.getText().trim();
  267. if (fileName.equals(""))
  268. {
  269. return;
  270. }
  271. // Load?
  272. if (evt.getSource() == (Object)loadButton)
  273. {
  274. try {
  275. gameOfLife.load(fileName);
  276. outputText.setText(fileName + " loaded");
  277. }
  278. catch (IOException e) {
  279. outputText.setText(e.getMessage());
  280. }
  281. }
  282. // Save?
  283. if (evt.getSource() == (Object)saveButton)
  284. {
  285. try {
  286. gameOfLife.save(fileName);
  287. outputText.setText(fileName + " saved");
  288. }
  289. catch (IOException e) {
  290. outputText.setText(e.getMessage());
  291. }
  292. }
  293. }
  294. }
  295. }