带有 GUI 的 Java 捕食者-猎物模拟无法运行模拟 [英] Java predator-prey simulation with GUI can't run simulation

查看:29
本文介绍了带有 GUI 的 Java 捕食者-猎物模拟无法运行模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向捕食者-猎物模拟添加 GUI.它可以让用户选择他们想要做的模拟(涉及的物种),设置他们想要的模拟场大小,并显示模拟的进度和结果.

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.

这是我的 GUI 类的代码:

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.
            }
        }
    }
}

我的generate按钮生成的数据好像在我用剩下的按钮的时候没有访问到,但是我试了很久还是解决不了...

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...

这是我的代码:https://github.com/KasmaJC/predator-prey-simulation-with-图形界面

推荐答案

没关系...我找到了问题的根源:

Never mind... I find out where caused the problem:

当我单击这些按钮时,我再次创建新对象方法,这就是为什么当我使用其余按钮时不会访问生成按钮生成的数据.

I create new objects method again when I click those button, that's why the data generated by generate button is not accessed when I use rest of the buttons.

private class ResetbuttHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
        simulator = new Simulator();
        Simulator reseting = new Simulator();// HERE
        reseting.reset();        
    }
}   
private class NextstepbuttHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
        simulator = new Simulator();
        Simulator onestep = new Simulator();// HERE
        onestep.simulateOneStep();        
    }
}
private class LongstepbuttHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
        simulator = new Simulator();
        Simulator longstep = new Simulator();// HERE
        longstep.runLongSimulation();        
    }
} 

我应该使用与生成按钮使用相同的对象方法.

I should have use the same object method which generate button use.

但后来又演变成了另一个问题……如何让按钮的其余部分使用与生成按钮相同的对象方法,但又不再次生成字段?(也许我猜这是一个逻辑问题...)

But then it evolved into another problem... How do I let the rest of the button use the same object method which generate button use, but also don't generate the field again? (Maybe that's a logic problem I guess...)

我可能会为此问另一个问题...

I might ask another question for this...

这篇关于带有 GUI 的 Java 捕食者-猎物模拟无法运行模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆