2012-04-01 2 views
1

저는 Conway의 Game of Life의 그래픽 모델을 만드는 프로그램을 만들고 있습니다.하지만 게임을 시작한 후에는 아무것도 할 수 없습니다. 버튼이 작동하지 않고 그리드가 변경되지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?Java Game of Life 프로그램이 작동하지 않는 이유는 무엇입니까?

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 

    } 
}  

누군가가 내게 무엇이 잘못되었다고 말할 수 있다면, 그것은 굉장 할 것입니다.

+0

애플릿은 [이벤트 발송 스레드] (http://download.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)의 GUI 객체 여야합니다. – trashgod

+0

이 [Game of Life] (http://stackoverflow.com/a/8200046/418556) 버전도 참조하십시오. 애플릿은 고급 주제입니다. 'JFrame' 기반 앱 코드. 순간. –

답변

5

하나는 당신이 긴 프로세스를 실행하려고 시도하고 있다는 점이다이 얻을 것이다 당신은 문제를 해결 시작 Event Dispatch Thread 또는 EDT라고도하는 Swing 이벤트 스레드는 실제로 프로그램을 고정시킵니다.

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

    // ... 

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

    // ... 

} 

당신이 while(true) 루프 및 이벤트 스레드에서 호출해야 어느 쪽도 아니의 Thread.sleep(...) 모두 가지고 :이 문제는 여기서 발생을 참조하십시오.

대신 Swing Timer을 사용해야합니다.

스윙 이벤트 스레드에 대한 자세한 내용은 Concurrency in Swing을 참조하십시오.

또한 (1), 세포가 초기화되도록 허용합니까? 모든 세대와 함께 살아있는 세포가 없다면 빈 그리드 만 보이게 될 것입니다. 하나 이상의 구성 요소에 MouseListener를 추가해야합니까? 나는 이것이 좋은 생각 일 것이라고 생각한다.

또한 (2) 버튼은 일반적으로 Swing button tutorial에 설명 된대로 ActionListeners를 추가 할 때 훨씬 잘 작동합니다. 스윙 튜토리얼을 들으셨습니까? 그렇지 않다면, 그들을 체크 아웃하십시오 (here) 그들이 당신에게 상당히 도움이 될 것이라고 생각합니다.

또한 (3) 한 번에 너무 많은 문제를 해결하려고하는 것보다 더 많이 물어 뜯을 수 있습니다. 이와 비슷한 GUI를 만들 때, 저는 프로그램의 각 부분을 독립적으로 작업하고 모든 것을 하나의 큰 프로그램으로 결합하기 전에 먼저 작동 시키려고합니다. 예를 들어, 먼저 비 GUI 모델에서 작업하고 모델의 메소드를 호출하는 테스트 코드를 통해 실행하여 세대를 작동 시키십시오. GUI의 각 부분에 대한 다음 작업은 JButton을 포함하여 한 번에 하나씩, 그 다음 MouseListener, 그리고 삶의 게임을 보여준 다음 세대를 구현합니다.

더 작은 테스트 프로그램을 디버그 한 다음 전체를 디버깅하려고 시도하는 것이 훨씬 쉽습니다. 나를 신뢰하십시오.

+0

도움에 감사드립니다. 이것은 분명히 그것이 작동하도록 도와 줄 것입니다. – Areth

+0

@Areth : 천만에요. 또한 "Also (3)"을 읽으십시오. –

+1

@HovercraftFullOfEels 'while (paused = false)'이 'while (true)'과 동일합니까? 그것은 대입이 아니라 비교 ('==')입니다. 나는 이것이 유효한 자바 구문인지조차 몰랐다. 내 IDE는'while (false)'iso'와 같다고 제안한다. while (true)' – Robin

0

아마도 init()에서 super.init()를 시도해보십시오.

+2

이 답변은 어떻게 도움이 될 수 있습니까? 진지하게. –

+1

@ RayTayek - 답변을 게시하기 전에 정말로 확인해야합니다. –

1

프로그램이 시작되지만 다른 문제가 있습니다.

변경 :

cell = new cellClass(); 

사람 : 당신의 주요 문제의

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

고마워, 나는 그것을 새로운 프로젝트 (새로운 프로젝트에서)로 C & P하고 그것을로드했다. 내가 알아 차렸을 것 같은 것을 지적 해 주셔서 감사합니다. – Areth

관련 문제