import javax.swing.JFrame; import javax.swing.*; import java.awt.*; import java.awt.event.*; class MouseHandler implements MouseListener { private GridDisplay grid; public MouseHandler (GridDisplay display) { super (); grid = display; } public void mousePressed(MouseEvent e) { ; } public void mouseReleased(MouseEvent e) { ; } public void mouseEntered(MouseEvent e) { ; } public void mouseExited(MouseEvent e) { ; } public void mouseClicked(MouseEvent e) { grid.setCellAt (e.getX (), e.getY ()); } } class GridDisplay extends JPanel { private Grid grid; GridDisplay (Grid grid) { this.grid = grid; setOpaque (false); // This is necessary to make painting work } private int getSquareWidth () { return getSize ().width / grid.numColumns (); } private int getSquareHeight () { return getSize ().height / grid.numRows (); } private int getHorizontalOffset () { return (getSize ().width - (getSquareWidth () * grid.numColumns ())) / 2; } private int getVerticalOffset () { return (getSize ().height - (getSquareHeight () * grid.numRows ())) / 2; } public void setCellAt (int x, int y) { int row = (y - getVerticalOffset ()) / getSquareHeight (); int col = (x - getHorizontalOffset ()) / getSquareWidth (); grid.getCellAt (row, col).setState (CellState.createAlive ()); repaint (); } public void step () { grid.step (); repaint (); } public void paintComponent (Graphics g) { int squarewidth = getSquareWidth (); int squareheight = getSquareHeight (); int hoffset = getHorizontalOffset (); int voffset = getVerticalOffset (); for (int row = 0; row < grid.numRows (); row++) { for (int col = 0; col < grid.numColumns (); col++) { if (grid.getCellAt (row, col).isAlive ()) { g.setColor (Color.green); } else { g.setColor (Color.black); } g.fillRect (hoffset + col * squarewidth, voffset + row * squareheight, squarewidth - 1, squareheight - 1); } } } } public class CellAutomata extends JPanel implements ActionListener { GridDisplay display; private JButton startButton, stopButton, stepButton; private CellThread thread; // Display frame private static final int FRAME_WIDTH = 520; private static final int FRAME_HEIGHT = 590; private static final int BUTTONS_HEIGHT = 80; public CellAutomata (Grid grid) { try { UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ()); } catch (Exception e) { System.out.println ("Error setting native LAF: " + e); } setLayout (new BoxLayout (this, BoxLayout.Y_AXIS)); display = new GridDisplay (grid); display.setPreferredSize (new Dimension (FRAME_WIDTH, FRAME_HEIGHT - BUTTONS_HEIGHT)); display.setMinimumSize (new Dimension (FRAME_WIDTH, FRAME_HEIGHT - BUTTONS_HEIGHT)); display.addMouseListener (new MouseHandler (display)); add (display); add (Box.createRigidArea (new Dimension (FRAME_WIDTH, 5))); JPanel panel1 = new JPanel(); panel1.setSize (new Dimension (FRAME_WIDTH, BUTTONS_HEIGHT)); panel1.setPreferredSize (new Dimension (FRAME_WIDTH, BUTTONS_HEIGHT)); panel1.setMaximumSize (new Dimension (FRAME_WIDTH, BUTTONS_HEIGHT)); panel1.setBackground (Color.white); startButton = new JButton ("Start"); // place button at center, left position startButton.setVerticalTextPosition (AbstractButton.CENTER); startButton.setHorizontalTextPosition (AbstractButton.LEFT); startButton.setMnemonic (KeyEvent.VK_D); startButton.setActionCommand ("start"); stepButton = new JButton ("Step"); // place button at center, left position stepButton.setVerticalTextPosition (AbstractButton.CENTER); stepButton.setHorizontalTextPosition (AbstractButton.LEFT); stepButton.setMnemonic (KeyEvent.VK_D); stepButton.setActionCommand ("step"); stopButton = new JButton ("Stop"); // Use the default button position of CENTER, RIGHT. stopButton.setMnemonic (KeyEvent.VK_E); stopButton.setActionCommand ("stop"); stopButton.setEnabled (false); // Listen for actions on the Start and Stop buttons. startButton.addActionListener (this); stepButton.addActionListener (this); stopButton.addActionListener (this); // Add the start and stop buttons, and the table, to the // container, using the default layout. panel1.add (startButton); panel1.add (stepButton); panel1.add (stopButton); add (panel1); } public void step () { display.step (); } public void actionPerformed (ActionEvent e) { if (e.getActionCommand ().equals ("start")) { startButton.setEnabled (false); stopButton.setEnabled (true); // Start the game thread thread = new CellThread (this); thread.start (); } else if (e.getActionCommand ().equals ("stop")) { startButton.setEnabled (true); stopButton.setEnabled (false); // Inform the game thread to stop at next opportunity thread.suspendThread (); } else if (e.getActionCommand ().equals ("step")) { step (); } } public static void main (String [] args) { try { if (args.length != 1) { System.err.println ("Usage: java CellAutomata "); System.exit (1); } Class cellClass = Class.forName (args[0]); JFrame frame = new JFrame ("CS201J Game of Life"); frame.setSize (FRAME_WIDTH, FRAME_HEIGHT); frame.addWindowListener (new WindowAdapter () { public void windowClosing (WindowEvent e) { System.exit (0); } } ); Grid grid = new Grid (cellClass, 50, 50); CellAutomata ca = new CellAutomata (grid); frame.getContentPane ().add (ca, BorderLayout.CENTER); frame.show (); } catch (ClassNotFoundException e) { System.out.println ("Could not find cell class: " + args[0]); System.exit (0); } } }