简体   繁体   English

为什么我的Java游戏人生计划无法正常工作?

[英]Why isn't my Java Game of Life program working?

I'm working on a program that makes a graphical model of Conway's Game of Life, but it's not letting me do anything once it's launched; 我正在开发一个程序,该程序可以创建Conway的《人生游戏》的图形模型,但是一旦发布,它并不能让我做任何事。 the buttons don't work and the grid isn't changing. 按钮不起作用,网格也没有变化。 What am I doing wrong? 我究竟做错了什么?

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;


public class gameOfLife extends JApplet{
    private static final long serialVersionUID = 1L;

cellClass cell;

public void init() {
    Container contentWindow = getContentPane();
    cell = new cellClass();{{
    setLayout(new FlowLayout()) }};
    contentWindow.add(cell);    
    }
} 

class grid extends JComponent{ 
    private static final long serialVersionUID = 2L;

    int XSIZE = 500;
    int YSIZE = 500;
    private int row;
    private int col;
    private int size = 5;
    private cellClass c;
    private Dimension preferredSize = new Dimension(XSIZE, YSIZE);

    public void paint(Graphics a) {
    int x, y;
        for(x=0; x<row; x++){
        for(y=0; y<col; y++){
            if(c.grid[x][y] != 0){
                a.drawRect(x * size, y * size, 5, 5);
            }
        }
    }
    a.drawRect(0, 0, XSIZE, YSIZE);

}

public grid(cellClass newGrid, int newRow, int newCol, int newSize) {
    setMinimumSize(preferredSize);
    setMaximumSize(preferredSize);
    setPreferredSize(preferredSize);
    this.row = newRow;
    this.col = newCol;
    this.size = newSize;
    this.c = newGrid;

}
}

class cellClass extends JPanel implements ActionListener{
private static final long serialVersionUID = 3L;

static final int ROW = 100;
static final int COL = 100;
static final int SIZE = 5;
static final int min = 2;
static final int max = 3;
static final int birth = 3;
public int genCount = 0;

public int[][] grid;
private int[][] nextGrid;

private GridBagLayout gridBag = new GridBagLayout();
private GridBagConstraints c = new GridBagConstraints();

JLabel title;
JLabel genCounter;
JButton oneGen;
JButton contPlay;
JButton stop;
public grid board;
public boolean paused = true;
public boolean canChange = true;

cellClass() {
    grid = new int [ROW][COL];
    nextGrid = new int[ROW][COL];

    makeGrid(grid);

    setLayout(gridBag);

    title = new JLabel("Game of Life Applet");
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    c.insets = new Insets(2,0,0,0);
    c.anchor = GridBagConstraints.WEST;
    add(title);

    board = new grid(this,ROW,COL,SIZE);
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 1;
    gridBag.setConstraints(board, c);
    add(board);

    oneGen = new JButton("Move one Generation");
    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 1;
    gridBag.setConstraints(oneGen, c);
    add(oneGen);

    contPlay = new JButton("Play");
    c.gridx = 1;
    c.gridy = 3;
    c.gridwidth = 1;
            contPlay.setVisible(true);
    gridBag.setConstraints(contPlay, c);
    add(contPlay);

    stop = new JButton("Stop");
    c.gridx = 2;
    c.gridy = 3;
    c.gridwidth = 1;
            stop.setVisible(false);
    gridBag.setConstraints(stop, c);
    add(stop);

    genCounter = new JLabel("Generation: 0");
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 1;
    gridBag.setConstraints(genCounter, c);
    add(genCounter);
}

class ButtonListener {
    public void addActionListener(ActionEvent e) throws InterruptedException {
        JButton source = (JButton)e.getSource();

        if(source == oneGen){
            nextGen();
        }
        if(source == contPlay){
            paused = false;
            canChange = false;
                            contPlay.setVisible(false);
                            stop.setVisible(true);
            while (paused = false) {
                nextGen();
                Thread.sleep(1000);
            }
        }
        if(source == stop) {
            paused = true;
            canChange = false;
                            stop.setVisible(false);
                            contPlay.setVisible(true);
        }
    }
}

public void mouseClicked(MouseEvent e){
    int xco = e.getX() - board.getX();
    int yco = e.getY() - board.getY();
    if((e.getComponent() == board) && (paused == true)){
        if(grid[xco/5][yco/5] == 1){
            grid[xco/5][yco/5] = 0;
            board.repaint();
        }else if(grid[xco/5][yco/5] == 0){
            grid[xco/5][yco/5] = 1;
            board.repaint();
        }
    }
}

public void makeGrid(int[][] emptyGrid) {
    int x, y;
    for(x = 0; x < ROW; x++){
        for(y = 0; y < COL; y++){
            emptyGrid[x][y] = 0;
        }
    }
}

public void nextGen() {
    getNextGen();
    board.repaint();
    genCount++;
    genCounter.setText("Generation: " + Integer.toString(genCount));        
}

public void getNextGen() {
    int x, y, neighbor;
    makeGrid(nextGrid);
    for(x = 0; x < ROW; x++){
        for(y=0; y<COL; y++){
            neighbor = calculate(x,y);

            if(grid[x][y] != 0){
                if((neighbor >= min) && (neighbor <= max)) {
                    nextGrid[x][y] = neighbor;
                }
            }else {
                if(neighbor == birth){
                    nextGrid[x][y] = birth;
                }
            }
        }
    }
    makeGrid(grid);
    copyGrid(nextGrid,grid);
}

public void copyGrid(int[][] source, int[][] newGrid) {
    int x, y;
    for(x=0; x<ROW; x++){
        for(y=0; y<COL; y++){
            newGrid[x][y] = source[x][y];
        }
    }
}

private int calculate(int x, int y){
    int a, b, total;

    total = (grid[x][y]);
    for (a = -1; a<= 1; a++) {
        for (b = -1; b <= 1; b++){
            if(grid[(ROW + (x + a)) % ROW][(COL + (y + b)) % COL] != 0) {
                total++;
            }
        }
    }
    return total;
}

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub

    }
}       

If anyone could tell me what's wrong with it, that would be awesome. 如果有人能告诉我这是怎么回事,那太好了。

One of your main problems is that you're attempting to run a long process on the Swing event thread, also known as the Event Dispatch Thread or EDT, and this in effect will freeze your program. 您的主要问题之一是您试图在Swing事件线程(也称为事件调度线程或EDT)上运行一个较长的过程,这实际上将冻结您的程序。 I see this problem occurring here: 我看到这里发生了这个问题:

class ButtonListener {
  public void addActionListener(ActionEvent e) throws InterruptedException {
     JButton source = (JButton) e.getSource();

     // ...

        while (paused = false) { // *******
           nextGen();
           Thread.sleep(1000);  // ******
        }
     }

     // ...

}

you have both a while(true) loop and a Thread.sleep(...) neither of which should be called on the event thread. 您有一个while(true)循环和一个Thread.sleep(...)两者都不应该在事件线程上调用。

Instead you should be using a Swing Timer . 相反,您应该使用Swing Timer

For more on the Swing event thread, please read Concurrency in Swing . 有关Swing事件线程的更多信息,请阅读Swing中的并发

Also (1), where do you allow cells to be initialized to being alive? 另外(1),您在哪里允许将单元格初始化为活动状态? Without live cells to start with all generations will show nothing but an empty grid? 没有世代相传的活细胞,只会显示一个空的网格吗? Do you need to add a MouseListener to one or more of your components? 您是否需要将MouseListener添加到一个或多个组件中? I think that this would be a good idea. 我认为这将是一个好主意。

Also (2) buttons generally work a lot better when you add ActionListeners to them as is well outlined in the Swing button tutorial . 同样(2),当您向其添加ActionListener时,按钮通常会更好地工作,如Swing按钮教程中所述 Have you gone through the Swing tutorials? 您是否已完成Swing教程? If not, please check them out (find them here ) as they will help you quite a bit, I think. 如果没有,请检查一下(在此处查找),因为它们对您有很大帮助。

Also (3) you may be biting off more than you can chew in that you're trying to solve too many problems at one time. 同样(3),您一次尝试解决太多问题的能力可能会比想得到的要好得多。 When I create a GUI similar to this, I like to work on each portion of the program in isolation and get it working first before combining it all into one big program. 当我创建与此类似的GUI时,我希望独立地处理程序的每个部分,并先使其工作,然后再将其组合成一个大程序。 So for instance, first work on the non-GUI model and get the generations working by running it through test code that calls the model's methods. 因此,例如,首先在非GUI模型上工作,并通过调用该模型方法的测试代码运行它来使世代工作。 Next work on each portion of the GUI one at a time including the JButtons, then the MouseListener, then the display of the game of life, then implementing the generations. 接下来,一次处理GUI的每个部分,包括JButton,MouseListener,生活游戏的显示,然后实现各代。

It is much easier to debug smaller test programs then to try to debug the whole shebang, trust me. 调试较小的测试程序要容易得多,然后尝试调试整个shebang,请相信我。

Your program starts for me but has other problems. 您的程序为我启动,但是还有其他问题。 This will get you started with fixing the problems: 这将帮助您开始解决问题:

Change: 更改:

cell = new cellClass();

To: 至:

cell = new cellClass(){{
  setLayout(new FlowLayout());
}}; 

也许在init()中尝试super.init()?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM