I'm working on modeling John Conway's Game of Life for presentation at a conference coming up, and I have the program in a place that should be 95% complete, however, nothing is responding to user input. It almost seems like my action listener and mouse listener aren't being implemented correctly, but I'm not sure where. The program is almost entirely complete; there are a few portions that are still empty, but it will still compile and create my JFrame properly.
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GameOfLife
{
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
}
}
Class that contains global information:
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GLOBAL
{
/**
* Build Information for GameOfLife
*/
public static final double BUILDVERSION = 0.1;
public static final String BUILDNAME = "Alpha 0.1";
/**
* Global Constants for GameOfLife
*/
public static final int FRAMEHEIGHT = 1000; //Frame Height
public static final int FRAMEWIDTH = 1000; //Frame Width
public static final int HEIGHT = 100; //Game Height
public static final int WIDTH = 100; //Game Width
/**
* Global Variables
*/
public static int delay = 500; //Step Delay (Milliseconds)
public static byte[][] herd0; //Herd Byte Array 0
public static byte[][] herd1; //Herd Byte Array 2
public static byte[][] startHerd; //Customized herd before animation is started
public static byte activeArray; //Array currently being displayed
public static boolean active; //States if simulation is repeating
public static long arraySwitches; //Tallies times active array is switched
/**
* Action Commands
*/
public static final String CLOSE = "close"; //Closes Application
public static final String START = "go"; //Starts looping simulation
public static final String STOP = "stop"; //Stops loop
public static final String RULES = "rules"; //Pops up window with Rules for GOL
public static final String ABOUT = "about"; //Displays about dialog
public static final String RESETGRID = "resetGrid"; //Resets the grid to before the simulation
public static final String NEWGAME = "new"; //Zeroes the grid and arrays
}
Frame:
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.*;
/**
* @author Brendan Kristiansen
*/
public class MyFrame extends JFrame implements ActionListener, ChangeListener
{
private JPanel mPanel;
private JButton start;
private JButton stop;
private JButton setGame;
private JButton resetGame;
private JButton newGame;
private JLabel speedLabel;
private JSlider speed;
private HerdPanel mHerdPanel;
/**
* Constructor
*/
public MyFrame()
{
GLOBAL.active = false;
initArrays();
setSize(GLOBAL.FRAMEWIDTH, GLOBAL.FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mPanel = new JPanel();
initForm();
setVisible(true);
mPanel.setVisible(true);
JMenuBar menu = new JMenuBar();
JMenu game = new JMenu("GameOfLife");
JMenu help = new JMenu("Help");
JMenuItem gamePlay = new JMenuItem("Play");
JMenuItem gameExit = new JMenuItem("Exit");
JMenuItem helpRules = new JMenuItem("Rules");
JMenuItem helpAbout = new JMenuItem("About");
gamePlay.addActionListener(this);
gameExit.addActionListener(this);
helpRules.addActionListener(this);
helpAbout.addActionListener(this);
gamePlay.setActionCommand(GLOBAL.START);
gameExit.setActionCommand(GLOBAL.CLOSE);
helpRules.setActionCommand(GLOBAL.RULES);
helpAbout.setActionCommand(GLOBAL.ABOUT);
game.add(gamePlay);
game.add(gameExit);
help.add(helpRules);
help.add(helpAbout);
menu.add(game);
menu.add(help);
this.setJMenuBar(menu);
this.setVisible(true);
}
/**
* Lays Out Panel
*/
public void initForm()
{
setGame = new JButton("Set Grid");
resetGame = new JButton("Reset Grid");
newGame = new JButton("Clear Grid");
start = new JButton("Start Simulation");
stop = new JButton("Stop Simulation");
speedLabel = new JLabel("Simulation Speed (ms): " + GLOBAL.delay);
// N speed = new JSlider(3000, 50, GLOBAL.delay);
setGame.addActionListener(this);
resetGame.addActionListener(this);
newGame.addActionListener(this);
start.addActionListener(this);
stop.addActionListener(this);
// setGame.setActionCommand(GLOBAL.SETGRID);
resetGame.setActionCommand(GLOBAL.RESETGRID);
newGame.setActionCommand(GLOBAL.NEWGAME);
start.setActionCommand(GLOBAL.START);
stop.setActionCommand(GLOBAL.STOP);
mPanel = new JPanel();
mPanel.setLayout(new BoxLayout(mPanel, BoxLayout.X_AXIS));
mPanel.setBackground(new Color(100, 100, 100));
mHerdPanel = new HerdPanel();
mPanel.add(setGame);
mPanel.add(resetGame);
mPanel.add(newGame);
mPanel.add(start);
mPanel.add(stop);
// mPanel.add(speedLabel);
// mPanel.add(speed);
getContentPane().add(mPanel, BorderLayout.NORTH);
getContentPane().add(mHerdPanel, BorderLayout.CENTER);
}
/**
* Directs ActionEvents to the proper functions
* @param event
*/
@Override
public void actionPerformed(ActionEvent event)
{
String e = event.toString();
if(e.equals(GLOBAL.CLOSE))
{
System.exit(0);
}
else if(e.equals(GLOBAL.START))
{
GLOBAL.active = true;
playGame();
}
else if(e.equals(GLOBAL.STOP))
{
GLOBAL.active = false;
}
else if(e.equals(GLOBAL.NEWGAME))
{
initArrays();
mHerdPanel.paintImage();
}
else if(e.equals(GLOBAL.RESETGRID))
{
GLOBAL.herd0 = GLOBAL.startHerd;
GLOBAL.herd1 = GLOBAL.startHerd;
GLOBAL.activeArray = 0;
mHerdPanel.paintImage();
}
else if (e.equals(GLOBAL.ABOUT))
{
JOptionPane.showMessageDialog(null, "Game of Life\n Developed by Brendan Kristiansen with MSU Storytelling.");
}
else if (e.equals(GLOBAL.RULES))
{
}
}
/**
* Directs ChangeEvents to the proper functions
* @param e
*/
@Override
public void stateChanged(ChangeEvent e)
{
GLOBAL.delay = speed.getValue();
}
/**
* initializes byte arrays to be 0
*/
public void initArrays()
{
GLOBAL.herd0 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
GLOBAL.herd1 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
for(int i = 0; i <= GLOBAL.HEIGHT - 1; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH - 1; j++)
{
GLOBAL.herd0[i][j] = 0;
}
}
GLOBAL.herd1 = GLOBAL.herd0;
GLOBAL.activeArray = 0;
GLOBAL.arraySwitches = 0;
}
/**
*Controls the advancement of the game
*/
public void playGame()
{
GLOBAL.startHerd = GLOBAL.herd0;
if (GLOBAL.active == true)
{
while(GLOBAL.active == true)
{
nextFrame();
try
{
wait(GLOBAL.delay);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
else
{
nextFrame();
}
}
/**
*Advances Game of Life by one frame
*/
public void nextFrame()
{
if (GLOBAL.activeArray == 0)
{
for(int i = 0; i <= GLOBAL.HEIGHT; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH; j++)
{
int neighbors = countNeighbors(i, j, GLOBAL.herd0);
if (neighbors == 3 || neighbors == 4)
{
GLOBAL.herd1[i][j] = 1;
}
else
{
GLOBAL.herd1[i][j] = 0;
}
}
}
GLOBAL.activeArray = 1;
mHerdPanel.paintImage();
}
else
{
for(int i = 0; i <= GLOBAL.HEIGHT; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH; j++)
{
int neighbors = countNeighbors(i, j, GLOBAL.herd1);
if (neighbors == 3 || neighbors == 4)
{
GLOBAL.herd0[i][j] = 1;
}
else
{
GLOBAL.herd0[i][j] = 0;
}
}
}
GLOBAL.activeArray = 0;
mHerdPanel.paintImage();
}
GLOBAL.arraySwitches++;
}
/**
* Counts the living neighbors of a given cell in a herd
* @param i
* @param j
* @param herd
* @return
*/
public int countNeighbors(int i, int j, byte[][] herd)
{
int neighbors = 0;
if(i == 0 && j == 0) //Top left case
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom Neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
}
else if(i == 0 && j == GLOBAL.WIDTH) //Top right case
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(i == GLOBAL.HEIGHT && j == 0) //Bottom left case
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
}
else if(i == GLOBAL.HEIGHT && j == GLOBAL.WIDTH) //Bottom right case
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(i == 0) //Top Row
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(j == 0) //Left side
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
}
else if(i == GLOBAL.HEIGHT) //Bottom Row
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(j == GLOBAL.WIDTH) //Right side
{
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
}
else //Middle of herd
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
}
return neighbors;
}
}
And the HerdPanel class. This should be a grid which you can click on to change the color of a cell, then play Game Of Life with the cells you have highlighted:
/**
*
* @author Brendan Kristiansen
*/
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
//https://www.shodor.org/stella2java/rgbint.htmlhttps://www.shodor.org/stella2java/rgbint.html
public class HerdPanel extends JPanel implements MouseListener, MouseMotionListener
{
Graphics2D g;
Graphics2D g2;
BufferedImage grid;
BufferedImage bisonCell;
/**
* Constructor
*/
public HerdPanel()
{
setSize(500, 500); //Width, Height
addMouseListener(this);
addMouseMotionListener(this);
try
{
bisonCell = ImageIO.read(new File("bison.png"));
}
catch (IOException e)
{
System.out.println(e);
}
grid = new BufferedImage(GLOBAL.WIDTH, GLOBAL.HEIGHT, 1);
paintImage();
//g = grid.createGraphics();
}
/**
* Converts byte[][] array to BufferedImage
*/
public void paintImage()
{
if (GLOBAL.activeArray == 0)
{
for (int i = 0; i <= GLOBAL.WIDTH - 1; i++)
{
for (int j = 0; j <= GLOBAL.HEIGHT - 1; j++)
{
if (GLOBAL.herd0[j][i] == 0)
{
grid.setRGB(j, i, 16777215);
} else
{
grid.setRGB(j, i, 0);
}
}
}
}
else
{
for (int i = 0; i <= GLOBAL.WIDTH; i++)
{
for (int j = 0; j <= GLOBAL.HEIGHT; j++)
{
if (GLOBAL.herd1[j][i] == 0)
{
grid.setRGB(j, i, 16777215);
} else
{
grid.setRGB(j, i, 0);
}
}
}
}
g = grid.createGraphics();
super.paintComponent(g);
g.drawImage(grid, null, 0, 0);
repaint();
}
@Override
public void mouseClicked(MouseEvent e)
{
int xClick = (int)(e.getX() / GLOBAL.WIDTH);
int yClick = (int) (e.getY() / GLOBAL.HEIGHT);
if(GLOBAL.activeArray == 0)
{
GLOBAL.herd0[yClick][xClick] = 1;
}
else
{
GLOBAL.herd1[yClick][xClick] = 1;
}
paintImage();
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
@Override
public void mouseDragged(MouseEvent e)
{
}
@Override
public void mouseMoved(MouseEvent e)
{
}
}