0

こんにちは、いくつかのキューブをクリックしてデッドまたはアライブに設定するこのコードがあります。一連のルールに従って、Java は次のステップの後にどのセルがアライブ/デッドになるかを計算します。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
class GameOfLife implements ActionListener{
Scanner scanner;                                                               //to      read the text file
File file;
boolean play = false;
String filename = "birth.txt";                                                 //the file that has to be read
Cell[][] cells=new Cell[10][10];                                               //array containing all the cells
JButton nextButton;
JButton playButton;
JPanel buttonPanel;
JPanel cellPanel;
GridLayout gridLayout=new GridLayout(10,10);
JFrame frame=new JFrame();
void buildit(){
    readInput();
    frame.setSize(600,700);        
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    buttonPanel=new JPanel();
    buttonPanel.setPreferredSize(new Dimension(600,100));
    frame.add(buttonPanel, BorderLayout.PAGE_START);
    nextButton=new JButton("Next generation");
    playButton=new JButton("Play");
    nextButton.setPreferredSize(new Dimension(150,50));
    playButton.setPreferredSize(new Dimension(150,50));
    nextButton.addActionListener(this);
    playButton.addActionListener(this);
    frame.add(nextButton, BorderLayout.LINE_START);
    frame.add(playButton, BorderLayout.LINE_END);

    cellPanel=new JPanel();        
    cellPanel.setLayout(gridLayout);                                               //gives the panel a gridlayout
    cellPanel.setPreferredSize(new Dimension(600,600));
    frame.add(cellPanel, BorderLayout.PAGE_START);
    for(int i=0; i<100; i++){  
        cells[i%10][i/10]=new Cell();                                            //i/10 will be rounded down, so it equals the rownumber
        cellPanel.add(cells[i%10][i/10]);
        cells[i%10][i/10].addMouseListener(cells[i%10][i/10]);                   //add a mouselistener to the cell
        cells[i%10][i/10].setOpaque(true);                                       //makes the backgroundcolor visible
        cells[i%10][i/10].setBackground(Color.BLACK);
        cells[i%10][i/10].setBorder(BorderFactory.createLineBorder(Color.WHITE));

    }    

    frame.setVisible(true);
    for(int i=0; i<100; i++){  
        for(int j=0; j<9; j++){
            if((i%10-1+j%3>=0) && (i%10-1+j%3<10) && (i/10-1+j/3>=0) && (i/10-1+j/3<10) && !(j==4)){   //exclude cells that are outside the frame (non existant) and the cell itself  
                cells[i%10][i/10].setNeighbours(cells[i%10-1+j%3][i/10-1+j/3]);           //this adds all the neighbours to the arraylist
            }
        }
    }
}
public void actionPerformed(ActionEvent e){
    if(e.getSource()==nextButton){
        for(int i=0; i<100; i++){ 
            cells[i%10][i/10].calculateNextState(); 
        }
        for(int i=0; i<100; i++){  
            cells[i%10][i/10].updateToNextState();
        }
    }
    else{if (e.getSource()==playButton) {
      play = true;
      for (int p=0; p<3;p++) {

        for(int i=0; i<100; i++){ 
            cells[i%10][i/10].calculateNextState(); 
        }
        for(int i=0; i<100; i++){  
            cells[i%10][i/10].updateToNextState();
        }

    }

    }

    }
}

void readInput(){
    try{
        file = new File( filename);
        scanner = new Scanner( file );
        String nextGen="";                                                               //this string will contain the output
        int row=scanner.nextInt();                                                       //read the row number
        int col=scanner.nextInt();                                                       //and the column number
        Cell[][] cellen=new Cell[row][col];                                              //array containing all the cells
        for(int i=0; i<row*col; i++){
            cellen[i%row][i/col]=new Cell(); 
            if(scanner.next().equals(".")){
                cellen[i%row][i/col].setState(CellState.alive);                                     //set the state
            }
            else{
                cellen[i%row][i/col].setState(CellState.dead); 

            }

        }
        for(int i=0; i<row*col; i++){
            for(int j=0; j<9; j++){
                if((i%row-1+j%3>=0) && (i%row-1+j%3<row) && (i/col-1+j/3>=0) && (i/col-1+j/3<col) && !(j==4)){ 
                    cellen[i%row][i/col].setNeighbours(cellen[i%row-1+j%3][i/col-1+j/3]);            //set the neighbours
                }
            }
        }
        for(int i=0; i<row*col; i++){
            cellen[i%row][i/col].calculateNextState();                                  //calculate the next state for all the cells
        }
        for(int i=0; i<row*col; i++){
            cellen[i%row][i/col].updateToNextState();                                   //update all the cells to the next state
        }
        for(int i=0; i<row; i++){
            for(int j=0; j<col; j++){
                if(cellen[i%row][i/col].getCurrentState()==CellState.alive){                             //the cell is alive if getCurrentState is true
                    nextGen+="*";
                }
                else{
                    nextGen+=".";
                }
            }
            nextGen+=System.getProperty("line.separator");                              //add an enter after each row
        }
        System.out.println(nextGen);                                                    //print the next generation to the console
    }

    catch(FileNotFoundException e) {
        System.out.println( "Could not find or open file <"+filename+">\n"+e );         
    } 
}
public static void main(String[] args) {
    new GameOfLife().buildit();
}
}

私の問題は、計算を無制限に保持しようとすると、以下のコードでわかるように、プログラムがフリーズすることです

 else{if (e.getSource()==playButton) {
      play = true;
      for (int p=0; p<3;p++) {

        for(int i=0; i<100; i++){ 
            cells[i%10][i/10].calculateNextState(); 
        }
        for(int i=0; i<100; i++){  
            cells[i%10][i/10].updateToNextState();
        }

    }

    }

私は計算を 3 回しか実行しませんが、各計算の間に 1 秒の一時停止がある停止ボタン (作成されるジェット) まで、これらの無制限の回数を実行したいと考えています。私はすでにwhileループを試しましたが、これは私のアプリケーションをフリーズさせました一時停止と無制限の計算の両方に関するいくつかの助けが大いに期待されます

4

3 に答える 3

1

ここでの問題は、コードがSwing Event Dispatch Threadで実行されていることです。つまり、ボタン クリックへの応答や変更の描画などの処理に戻る前に、実行中のすべての処理を終了する必要があります。

調べることをお勧めします:

于 2013-10-23T23:15:16.997 に答える
0

簡単な方法は、ループ内に Thread.sleep(1000) を配置して進行状況を表示し、SwingUtilities.invokeLater() を使用してのみ UI を更新することです。これはあまり美しい解決策ではありませんが、うまくいくはずです。

于 2013-10-23T23:19:01.990 に答える