2013-05-11 69 views
0

我在Java中,這GUI類:動畫不能正常工作,除非你調整框架

import java.awt.Graphics; 
import java.awt.Color; 
import javax.swing.JFrame; 
public class GUI extends JFrame { 
    private boolean[][] board; 
    private int width; 
    private int height; 
    private int multiplier = 25; 
    private int xMarginLeft = 2; 
    private int xMarginRight = 1; 
    private int yMarginBottom = 3; 
    private int yMarginTop = 2; 

    public GUI(boolean[][] board) { 
     this.width = GameOfLife.getNextBoard().length + xMarginLeft; 
     this.height = GameOfLife.getNextBoard()[0].length + yMarginBottom; 
     setTitle("John Conway's Game of Life"); 
     setSize(width * multiplier, height * multiplier); 
     setVisible(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 

    public void paint(Graphics g) { 
     board = GameOfLife.getNextBoard(); 
     g.setColor(Color.black); 
     g.fillRect(0, 0, width * multiplier, height * multiplier); 
     g.setColor(Color.green); 
     for (int i = 0; i < board.length; i++) { 
      for (int j = 0; j < board[i].length; j++) { 
       if (board[i][j]) { 
        g.fillRect((i + xMarginRight) * multiplier, (j + yMarginTop) * multiplier, multiplier - 1, multiplier - 1); 
       } 
      } 
     } 
    } 
} 

這是從主類的一個片段:

public static void main(String[] args) { 
    GUI boardGraphics = new GUI(nextBoard); 
    boolean[][] board = new boolean[nextBoard.length][nextBoard[0].length]; 
    for (int gen = 0; gen < 25; gen++) { 
     for (int i = 0; i < nextBoard.length; i++) { 
      for (int j = 0; j < nextBoard[i].length; j++) { 
       board[i][j] = nextBoard[i][j]; 
      } 
     } 
     try { 
      boardGraphics.paint(null); 
     } 
     catch (NullPointerException e) {} 
     for (int i = 0; i < board.length; i++) { 
      for (int j = 0; j < board[i].length; j++) { 
       if (board[i][j] && !(countSurrounding(board, i, j) == 2 || countSurrounding(board, i, j) == 3)) { 
        nextBoard[i][j] = false; 
       } 
       else if (!board[i][j] && countSurrounding(board, i, j) == 3) { 
        nextBoard[i][j] = true; 
       } 
      } 
     } 
     try { 
      Thread.sleep(1000); 
     } 
     catch (InterruptedException e) {} 
    } 
} 

然而,當我運行程序,動畫只適用於如果我調整/最小化/最大化框架。這完全是錯誤的動畫方法?或者我的代碼在某些方面不正確?

+0

我看不到板的繪畫在哪裏繼續運行,我只看到一個調用來繪製一個空參數。我會建議你構建從面板擴展的板類,並管理所有刷新,而不是直接通過'JFrame'。 – Noe 2013-05-11 17:35:57

+0

1)爲了更快地獲得更好的幫助,請發佈[SSCCE](http://sscce.org/)。 2)將catch(Exception e){..']形式的代碼更改爲catch(Exception e){e.printStackTrace(); //非常翔實! 3)不要阻塞EDT(Event Dispatch Thread) - 當發生這種情況時,GUI將「凍結」。而不是調用'Thread.sleep(n)'實現一個Swing'Timer'來重複執行任務,或者一個'SwingWorker'執行長時間運行的任務。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 – 2013-05-12 05:44:23

回答

1

其實你是對的:這是錯誤的方法,以動畫:

  1. 你必須運行訪問在事件指派線程GUI類的所有代碼;
  2. 通過在Swing的Timer上安排重複任務來實現動畫,並且從不使用涉及Thread.sleep的循環。
+0

嗯,我認爲使用循環也是這種程序的有效方法@Marko Topolnik,但肯定會更難控制幀/刷新率。當然,如果使用swing的定時器,所有這些麻煩變得很容易處理。 – Noe 2013-05-11 17:34:51

+0

@Noe如果你想要一個循環,這意味着你基本上是在重新實現一個任務調度器:你將有一個線程不會做任何事情,但等待99%的時間,並且它所做的所有實際工作是提交一個「運行」到EDT。除了控制動畫步驟的數量稍微方便之外,這種方法實際上沒有什麼好處。 – 2013-05-11 17:43:49