2013-05-11 46 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