import java.awt.Container; import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.Color; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; import javax.swing.*; // package life; public class MainApp { static JButton[][] gridCell; static JLabel turnCountDisplay = new JLabel("0",SwingConstants.CENTER); static int rows; static int turnCount = 0; static int turnSpeed = 2000; static boolean running = false; static ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { doUpdate(gridCell); turnCount++; turnCountUpdate(); } }; public static void main(String[] args) { if (args.length > 0) { try { rows = Integer.parseInt(args[0]); } catch (NumberFormatException except) { System.err.println("The first parameter should be a number"); System.exit(0); } } else { rows = 40; } javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { if (rows > 2) { lifeWindow(rows); } else { System.out.println("Must choose grid size of at least 3"); } } }); } static Timer t = new Timer(turnSpeed, taskPerformer); static class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { t.setInitialDelay(0); JButton sent = (JButton)event.getSource(); // the button pressed String label = sent.getText(); // the button's label if (label.equals("Clear") && !running) { turnCount = 0; turnCountUpdate(); for (int i=0; i < rows; i++) { for (int j=0; j < rows; j++) { gridCell[i][j].setBackground(Color.gray); } } t.setRepeats(true); } else if (label.equals("Step") && !running) { running = true; t.setRepeats(false); t.start(); running = false; } else if (label.equals("Run") && !running) { sent.setText("Pause"); t.setRepeats(true); t.start(); running = true; } else if (label.equals("Pause")) { sent.setText("Run"); t.stop(); running = false; } else if (label.equals("Stop") && !running) { System.exit(0); } } } public static void turnCountUpdate() { turnCountDisplay.setText(String.valueOf(turnCount)); } public static void doUpdate(JButton[][] gridCell) { int[][] hold = new int[rows][rows]; for (int i=0; i < rows; i++) { for (int j=0; j < rows; j++) { hold[i][j] = getColourValue(gridCell[i][j]); } } processValues(hold); for (int i=0; i < rows; i++) { for (int j=0; j < rows; j++) { gridCell[i][j] = putColourValue(hold[i][j]); } } } public static void processValues(int[][] values) { int[] surroundingCellData = new int[8]; for (int i=0; i < rows; i++) { for (int j=0; j < rows; j++) { surroundingCellData[0] = values[transCoOrd(i-1)][transCoOrd(j-1)]; surroundingCellData[1] = values[transCoOrd(i-1)][transCoOrd( j )]; surroundingCellData[2] = values[transCoOrd(i-1)][transCoOrd(j+1)]; surroundingCellData[3] = values[transCoOrd( i )][transCoOrd(j-1)]; surroundingCellData[4] = values[transCoOrd( i )][transCoOrd(j+1)]; surroundingCellData[5] = values[transCoOrd(i+1)][transCoOrd(j-1)]; surroundingCellData[6] = values[transCoOrd(i+1)][transCoOrd( j )]; surroundingCellData[7] = values[transCoOrd(i+1)][transCoOrd(j+1)]; int redCount = 0; int greenCount = 0; for (int k=0; k < surroundingCellData.length; k++) { if (surroundingCellData[k] == 1) { redCount++; } else if (surroundingCellData[k] == 2) { greenCount++; } } if (((redCount + greenCount) >= 4) || ((redCount + greenCount) <= 1)) { values[i][j] = 0; } else if (((redCount + greenCount) == 3) && (values[i][j] == 0)) { if (redCount > greenCount) { values[i][j] = 1; } else { values[i][j] = 2; } } } } } public static int transCoOrd(int CoOrd) { if (CoOrd == -1) { CoOrd = CoOrd + rows; } else if (CoOrd == rows) { CoOrd = CoOrd - rows; } return CoOrd; } public static int getColourValue(JButton button) { if (button.getBackground() == Color.red) { return 1; } else if (button.getBackground() == Color.green) { return 2; } else { return 0; } } public static JButton putColourValue(int colour) { JButton newButton = new JButton(); if (colour == 1) { newButton.setBackground(Color.red); } else if (colour == 2) { newButton.setBackground(Color.green); } else { newButton.setBackground(Color.gray); } return newButton; } public static void lifeWindow(int rows) { gridCell = new JButton[rows][rows]; MouseButtonControl mouseListen = new MouseButtonControl(); for (int i=0; i < rows; i++) { for (int j=0; j < rows; j++) { gridCell[i][j] = new JButton(); gridCell[i][j].addMouseListener(mouseListen); } } JButton clearBtn = new JButton("Clear"); JButton stepBtn = new JButton("Step"); JButton runBtn = new JButton("Run"); JButton stopBtn = new JButton("Stop"); ButtonListener listen = new ButtonListener(); clearBtn.addActionListener(listen); stepBtn.addActionListener(listen); runBtn.addActionListener(listen); stopBtn.addActionListener(listen); JFrame frame = new JFrame(); frame.setSize(500,500); Container contentPane = frame.getContentPane(); JPanel cellGrid = new JPanel(); JPanel buttonPanel = new JPanel(); cellGrid.setLayout(new GridLayout(rows,rows,0,0)); for (int i=0; i < rows; i++) { for (int j=0; j < rows; j++) { cellGrid.add(gridCell[i][j]); gridCell[i][j].setBackground(Color.gray); } } cellGrid.setBorder(BorderFactory.createEmptyBorder(0,10,0,0)); JSlider slide = new JSlider(JSlider.VERTICAL,1,10,1); slide.setMajorTickSpacing(1); slide.setMinorTickSpacing(1); slide.setPaintTicks(true); slide.setPaintLabels(true); slide.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); buttonPanel.add(clearBtn); buttonPanel.add(stepBtn); buttonPanel.add(runBtn); buttonPanel.add(stopBtn); contentPane.add(turnCountDisplay,BorderLayout.NORTH); contentPane.add(cellGrid,BorderLayout.CENTER); contentPane.add(slide,BorderLayout.EAST); contentPane.add(buttonPanel,BorderLayout.SOUTH); slide.addChangeListener(new ChangeValue()); frame.setVisible(true); } static class ChangeValue implements ChangeListener { public void stateChanged(ChangeEvent expn) { JSlider source = (JSlider)expn.getSource(); if (!source.getValueIsAdjusting()) { t.setDelay(2000 / (int)source.getValue()); } } } static class MouseButtonControl extends MouseAdapter { public void mousePressed(MouseEvent event) { JButton cell = (JButton)event.getSource(); if (!running) { if (SwingUtilities.isLeftMouseButton(event)) { cell.setBackground(Color.red); } else if (SwingUtilities.isRightMouseButton(event)) { cell.setBackground(Color.green); } else { cell.setBackground(Color.gray); } } } } }