5

我想首先说这是一项任务。我不想把答案勺喂给我,但我想知道是什么导致了我的问题。

我目前正在实施康威的生命游戏。单击单元格应更改颜色,以表示该单元格正在切换到活动状态。如果再次单击,它应该返回默认颜色。

当我单击窗口中的任意位置时,程序会在第 56 行抛出空指针异常。在最后一天左右一直坚持这一点,因此感谢您的帮助。谢谢!

继承人的代码:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class VisibleGrid extends JPanel implements MouseListener, KeyListener{ 

  CellGrid cellGrid;
  Graphics rect;

  public VisibleGrid(){
    addMouseListener(this);
    cellGrid = new CellGrid();
  }

  //Draw the grid of cells, 7px wide, 75 times to create 75x75 grid
  public void paint(Graphics g){
    for(int i=0; i<525;i=i+7){
      for(int j = 0; j<525; j=j+7){
        g.drawRect(i ,j,7,7);       
      }
    }   
  }

  //auxillary method called to fill in rectangles
  public void paint(Graphics g, int x, int y){
    g.fillRect(x, y, 7, 7);
    repaint();

  }

  //main method, adds this JPanel to a JFrame and sets up the GUI  
  public static void main(String[] args){
    JFrame j = new JFrame("Conway's Game of Life");
    j.setLayout(new BorderLayout());
    j.add(new VisibleGrid(), BorderLayout.CENTER);
    JTextArea info = new JTextArea("Press S to Start, E to End");
    info.setEditable(false);
    j.add(info, BorderLayout.SOUTH);
    j.setSize(530,565);
    j.setVisible(true);
  }

  //these methods are to satisfy the compiler/interface
  //Begin Mouse Events
  public void mouseExited(MouseEvent e){}
  public void mouseEntered(MouseEvent e){}
  public void mouseReleased(MouseEvent e){}
  public void mousePressed(MouseEvent e){}
  public void mouseClicked(MouseEvent e){
    //fill the selected rectangle
    rect.fillRect(e.getX(), e.getY(), 7,7); 
    repaint();

    //set the corresponding cell in the grid to alive
    int row = e.getY() /7;
    int column = e.getX() /7;
     cellGrid.getCell(row, column).setAlive(true);
  } 
  //End Mouse Events

//These methods are to satisfy the compiler/interface
//Begin KeyEvents
  public void keyReleased(KeyEvent e){}
  public void keyPressed(KeyEvent e){}
  public void keyTyped(KeyEvent e){}



}
4

2 回答 2

3

这里的问题是您的rect 字段从未设置为任何内容,因此它保持为null. 调用rect.drawRect将导致您看到的 NullPointerException。

如果我没记错的话,SwingGraphics对象并不真正喜欢你在它们上绘画,因为它们并不期望你在做任何绘画。因此,我建议不要将Graphics您在调用期间获得的对象存储paint()在诸如rect. 如果你想重绘窗口的一部分,最好告诉 Swing 窗口的哪一部分需要重绘,然后让它调用你的paint()方法。

在您的mouseClicked()方法中,我删除了对的调用rect.fillRect()并将调用移至repaint()方法的末尾。我还修改了paint()方法,如果单元格是活动的,则绘制一个填充的矩形,否则绘制一个未填充的矩形。完成此操作后,您的代码似乎可以工作,因为我可以单击一些单元格,它们会变黑。

我有一些改进您的代码的建议。我将把最后两个作为练习留给你:

  • 我建议将行添加j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);main(). 此行使应用程序在您关闭窗口时正确退出。
  • 目前,每次单个单元格更改时,您的代码都会重新绘制整个 75 × 75 网格。应该可以更改您的代码,以便它仅重新绘制更改的单元格。您可以将 a 传递Rectangle给 repaint() 方法,该方法告诉 Swing '只有我的组件的这一部分需要重新绘制'。在该paint方法中,您可以使用getClipBounds()方法Graphics获取此矩形,并使用它来确定要重新绘制哪个或哪些单元格。
  • drawRect仅绘制矩形的轮廓。如果一个单元格死亡,您的paint方法不会从网格中清除现有的黑色矩形。您可以通过将死细胞绘制为顶部带有黑色轮廓矩形的白色填充矩形来解决此问题。
于 2012-04-29T08:53:55.587 回答
0

您确定CellGrid对象已被单元格填充吗?我不是 Java 专家,但我没有在你的代码中看到这个初始化......

于 2012-04-29T05:37:20.690 回答