有没有一种方法可以将数组显示为JFrame中不断变化的网格/条形图,作为生命游戏模拟的一部分?

时间:2019-02-06 19:06:54

标签: java swing graphics jframe jcomponent

我目前正在尝试设置《生命游戏》的迷你版,但是我正在努力使它在框架中可视化,使用数组生成网格。

这是我第一次使用界面,因此我决定通过修改后的条形图来显示网格和数组的比例。但是,当我尝试使用称为paintComponent的方法将图形/网格放置到框架中时,JComponent始终出现错误。尽管我确实将JFrame,JComponent和Graphic导入到主体中,但我还没有创建Graphic g。

主体

 JFrame frame = new JFrame();
 frame.setSize(400,200);
 frame.setTitle("Mini Game of Life");
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 for (int t = 0; t < 30; t++)
 {
      grid = LifeSweeper(grid, x, y);   //Line 104
      grid = next;  
      // Line below main Error
      JComponent component = paintComponent(Graphics g; x; y; int grid[][]);
      frame.add(component);

      frame.setVisible(true);
 }

paintComponent方法

public void paintComponent(Graphics g, int x, int y, int grid[][])
{
  for (int i = 0; i < x; i++) 
    {
        for (int j = 0; j < y; j++) 
        {

            if (grid[i][j] == 1) 
            {
                g.fillRect(x, y, 10, 10);
            }
        }
    }  
}

该计划是让生活类游戏在for循环内运行,这将更新框架图形,其中grid是游戏数组的当前版本,x和y是网格大小,其次是从数组返回的数组。 LifeSweeper方法。然后,paintComponent将生成图形并将其放置在框架中,并在for循环中进行更新。但是,JComponent不断返回错误,指出该行不是语句,以及如何缺少分号。我想有一个更简单的方法可以解决此问题,但是我无法在javadoc或其他页面中找到它。

编辑:我试图按原样运行程序,这是当前的错误/异常消息:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at lifegame.LifeGame.LifeSweeper(LifeGame.java:129)
at lifegame.LifeGame.main(LifeGame.java:104)

编辑2:根据要求添加了LifeSweeper方法。尚未添加注释,但是它运行了两个嵌套的for循环系列,第一个用于检查和计数相邻单元格,第二个根据生活规则更改单元格。

public static int[][] LifeSweeper(int[][] next, int a, int b)
{
    int cellFate[][] = new int[a][b];
    int cellsStatus[][] = new int [a][b];
    for (int x = 1; x < next.length-1; x++)
    {
        for (int y = 1; y < next[0].length-1; y++)
        {
            int cellCounter = 0;
            int cellStatus = 0;
            for (int i = -1; i <= 1; i++)   
            {
                for (int j = -1; j <= 1; i++)
                {
                    if (next[i][j] == 1) // Line 129
                    {
                        cellCounter++;
                    }
                    else if (next[0][0] == 1)
                    {
                        cellStatus = 1;
                    }
                }
            }
            cellFate[x][y] = cellCounter - 1;
            cellsStatus[x][y] = cellStatus;
        }
    }
    for (int x = 1; x < next.length-1; x++)
    {
      for (int y = 1; y < next[0].length-1; y++)
      {
          if (cellsStatus[x][y] == 0)
          {
              if (cellFate[x][y] == 0)
              {
                  next[x][y] = 0;
              }
              if (cellFate[x][y] == 3)
              {
                  next[x][y] = 1;
              }
          }
          if (cellsStatus[x][y] == 1)
          {
              if (cellFate[x][y] < 2)
              {
                  next[x][y] = 0;
              }
              if (cellFate[x][y] == 2 || cellFate[x][y] == 3)
              {
                  next[x][y] = 1;
              }
              if (cellFate[x][y] > 3)
              {
                  next[x][y] = 0;
              }
          }
      }
    } 
    return next;
}

1 个答案:

答案 0 :(得分:0)

例外是“嘿,您试图访问超出数组范围的元素,该元素大于0且小于数组的大小”。眼前的问题就在这里:

for (int i = -1; i <= 1; i++)   // i starts at -1 
        {
            for (int j = -1; j <= 1; i++) // jstarts at -1  Note that you are incrementing i, which is unrelated to the exception, but still probably not what you want.
            {
                if (next[i][j] == 1) // Line 129  - next[-1][-1] accessed, which is prior to the beginning of the array.  Exception thrown.

在生活游戏中,您需要考虑单元格位于网格边缘的情况。在第129行之前,请检查并确保不要尝试指向网格之外的位置。

关于129行的另一点,您提到打算检查该位置的单元格邻居,但从我的阅读看来,您似乎只检查了0,0单元格的邻居。您是否打算检查x+iy+j?这样就可以完成对单元格xy的检查。

paintComponent似乎还可以,但是您的代码中的以下代码片段也存在一些您可能会考虑的问题:

grid = LifeSweeper(grid, x, y); // LifeSweeper looks like a constructor for a class.  Being a function, you should call it lifeSweeper.  Before you posted line 129, I was very confused about why you were trying to construct a LifeSweeper named grid using itself.
grid = next;  //I remain confused about what next is in this context, as your grid already updated, presumably.
JComponent component = paintComponent(Graphics g; x; y; int grid[][]); //This won't compile, and even if it did, it looks like you're calling with a null g and an empty grid.  Probably not what you want.

您沿着正确的道路前进,但是遇到了经典的案例,每个曾经做过“人生游戏”模拟的人都首先遇到了我,包括我在学习编码时也包括在内。

对于您的paintComponent,所编写的代码存在多个问题,其中最重要的一点是您实际上不应直接调用paintComponent;窗口系统将在需要时执行此操作(您可以通过调用revalidate()repaint()之类的方法来发出信号)。我将看看How does paintComponent work,它将使您走上正确的道路。