1

모두의 새로운 세대의 재귀/루핑 계산.The Game of Life

Game Of Life 응용 프로그램의 다음 세대 (corrector)가 정확하게 계산됩니다. 게임은 예상대로 작동하지만 새로운 세대를 원할 때마다 "다음"을 눌러야합니다. 세대를 돌리기 위해 "시작"버튼을 구현하는 데 문제가 있습니다. ("next"와 "start"의 차이점에 대한 링크를 참조하십시오.)

분명히 ActionListener 클래스 내부에 어떤 종류의 루프가 필요합니다. 개인 부울이 true 인 동안 actionListener 내부에서 nextGen()을 반복적으로 호출 해 보았습니다. 프로그램이 충돌합니다. 나는 또한 어떤 종류의 기다림을 시도했다. 그러나 그것은 중요하지 않다.

nextGen()의 10 줄을 배치하면 실제로 10 회 반복됩니다. 청취자 내부에서, 나는 여기에서 어떤 종류의 기다림이 필요하다고 생각하고있다. (문제는 메모리와 관련이 있습니다.)

희망을 당신이 나를 도울 수 있습니다. :)

다음 세대는 이렇게 계산됩니다.

의 ActionListener 클래스 : 버튼 "다음"을 누르면

public class GameOfLifeListener implements ActionListener 
{ 

    // IMPORTANT: GameOfLifeGrid contains the GameOfLife collection! 
    private GameOfLifeGrid gameOfLife; 



    public GameOfLifeListener (GameOfLifeGrid g) 
    { 
     this.gameOfLife = g; 
    } 

    @Override 
    public void actionPerformed (ActionEvent e) 
    { 
     // Get actionCommand 
     String ac = e.getActionCommand(); 

     if (ac.equals("next")) 
     { 
      // Method calculates next generation 
      nextGen(); 
     } 
     if (ac.equals("start")) 
     { 
      // ADDED CODE: See class GameOfLifeGrid in bottom. 
      gameOfLife.start(); 
     } 
    } 

    private void nextGen () 
    { 
     // Get Next generation 
     gameOfLife.getCollection().nextGen(); 

     // Repaint 
     gameOfLife.repaint(); 
    } 
} 

의 actionListener는 GameOfLife 객체에 nextGen()를 실행합니다. 어떻게 nextGen() 메소드가 작동하는 것은 중요하지 않지만 여기를 GameOfLife 클래스

public class GameOfLife extends CellCollection 
{ 
    // Temporary array for new generation . We must add next generations alive cells HERE. 
    // Else the calculations of the current generation will fail. 
    private Cell[][] nextGen = null; 

    public void nextGen () 
    { 
     // Create the new Array holding next generation 
     prepareNextCollection(); 

     // Iterate the whole grid 
     for (int row = 0; row < super.rows; row++) 
     { 
      for (int col = 0; col < super.cols; col++) 
      { 
       ruleOne(row, col); 
      } 
     } 

     // Set the new collection to superClass. 
     // Super class holds the collection that will be drawn 
     super.setCollection(nextGen); 
    } 


    private void ruleOne (int row, int col) 
    { 
     // Calculations not important. It works like expected. 
    } 

    private void prepareNextCollection () 
    { 
     this.nextGen = new Cell[rows][cols]; 
    } 

이의 일부와 함께 GameOfLifeGrid 클래스의 일부를 선택한다. 그리드와 살아있는 셀 (셀 배열)을 그립니다.

public class GameOfLifeGrid extends Grid 
{ 

    private GameOfLife collection = null; 

    // ADDED MEMBERS: Timer, int 
    private Timer timer; 
    private int updateEachMilliSec = 100; // Used in program. Not in this code 

    @Override 
    public void paintComponent (Graphics g) 
    { 
     super.paintComponent(g); 
     drawCells(g); 
    } 

    private void drawCells (Graphics g) 
    { 
     for (int row = 0; row < rows; row++) 
     { 
      for (int col = 0; col < cols; col++) 
      { 
       if (! collection.isEmptyPos(row, col)) 
       { 
        g.fillRect(super.calcX(col), super.calcY(row), cellSize, cellSize); 
       } 
      } 
     } 
    } 

    // ADDED METHOD! 
    public void start() 
    { 
     // Create a timer object. The timer will send events each 100 ms. 
     // The events will be caught by the ActionListener returned from 
     // nextGenlistener(). VOILA! 

     timer = new Timer(100, nextGenlistener()); 

     // Start sending events to be caught! 
     timer.start(); 
    } 

    // ADDED METHOD! The ActionListener who will catch the events sent by timer. 
    private ActionListener nextGenlistener() 
    { 
     return new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       // Get next generation 
       collection.nextGen(); 

       // Repaint 
       repaint(); 
      } 
     }; 
    } 

답변

1

문제는 actionPerformed 메소드에서()에 Thread.sleep와 루프하려고 할 때, 당신은 Event Dispatch Thread를 차단하고 있다는 점이다. 스레드의 제어권을 해제 할 때까지 아무 것도 다시 그릴 수 없으므로 actionPerformed 메소드가 끝나면 재 페인트 요청이 스풀링되고 즉시 실행됩니다.

new Timer(5000, new ActionListener(){ 
    public void actionPerformed(ActionEvent e) { 
    panel.repaint(); 
    } 
}).start(); 
+0

그것은 나에게이 권리를 얻기 위해 오랜 시간이 걸렸습니다 :

간단한 솔루션은 일정한 간격으로이 라인을 따라 뭔가를 이벤트를 발생하는 javax.swing.Timer를 사용하는 것입니다. 나는 올바른 방향으로 어떤 점도 발견하지 못했을 것입니다. 고맙습니다! –

관련 문제