I'm trying to add a GUI to the predator-prey simulation. It can allow users to choose which simulation(species involved) they want to do, set the simulation field size they want, and show the progress of the simulation and result.
The question is after I generate the field, I can't reset the simulation or run the next step or run the next hundred steps by clicking the buttons I set, not to mention show the progress of the simulation.
Here is the code of my GUI Class:
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JComboBox;
import javax.swing.JTextField;
/**
* Illustrate the GUI of the simulator.
*
* @author Jeremy Chu
* @version 2021.06.02
*/
public class GUI extends JFrame
{
private JFrame frame;
private JPanel panel1;
private JPanel panel2;
private JPanel panel3;
private Simulator simulator;
private Animal animal;
private Field field;
private SimulatorView view;
//species2 = {"RF","RW","RB","RH","FW","FB","FH","WB","WH","BH"};
private SimulatorRF simulatorRF;
private SimulatorRW simulatorRW;
private SimulatorRB simulatorRB;
private SimulatorRH simulatorRH;
private SimulatorFW simulatorFW;
private SimulatorFB simulatorFB;
private SimulatorFH simulatorFH;
private SimulatorWB simulatorWB;
private SimulatorWH simulatorWH;
private SimulatorBH simulatorBH;
//species3 = {"RFW","RFB","RFH","RWB","RWH","RBH","FWB","FWH","FBH","WBH"};
private SimulatorRFW simulatorRFW;
private SimulatorRFB simulatorRFB;
private SimulatorRFH simulatorRFH;
private SimulatorRWB simulatorRWB;
private SimulatorRWH simulatorRWH;
private SimulatorRBH simulatorRBH;
private SimulatorFWB simulatorFWB;
private SimulatorFWH simulatorFWH;
private SimulatorFBH simulatorFBH;
private SimulatorWBH simulatorWBH;
//species4 = {"RFWB","RFWH","RFBH","RWBH","FWBH"};
private SimulatorRFWB simulatorRFWB;
private SimulatorRFWH simulatorRFWH;
private SimulatorRFBH simulatorRFBH;
private SimulatorRWBH simulatorRWBH;
private SimulatorFWBH simulatorFWBH;
JComboBox comboBox1;
JComboBox comboBox2;
JComboBox comboBox3;
JComboBox comboBox4;
JButton button;
JButton button1;
JButton button2;
JButton button3;
JButton button4;
JButton button5;
JButton reset_butt;
JButton nextstep_butt;
JButton longstep_butt;
JTextField depthtxt;
JTextField widthtxt;
int depth = 100;
int width = 100;
int version = 0;
public GUI() {
frame = new JFrame();
panel1 = new JPanel();
panel2 = new JPanel();
//panel3 = new JPanel();
panel1.setBackground(Color.lightGray);
panel2.setBackground(Color.gray);
//panel3.setBackground(Color.blue);
String[] species2 = {"","Rabbits & Foxes","Rabbits & Wolves","Rabbits & Bears","Rabbits & Hunters","Foxes & Wolves",
"Foxes & Bears","Foxes & Hunters","Wolves & Bears","Wolves & Hunters","Bears & Hunters"};
String[] species3 = {"","Rabbits & Foxes & Wolves","Rabbits & Foxes & Bears","Rabbits & Foxes & Hunters","Rabbits & Wolves & Bears",
"Rabbits & Wolves & Hunters","Rabbits & Bears & Hunters","Foxes & Wolves & Bears","Foxes & Wolves & Hunters",
"Foxes & Bears & Hunters","Wolves & Bears & Hunters"};
String[] species4 = {"","Rabbits & Foxes & Wolves & Bears","Rabbits & Foxes & Wolves & Hunters","Rabbits & Foxes & Bears & Hunters",
"Rabbits & Wolves & Bears & Hunters","Foxes & Wolves & Bears & Hunters"};
String[] species5 = {"","ALL"};
comboBox1 = new JComboBox(species2);
comboBox1.addActionListener(new Combobox1Handler());
comboBox1.setEnabled(false);
comboBox2 = new JComboBox(species3);
comboBox2.addActionListener(new Combobox2Handler());
comboBox2.setEnabled(false);
comboBox3 = new JComboBox(species4);
comboBox3.addActionListener(new Combobox3Handler());
comboBox3.setEnabled(false);
comboBox4 = new JComboBox(species5);
comboBox4.addActionListener(new Combobox4Handler());
comboBox4.setEnabled(false);
JLabel label1 = new JLabel("");
JLabel label2 = new JLabel("Choose Options to generate Simulation");
JLabel label3 = new JLabel("");
JLabel label4 = new JLabel("Choose species in the field: ");
JLabel label5 = new JLabel("");
JLabel label6 = new JLabel("<html><font size='4'color=gray> Rabbits</font> <font size='4'color=orange> Foxes</font><font size='4'color=blue> Wolves</font><font size='4'color=red> Bears</font><font size='4'color=black> Hunters</font></html>");
JLabel label7 = new JLabel("");
JLabel label17 = new JLabel("");
JLabel label18 = new JLabel("");
JLabel label8 = new JLabel("Simulate:");
JLabel label9 = new JLabel("");
JLabel label10 = new JLabel("");
JLabel label11 = new JLabel("depth:");
JLabel label12 = new JLabel("Width:");
JLabel label13 = new JLabel("");
JLabel label14 = new JLabel("Reset");
JLabel label15 = new JLabel("Next step");
JLabel label16 = new JLabel("Next hundred step");
button1 = new JButton("Two species");
button1.addActionListener(new Button1Handler());
button2 = new JButton("Three species");
button2.addActionListener(new Button2Handler());
button3 = new JButton("Four species");
button3.addActionListener(new Button3Handler());
button4 = new JButton("All");
button4.addActionListener(new Button4Handler());
button5 = new JButton("Reset");
button5.addActionListener(new Button5Handler());
button = new JButton("Generate Field");
button.addActionListener(new ButtonHandler());
reset_butt = new JButton("Reset");
reset_butt.addActionListener(new ResetbuttHandler());
nextstep_butt = new JButton("Next step");
nextstep_butt.addActionListener(new NextstepbuttHandler());
longstep_butt = new JButton("Next hundred steps");
longstep_butt.addActionListener(new LongstepbuttHandler());
depthtxt = new JTextField();
depthtxt.setText("100");
//depthtxt.setEnabled(false);
widthtxt = new JTextField();
widthtxt.setText("100");
panel1.setLayout(new GridLayout(7,5,10,0));
panel1.add(label1); panel1.add(label2); panel1.add(label3);
panel1.add(label4); panel1.add(label5); panel1.add(label6);
panel1.add(button1); panel1.add(button2); panel1.add(button3);
panel1.add(comboBox1); panel1.add(comboBox2); panel1.add(comboBox3);
panel1.add(button4); panel1.add(label7); panel1.add(label18);
panel1.add(comboBox4); panel1.add(label17); panel1.add(button5);
panel2.setLayout(new GridLayout(5,4,10,0));
panel2.add(label8); panel2.add(label9); panel2.add(label10);
panel2.add(label11); panel2.add(label12); panel2.add(label13);
panel2.add(depthtxt); panel2.add(widthtxt); panel2.add(button);
panel2.add(reset_butt); panel2.add(nextstep_butt); panel2.add(longstep_butt);
//panel3.setLayout(new GridLayout(5,4,10,0));
frame.add(panel1,BorderLayout.NORTH);
frame.add(panel2,BorderLayout.SOUTH);
//frame.add(panel3,BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Predator and Prey simulator");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
new GUI();
}
private class Button1Handler implements ActionListener{//Two Species
public void actionPerformed(ActionEvent e){
button2.setEnabled(false);
button3.setEnabled(false);
button4.setEnabled(false);
comboBox1.setEnabled(true);
comboBox2.setEnabled(false);
comboBox3.setEnabled(false);
comboBox4.setEnabled(false);
}
}
private class Button2Handler implements ActionListener{//Three Species
public void actionPerformed(ActionEvent e){
button1.setEnabled(false);
button3.setEnabled(false);
button4.setEnabled(false);
comboBox1.setEnabled(false);
comboBox2.setEnabled(true);
comboBox3.setEnabled(false);
comboBox4.setEnabled(false);
}
}
private class Button3Handler implements ActionListener{//Four Species
public void actionPerformed(ActionEvent e){
button1.setEnabled(false);
button2.setEnabled(false);
button4.setEnabled(false);
comboBox1.setEnabled(false);
comboBox2.setEnabled(false);
comboBox3.setEnabled(true);
comboBox4.setEnabled(false);
}
}
private class Button4Handler implements ActionListener{//All Species
public void actionPerformed(ActionEvent e){
button1.setEnabled(false);
button2.setEnabled(false);
button3.setEnabled(false);
comboBox1.setEnabled(false);
comboBox2.setEnabled(false);
comboBox3.setEnabled(false);
comboBox4.setEnabled(true);
}
}
private class Button5Handler implements ActionListener{//Reset Species
public void actionPerformed(ActionEvent e){
button1.setEnabled(true);
button2.setEnabled(true);
button3.setEnabled(true);
button4.setEnabled(true);
comboBox1.setEnabled(false);
comboBox2.setEnabled(false);
comboBox3.setEnabled(false);
comboBox4.setEnabled(false);
comboBox1.setSelectedIndex(0);
comboBox2.setSelectedIndex(0);
comboBox3.setSelectedIndex(0);
comboBox4.setSelectedIndex(0);
}
}
private class Combobox1Handler implements ActionListener{
public void actionPerformed(ActionEvent e){
//species2 = {"RF","RW","RB","RH","FW","FB","FH","WB","WH","BH"}
if(comboBox1.getSelectedIndex() == 1){//RF
version = 1;
}
else if(comboBox1.getSelectedIndex() == 2){//RW
version = 2;
}
...
else if(comboBox1.getSelectedIndex() == 10){
version = 10;
}
}
}
private class Combobox2Handler implements ActionListener{
public void actionPerformed(ActionEvent e){
//species3 = {"RFW","RFB","RFH","RWB","RWH","RBH","FWB","FWH","FBH","WBH"};
if(comboBox2.getSelectedIndex() == 1){
version = 11;
}
else if(comboBox2.getSelectedIndex() == 2){
version = 12;
}
...
else if(comboBox2.getSelectedIndex() == 10){
version = 20;
}
}
}
private class Combobox3Handler implements ActionListener{
public void actionPerformed(ActionEvent e){
//species4 = {"RFWB","RFWH","RFBH","RWBH","FWBH"};
if(comboBox3.getSelectedIndex() == 1){
version = 21;
}
else if(comboBox3.getSelectedIndex() == 2){
version = 22;
}
...
else if(comboBox3.getSelectedIndex() == 5){
version = 25;
}
}
}
private class Combobox4Handler implements ActionListener{
public void actionPerformed(ActionEvent e){
//species5 = {"All"};
if(comboBox4.getSelectedIndex() == 1){
version = 0;
}
}
}
private class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
String depthstr = depthtxt.getText();
String widthstr = widthtxt.getText();
int depth = Integer.parseInt(depthstr);
int width = Integer.parseInt(widthstr);
switch(version) {
case 0:
Simulator setsize = new Simulator();
setsize.Simulator(depth,width);
break;
case 1:
SimulatorRF setsizeRF = new SimulatorRF();
setsizeRF.SimulatorRF(depth,width);
break;
case 2:
SimulatorRW setsizeRW = new SimulatorRW();
setsizeRW.SimulatorRW(depth,width);
break;
...
case 25:
SimulatorFWBH setsizeFWBH = new SimulatorFWBH();
setsizeFWBH.SimulatorFWBH(depth,width);
break;
}
}
}
private class ResetbuttHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
simulator = new Simulator();
Simulator reseting = new Simulator();
reseting.reset();//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
}
}
private class NextstepbuttHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
simulator = new Simulator();
Simulator onestep = new Simulator();
onestep.simulateOneStep();//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
}
}
private class LongstepbuttHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
simulator = new Simulator();
Simulator longstep = new Simulator();
longstep.runLongSimulation();//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
}
}
}
And no matter I click the button "Reset" or "Next Step" or "Next hundred steps", it showed up the same error message:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.simulateOneStep(Simulator.java:112)
at GUI.actionPerformed(GUI.java:463)
...
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.simulate(Simulator.java:95)
at Simulator.runLongSimulation(Simulator.java:85)
at GUI.actionPerformed(GUI.java:468)
...
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.reset(Simulator.java:132)
at GUI.actionPerformed(GUI.java:458)
...
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.simulate(Simulator.java:95)
at Simulator.runLongSimulation(Simulator.java:85)
...
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.simulateOneStep(Simulator.java:112)
at GUI$NextstepbuttHandler.actionPerformed(GUI.java:485)
...
java.lang.NullPointerException
at Simulator.simulateOneStep(Simulator.java:112)
java.lang.NullPointerException
at Simulator.simulateOneStep(Simulator.java:112)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.simulateOneStep(Simulator.java:112)
at GUI$NextstepbuttHandler.actionPerformed(GUI.java:481)
...
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Simulator.reset(Simulator.java:132)
at GUI$ResetbuttHandler.actionPerformed(GUI.java:474)
...
I know it may be hard to understand, but can anyone figure out what may probably go wrong with my code? Sorry for the inconvenience...
This is my first time posting so if there are any problems please let me know.
*Edit------------------------------------------------------------------------------------------------------
Here is the code of Simulator Class which may caused the problem:
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.Color;
/**
* A simple predator-prey simulator, based on a rectangular field
*
* @author Jeremy Chu
* @version 2021.05.30
*/
public class Simulator
{
// Constants representing configuration information for the simulation.
// The default width for the grid.
private static final int DEFAULT_WIDTH = 100;
// The default depth of the grid.
private static final int DEFAULT_DEPTH = 100;
// The probability that a hunter will be created in any given grid position.
private static final double HUNTER_CREATION_PROBABILITY = 0.05;
// The probability that a bear will be created in any given grid position.
private static final double BEAR_CREATION_PROBABILITY = 0.01;
// The probability that a wolf will be created in any given grid position.
private static final double WOLF_CREATION_PROBABILITY = 0.02;
// The probability that a fox will be created in any given grid position.
private static final double FOX_CREATION_PROBABILITY = 0.03;
// The probability that a rabbit will be created in any given grid position.
private static final double RABBIT_CREATION_PROBABILITY = 0.08;
// List of animals in the field.
private List<Animal> animals;
// The current state of the field.
private Field field;
// The current step of the simulation.
private int step;
// A graphical view of the simulation.
private SimulatorView view;
/**
* Construct a simulation field with default size.
*/
public void Simulator()
{
Simulator(100, 100);
}
/**
* Create a simulation field with the given size.
* @param depth Depth of the field. Must be greater than zero.
* @param width Width of the field. Must be greater than zero.
*/
public void Simulator(int depth, int width)
{
if(width <= 0 || depth <= 0) {
System.out.println("The dimensions must be greater than zero.");
System.out.println("Using default values.");
depth = DEFAULT_DEPTH;
width = DEFAULT_WIDTH;
}
animals = new ArrayList<Animal>();
field = new Field(depth, width);
// Create a view of the state of each location in the field.
view = new SimulatorView(depth, width);
view.setColor(Rabbit.class, Color.gray);
view.setColor(Fox.class, Color.orange);
view.setColor(Wolf.class, Color.blue);
view.setColor(Bear.class, Color.red);
view.setColor(Hunter.class, Color.black);
// Setup a valid starting point.
reset();
}
/**
* Run the simulation from its current state for a reasonably long period,
* e.g. 100 steps.
*/
public void runLongSimulation()
{
simulate(100);//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
}
/**
* Run the simulation from its current state for the given number of steps.
* Stop before the given number of steps if it ceases to be viable.
* @param numSteps The number of steps to run for.
*/
public void simulate(int numSteps)
{
for(int step = 1; step <= numSteps && view.isViable(field); step++) {//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
simulateOneStep();
}
}
/**
* Run the simulation from its current state for a single step.
* Iterate over the whole field updating the state of each
* wolf, fox and rabbit.
*/
public void simulateOneStep()
{
step++;
// Provide space for newborn animals.
List<Animal> newAnimals = new ArrayList<Animal>();
// Let all rabbits act.
for(Iterator<Animal> it = animals.iterator(); it.hasNext(); ) {//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
Animal animal = it.next();
animal.act(newAnimals);
if(! animal.isAlive()) {
it.remove();
}
}
// Add the newly born wolves, foxes and rabbits to the main lists.
animals.addAll(newAnimals);
view.showStatus(step, field);
}
/**
* Reset the simulation to a starting position.
*/
public void reset()
{
step = 0;
animals.clear();//*Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
populate();
// Show the starting state in the view.
view.showStatus(step, field);
}
/**
* Randomly populate the field with wolves, foxes and rabbits.
*/
private void populate()
{
Random rand = Randomizer.getRandom();
field.clear();
for(int row = 0; row < field.getDepth(); row++) {
for(int col = 0; col < field.getWidth(); col++) {
if(rand.nextDouble() <= HUNTER_CREATION_PROBABILITY) {
Location location = new Location(row, col);
Hunter hunter = new Hunter(true, field, location);
animals.add(hunter);
}
else if(rand.nextDouble() <= BEAR_CREATION_PROBABILITY) {
Location location = new Location(row, col);
Bear bear = new Bear(true, field, location);
animals.add(bear);
}
else if(rand.nextDouble() <= WOLF_CREATION_PROBABILITY) {
Location location = new Location(row, col);
Wolf wolf = new Wolf(true, field, location);
animals.add(wolf);
}
else if(rand.nextDouble() <= FOX_CREATION_PROBABILITY) {
Location location = new Location(row, col);
Fox fox = new Fox(true, field, location);
animals.add(fox);
}
else if(rand.nextDouble() <= RABBIT_CREATION_PROBABILITY) {
Location location = new Location(row, col);
Rabbit rabbit = new Rabbit(true, field, location);
animals.add(rabbit);
}
// else leave the location empty.
}
}
}
}
It seems that the data generated by my generate button is not accessed when I use rest of the buttons, but I have tried for a long time and still can't solve it...
Here are my codes: https://github.com/KasmaJC/predator-prey-simulation-with-GUI