Java 小程序 AWT-EventQueue-1 异常

发布于 2025-01-07 08:42:25 字数 1406 浏览 0 评论 0原文

我用 java 小程序编写了生命游戏的简单实现。 以下是 Applet模型。

当我单击按钮获取下一次迭代时,会抛出这些异常。

Z:\GameOfLife>appletviewer driver.html
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException:
 65
        at GameOfLifeApplet.mouseClicked(GameOfLifeApplet.java:63)
        at java.awt.Component.processMouseEvent(Component.java:6219)
        at java.awt.Component.processEvent(Component.java:5981)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4583)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4413)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre    ad.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre    ad.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

I wrote a simple implementation of the Game of life with java applets.
Here's is the source code for the Applet and the Model.

When I click the button to get the next iteration these Exceptions get thrown.

Z:\GameOfLife>appletviewer driver.html
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException:
 65
        at GameOfLifeApplet.mouseClicked(GameOfLifeApplet.java:63)
        at java.awt.Component.processMouseEvent(Component.java:6219)
        at java.awt.Component.processEvent(Component.java:5981)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4583)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4413)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre    ad.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre    ad.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

仙女山的月亮 2025-01-14 08:42:25

尝试使用此代码添加一次按钮,而不是每次调用 paint()。请注意,如果您单击网格外部(而不是按钮上),此源仍然会抛出 AIOOBE,但这似乎是一个基本逻辑错误,一旦按钮修复,您应该进行调查。

// <applet code='GameOfLifeApplet' width=580 height=650></applet>
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class GameOfLifeApplet extends Applet implements MouseListener,ActionListener
{
  //the x and y coordinates to get the location of the clicked points
  private int xCo, yCo;
  private int diff_x, diff_y;
  private GameOfLife game = new GameOfLife();
  private Button nextButton = null;
  public void init()
  {
    setLayout(null);
    nextButton = new Button("Next Stage");
    diff_x = diff_y = 600 / game.getGridSize();
    nextButton.setLocation(250, 575);
    nextButton.setSize(120, 30);
    // add the button once only!
    add(nextButton);
    addMouseListener(this);
  }

  private void drawEmptyGrid(Graphics g)
  {
    g.setColor(Color.white);
    g.fillRect(0,0,600,600);
    g.setColor(Color.black);
    for(int i=0;i<game.getGridSize();++i)
    {
      g.drawLine(0,i*diff_x,600,i*diff_x);
      g.drawLine(i*diff_x,0,i*diff_x,600);
    }
    g.setColor(Color.white);
  }

  public void paint(Graphics g)
  {
    drawEmptyGrid(g);
    g.setColor(Color.red);
    for(int i=0;i<game.getGridSize();++i)
    {
      for(int j=0;j<game.getGridSize();++j)
      {
        if( game.grid[i][j] )
        {
          g.fillRect(i*diff_x,j*diff_y,diff_x,diff_y);
        }
      }
    }
    g.setColor(Color.white);
  }

 // This method will be called when the mouse has been clicked.
 public void mouseClicked (MouseEvent me) {

  // Save the coordinates of the click lke this.
  xCo = me.getX();
  yCo = me.getY();

  int x_init = xCo / diff_x;
  int y_init = yCo / diff_y;

  System.out.println(x_init + "x" + y_init);
  game.grid[x_init][y_init] = true;
  //show the results of the click
  repaint();

 }

 // This is called when the mous has been pressed
 public void mousePressed (MouseEvent me) {}

 // When it has been released
 // not that a click also calls these Mouse-Pressed and Released.
 // since they are empty nothing hapens here.
 public void mouseReleased (MouseEvent me) {}

 // This is executed when the mouse enters the applet. it will only
 // be executed again when the mouse has left and then re-entered.
 public void mouseEntered (MouseEvent me) {}

 // When the Mouse leaves the applet.
 public void mouseExited (MouseEvent me) {}

 public void actionPerformed(ActionEvent evt)
  {
  // Here we will ask what component called this method
    if (evt.getSource() == nextButton)
    {
      System.out.println("I got clicked!");
      game.nextIteration();
      repaint();
    }
  }

}

class GameOfLife
{
  private final int GRID_SIZE = 64;
  public boolean [][] grid = new boolean[GRID_SIZE][GRID_SIZE];
  //default constructor
  public GameOfLife()
  {
    for(int i=0;i<GRID_SIZE;++i)
    {
      for(int j=0;j<GRID_SIZE;++j)
    {
      grid[i][j] = false;
    }
    }
  }

  public int getGridSize()
  {
    return GRID_SIZE;
  }

  public int getLiveNeighbors(int i,int j)
  {
    int neighbors = 0;
    for( int tmp_i = i-1; tmp_i <= i+1; ++tmp_i )
    {
      for( int tmp_j = j-1; tmp_j <= j+1; ++tmp_j )
      {
        if( tmp_i < 0 || tmp_i >= GRID_SIZE || tmp_j < 0 || tmp_j >= GRID_SIZE )
        {}
        else
        {
          if( grid[tmp_i][tmp_j] )
          {
            neighbors++;
          }
        }
      }
    }
    return neighbors;
  }

  public void nextIteration()
  {
    boolean [][] newGrid = new boolean[GRID_SIZE][GRID_SIZE];

    for(int i=0;i<GRID_SIZE;++i)
    {
      for(int j=0;j<GRID_SIZE;++j)
      {
        newGrid[i][j] = grid[i][j];
      }
    }

    for( int i=0;i<GRID_SIZE;++i)
    {
      for( int j=0;j<GRID_SIZE;++j)
      {
        int my_neighbors = getLiveNeighbors(i,j);
        if( !newGrid[i][j] && my_neighbors == 3)
        {
          grid[i][j] = true;
        }

        else if( newGrid[i][j] && ( my_neighbors == 2 || my_neighbors == 3 ) )
        {
          grid[i][j] = true;
        }

        else
        {
          grid[i][j] = false;
        }
      }
    }
    System.out.println("Change of assignment");
  }
}

进一步提示

  1. 在这个世纪不要使用 AWT 组件,而应使用 Swing。
  2. 不要使用 null 布局。自定义渲染区域不需要它,并且应该使用布局管理器来调整按钮的大小和位置(可能有一个边框将其填充)。

更新

此代码实现了上面“使用布局”的第二个建议,但将其作为练习留给读者,以将组件更新为本世纪可能使用的组件(即 Swing)。

下面的源代码在某种意义上“作弊”,以自然大小显示 GUI。这在小程序中很难做到,因为大小是由 HTML 设置的。但是,将 GUI 放入基于 Swing 的 JOptionPane 中,只需几行代码即可将其显示在屏幕上,并按其自然大小排列。

这是它在“自然大小”下的样子(我使用了一些数字,以使 GUI 更小)。

GameOfLifeApplet

// <applet code='GameOfLifeApplet' width=320 height=350></applet>
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class GameOfLifeApplet extends Applet implements ActionListener
{
    private Button nextButton = null;
    private Ecosystem ecosystem;

    public void init()
    {
        add(getGui());
    }

    public Component getGui() {
        Panel gui = new Panel(new BorderLayout(3,3));
        ecosystem = new Ecosystem();
        gui.add(ecosystem, BorderLayout.CENTER);
        nextButton = new Button("Next Stage");

        Panel p = new Panel(new FlowLayout());
        p.add(nextButton);
        gui.add(p, BorderLayout.SOUTH);
            nextButton.addActionListener(this);
        return gui;
    }

    public void actionPerformed(ActionEvent evt)
    {
        // Here we will ask what component called this method
        if (evt.getSource() == nextButton)
        {
            System.out.println("I got clicked!");
            ecosystem.nextIteration();
            ecosystem.repaint();
        }
    }

    public static void main(String[] args) {
        GameOfLifeApplet gola = new GameOfLifeApplet();
        // quick cheat to get it on-screen (packed).
        javax.swing.JOptionPane.showMessageDialog(null,gola.getGui());
    }
}

class Ecosystem extends Panel implements MouseListener {
    private GameOfLife game = new GameOfLife();
    //the x and y coordinates to get the location of the clicked points
    private int xCo, yCo;
    private int diff_x, diff_y;
    private int size = 300;

    Ecosystem() {
        diff_x = diff_y = 600 / game.getGridSize();
        setPreferredSize(new Dimension(size,size));
        addMouseListener(this);
    }

    public void nextIteration() {
        game.nextIteration();
    }

    private void drawEmptyGrid(Graphics g)
    {
        g.setColor(Color.white);
        g.fillRect(0,0,size,size);
        g.setColor(Color.black);
        for(int i=0;i<game.getGridSize();++i)
        {
            g.drawLine(0,i*diff_x,size,i*diff_x);
            g.drawLine(i*diff_x,0,i*diff_x,size);
        }
        g.setColor(Color.white);
    }

    public void paint(Graphics g)
    {
        drawEmptyGrid(g);
        g.setColor(Color.red);
        for(int i=0;i<game.getGridSize();++i)
        {
            for(int j=0;j<game.getGridSize();++j)
            {
                if( game.grid[i][j] )
                {
                    g.fillRect(i*diff_x,j*diff_y,diff_x,diff_y);
                }
            }
        }
        g.setColor(Color.white);
    }

    // This method will be called when the mouse has been clicked.
    public void mouseClicked (MouseEvent me) {
        Point point = me.getPoint();

        // Save the coordinates of the click lke this.
        xCo = (int)point.getX();
        yCo = (int)point.getY();

        int x_init = xCo / diff_x;
        int y_init = yCo / diff_y;

        System.out.println(x_init + "x" + y_init);
        game.grid[x_init][y_init] = true;
        //show the results of the click
        repaint();
    }

    // This is called when the mous has been pressed
    public void mousePressed (MouseEvent me) {}

    // When it has been released
    // not that a click also calls these Mouse-Pressed and Released.
    // since they are empty nothing hapens here.
    public void mouseReleased (MouseEvent me) {}

    // This is executed when the mouse enters the applet. it will only
    // be executed again when the mouse has left and then re-entered.
    public void mouseEntered (MouseEvent me) {}

    // When the Mouse leaves the applet.
    public void mouseExited (MouseEvent me) {}
}

class GameOfLife
{
    private final int GRID_SIZE = 60;
    public boolean [][] grid = new boolean[GRID_SIZE][GRID_SIZE];

    //default constructor
    public GameOfLife()
    {
        for(int i=0;i<GRID_SIZE;++i)
        {
            for(int j=0;j<GRID_SIZE;++j)
            {
                grid[i][j] = false;
            }
        }
    }

    public int getGridSize()
    {
        return GRID_SIZE;
    }

    public int getLiveNeighbors(int i,int j)
    {
        int neighbors = 0;
        for( int tmp_i = i-1; tmp_i <= i+1; ++tmp_i )
        {
            for( int tmp_j = j-1; tmp_j <= j+1; ++tmp_j )
            {
                if( tmp_i < 0 || tmp_i >= GRID_SIZE || tmp_j < 0 || tmp_j >= GRID_SIZE )
                {}
                else
                {
                    if( grid[tmp_i][tmp_j] )
                    {
                    neighbors++;
                    }
                }
            }
        }
        return neighbors;
    }

    public void nextIteration()
    {
        boolean [][] newGrid = new boolean[GRID_SIZE][GRID_SIZE];

        for(int i=0;i<GRID_SIZE;++i)
        {
            for(int j=0;j<GRID_SIZE;++j)
            {
                newGrid[i][j] = grid[i][j];
            }
        }

        for( int i=0;i<GRID_SIZE;++i)
        {
            for( int j=0;j<GRID_SIZE;++j)
            {
                int my_neighbors = getLiveNeighbors(i,j);
                if( !newGrid[i][j] && my_neighbors == 3)
                {
                    grid[i][j] = true;
                }
                else if( newGrid[i][j] && ( my_neighbors == 2 || my_neighbors == 3 ) )
                {
                    grid[i][j] = true;
                }
                else
                {
                    grid[i][j] = false;
                }
            }
        }
        System.out.println("Change of assignment");
    }
}

其他事项

  1. 代码将自定义绘画移动到Panel。这解决了直接绘制到顶级容器的常见问题。它还允许在不同容器中轻松地重复使用相同的 GUI。在本例中,既是一个小程序,又是一个 JOptionPane 对于“应用程序”(通常放在框架中)。现在它被称为“混合小程序/应用程序”(更容易测试)。
  2. 自定义绘制的组件Ecosystem(耸耸肩)通知布局它喜欢的大小。这有助于我们避免需要设置任何东西的大小或边界。
  3. 按钮的大小将完全符合其需要的大小。

Try this code that adds the button once rather than every call to paint(). Note that this source still throws AIOOBE if you click outside the grid (and not on the button), but that seems like a basic logic error you should investigate once the button is fixed.

// <applet code='GameOfLifeApplet' width=580 height=650></applet>
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class GameOfLifeApplet extends Applet implements MouseListener,ActionListener
{
  //the x and y coordinates to get the location of the clicked points
  private int xCo, yCo;
  private int diff_x, diff_y;
  private GameOfLife game = new GameOfLife();
  private Button nextButton = null;
  public void init()
  {
    setLayout(null);
    nextButton = new Button("Next Stage");
    diff_x = diff_y = 600 / game.getGridSize();
    nextButton.setLocation(250, 575);
    nextButton.setSize(120, 30);
    // add the button once only!
    add(nextButton);
    addMouseListener(this);
  }

  private void drawEmptyGrid(Graphics g)
  {
    g.setColor(Color.white);
    g.fillRect(0,0,600,600);
    g.setColor(Color.black);
    for(int i=0;i<game.getGridSize();++i)
    {
      g.drawLine(0,i*diff_x,600,i*diff_x);
      g.drawLine(i*diff_x,0,i*diff_x,600);
    }
    g.setColor(Color.white);
  }

  public void paint(Graphics g)
  {
    drawEmptyGrid(g);
    g.setColor(Color.red);
    for(int i=0;i<game.getGridSize();++i)
    {
      for(int j=0;j<game.getGridSize();++j)
      {
        if( game.grid[i][j] )
        {
          g.fillRect(i*diff_x,j*diff_y,diff_x,diff_y);
        }
      }
    }
    g.setColor(Color.white);
  }

 // This method will be called when the mouse has been clicked.
 public void mouseClicked (MouseEvent me) {

  // Save the coordinates of the click lke this.
  xCo = me.getX();
  yCo = me.getY();

  int x_init = xCo / diff_x;
  int y_init = yCo / diff_y;

  System.out.println(x_init + "x" + y_init);
  game.grid[x_init][y_init] = true;
  //show the results of the click
  repaint();

 }

 // This is called when the mous has been pressed
 public void mousePressed (MouseEvent me) {}

 // When it has been released
 // not that a click also calls these Mouse-Pressed and Released.
 // since they are empty nothing hapens here.
 public void mouseReleased (MouseEvent me) {}

 // This is executed when the mouse enters the applet. it will only
 // be executed again when the mouse has left and then re-entered.
 public void mouseEntered (MouseEvent me) {}

 // When the Mouse leaves the applet.
 public void mouseExited (MouseEvent me) {}

 public void actionPerformed(ActionEvent evt)
  {
  // Here we will ask what component called this method
    if (evt.getSource() == nextButton)
    {
      System.out.println("I got clicked!");
      game.nextIteration();
      repaint();
    }
  }

}

class GameOfLife
{
  private final int GRID_SIZE = 64;
  public boolean [][] grid = new boolean[GRID_SIZE][GRID_SIZE];
  //default constructor
  public GameOfLife()
  {
    for(int i=0;i<GRID_SIZE;++i)
    {
      for(int j=0;j<GRID_SIZE;++j)
    {
      grid[i][j] = false;
    }
    }
  }

  public int getGridSize()
  {
    return GRID_SIZE;
  }

  public int getLiveNeighbors(int i,int j)
  {
    int neighbors = 0;
    for( int tmp_i = i-1; tmp_i <= i+1; ++tmp_i )
    {
      for( int tmp_j = j-1; tmp_j <= j+1; ++tmp_j )
      {
        if( tmp_i < 0 || tmp_i >= GRID_SIZE || tmp_j < 0 || tmp_j >= GRID_SIZE )
        {}
        else
        {
          if( grid[tmp_i][tmp_j] )
          {
            neighbors++;
          }
        }
      }
    }
    return neighbors;
  }

  public void nextIteration()
  {
    boolean [][] newGrid = new boolean[GRID_SIZE][GRID_SIZE];

    for(int i=0;i<GRID_SIZE;++i)
    {
      for(int j=0;j<GRID_SIZE;++j)
      {
        newGrid[i][j] = grid[i][j];
      }
    }

    for( int i=0;i<GRID_SIZE;++i)
    {
      for( int j=0;j<GRID_SIZE;++j)
      {
        int my_neighbors = getLiveNeighbors(i,j);
        if( !newGrid[i][j] && my_neighbors == 3)
        {
          grid[i][j] = true;
        }

        else if( newGrid[i][j] && ( my_neighbors == 2 || my_neighbors == 3 ) )
        {
          grid[i][j] = true;
        }

        else
        {
          grid[i][j] = false;
        }
      }
    }
    System.out.println("Change of assignment");
  }
}

Further tips

  1. Don't use AWT components in this millennium, use Swing instead.
  2. Don't use null layouts. The custom rendered area does not need it, and the button should be sized and positioned using a layout manager (with maybe a border to pad it out).

Update

This code implements the 2nd suggestion from above 'use layouts', but leaves it as an exercise for the reader to update the components to something that might be used in this millennium (i.e. Swing).

The source below 'cheats' in a sense to show the GUI at it's natural size. This is tricky to do in an applet, since the size is set by the HTML. But put the GUI into a Swing based JOptionPane and it can be put on-screen, packed to its natural size, in just a couple of lines of code.

Here is what it looks like at the 'natural size' (I played with some numbers, to make the GUI smaller).

GameOfLifeApplet

// <applet code='GameOfLifeApplet' width=320 height=350></applet>
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class GameOfLifeApplet extends Applet implements ActionListener
{
    private Button nextButton = null;
    private Ecosystem ecosystem;

    public void init()
    {
        add(getGui());
    }

    public Component getGui() {
        Panel gui = new Panel(new BorderLayout(3,3));
        ecosystem = new Ecosystem();
        gui.add(ecosystem, BorderLayout.CENTER);
        nextButton = new Button("Next Stage");

        Panel p = new Panel(new FlowLayout());
        p.add(nextButton);
        gui.add(p, BorderLayout.SOUTH);
            nextButton.addActionListener(this);
        return gui;
    }

    public void actionPerformed(ActionEvent evt)
    {
        // Here we will ask what component called this method
        if (evt.getSource() == nextButton)
        {
            System.out.println("I got clicked!");
            ecosystem.nextIteration();
            ecosystem.repaint();
        }
    }

    public static void main(String[] args) {
        GameOfLifeApplet gola = new GameOfLifeApplet();
        // quick cheat to get it on-screen (packed).
        javax.swing.JOptionPane.showMessageDialog(null,gola.getGui());
    }
}

class Ecosystem extends Panel implements MouseListener {
    private GameOfLife game = new GameOfLife();
    //the x and y coordinates to get the location of the clicked points
    private int xCo, yCo;
    private int diff_x, diff_y;
    private int size = 300;

    Ecosystem() {
        diff_x = diff_y = 600 / game.getGridSize();
        setPreferredSize(new Dimension(size,size));
        addMouseListener(this);
    }

    public void nextIteration() {
        game.nextIteration();
    }

    private void drawEmptyGrid(Graphics g)
    {
        g.setColor(Color.white);
        g.fillRect(0,0,size,size);
        g.setColor(Color.black);
        for(int i=0;i<game.getGridSize();++i)
        {
            g.drawLine(0,i*diff_x,size,i*diff_x);
            g.drawLine(i*diff_x,0,i*diff_x,size);
        }
        g.setColor(Color.white);
    }

    public void paint(Graphics g)
    {
        drawEmptyGrid(g);
        g.setColor(Color.red);
        for(int i=0;i<game.getGridSize();++i)
        {
            for(int j=0;j<game.getGridSize();++j)
            {
                if( game.grid[i][j] )
                {
                    g.fillRect(i*diff_x,j*diff_y,diff_x,diff_y);
                }
            }
        }
        g.setColor(Color.white);
    }

    // This method will be called when the mouse has been clicked.
    public void mouseClicked (MouseEvent me) {
        Point point = me.getPoint();

        // Save the coordinates of the click lke this.
        xCo = (int)point.getX();
        yCo = (int)point.getY();

        int x_init = xCo / diff_x;
        int y_init = yCo / diff_y;

        System.out.println(x_init + "x" + y_init);
        game.grid[x_init][y_init] = true;
        //show the results of the click
        repaint();
    }

    // This is called when the mous has been pressed
    public void mousePressed (MouseEvent me) {}

    // When it has been released
    // not that a click also calls these Mouse-Pressed and Released.
    // since they are empty nothing hapens here.
    public void mouseReleased (MouseEvent me) {}

    // This is executed when the mouse enters the applet. it will only
    // be executed again when the mouse has left and then re-entered.
    public void mouseEntered (MouseEvent me) {}

    // When the Mouse leaves the applet.
    public void mouseExited (MouseEvent me) {}
}

class GameOfLife
{
    private final int GRID_SIZE = 60;
    public boolean [][] grid = new boolean[GRID_SIZE][GRID_SIZE];

    //default constructor
    public GameOfLife()
    {
        for(int i=0;i<GRID_SIZE;++i)
        {
            for(int j=0;j<GRID_SIZE;++j)
            {
                grid[i][j] = false;
            }
        }
    }

    public int getGridSize()
    {
        return GRID_SIZE;
    }

    public int getLiveNeighbors(int i,int j)
    {
        int neighbors = 0;
        for( int tmp_i = i-1; tmp_i <= i+1; ++tmp_i )
        {
            for( int tmp_j = j-1; tmp_j <= j+1; ++tmp_j )
            {
                if( tmp_i < 0 || tmp_i >= GRID_SIZE || tmp_j < 0 || tmp_j >= GRID_SIZE )
                {}
                else
                {
                    if( grid[tmp_i][tmp_j] )
                    {
                    neighbors++;
                    }
                }
            }
        }
        return neighbors;
    }

    public void nextIteration()
    {
        boolean [][] newGrid = new boolean[GRID_SIZE][GRID_SIZE];

        for(int i=0;i<GRID_SIZE;++i)
        {
            for(int j=0;j<GRID_SIZE;++j)
            {
                newGrid[i][j] = grid[i][j];
            }
        }

        for( int i=0;i<GRID_SIZE;++i)
        {
            for( int j=0;j<GRID_SIZE;++j)
            {
                int my_neighbors = getLiveNeighbors(i,j);
                if( !newGrid[i][j] && my_neighbors == 3)
                {
                    grid[i][j] = true;
                }
                else if( newGrid[i][j] && ( my_neighbors == 2 || my_neighbors == 3 ) )
                {
                    grid[i][j] = true;
                }
                else
                {
                    grid[i][j] = false;
                }
            }
        }
        System.out.println("Change of assignment");
    }
}

Other matters

  1. The code moves the custom painting to a Panel. This gets around the common problems of painting directly to a top-level container. It also allows easy re-use of the same GUI in different containers. In this case both an applet, and for the 'application' (which would usually be put in a frame), a JOptionPane. It is now what is known as a 'hybrid applet/application' (easier for testing).
  2. The custom painted component Ecosystem (shrugs) informs the layout what size it prefers to be. This helps us to avoid needing to set the size or bounds of anything.
  3. The button will be exactly as big as it needs to be.
蛮可爱 2025-01-14 08:42:25

首先,我认为您错误地读取了异常跟踪。该异常是 ArrayIndexOutOfBoundsException,发生在 GameOfLifeApplet.java 的第 63 行。您的应用程序是一个小程序,或者异常发生在线程 AWT-EventQueue-1 上,这些都没有任何关系。

根本原因是您没有正确同步模型和视图关于网格中有多少单元格的想法。至少,您应该考虑在访问数组元素之前检查用户是否实际单击了网格内部。

First, I think you're reading the exception trace wrong. The exception is an ArrayIndexOutOfBoundsException and occurs on line 63 of GameOfLifeApplet.java. That your app is an applet or that the exception occurs on the thread AWT-EventQueue-1 bears no relevance at all.

The root cause is that you've not properly synchronized the model and view's idea of how many cells there are in your grid. At the least, you should consider checking that the user actually clicked inside the grid before accessing the array element.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文