2012-04-29 57 views
5

我想先说这是一个任务。我不想让勺子喂给我,但我想知道是什么导致了我的问题。Java:填充网格上的矩形

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

当我在窗口中单击任意位置,该程序在罚球线上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){} 



} 
+1

哪条线是线56?当我复制/粘贴代码时,它是int column = e.getX()/ 7;这看起来不正确 – 2012-04-29 05:26:34

+0

我敢打赌线56 _rect.fillRect(e.getX(),e.​​getY(),7,7); _ – 2012-04-29 05:29:18

+0

作为@guido说,确保对象的图形,'rect'在访问之前被初始化或有一个有效的参考。 – Rupak 2012-04-29 08:34:42

回答

3

这里的问题是,你的rect字段永远不会设置为任何东西,所以它保持为null。调用rect.drawRect将导致您看到的NullPointerException。

如果我没有记错的话,Swing Graphics物体并不真的喜欢你在他们身上绘画,因为他们不希望你在做任何绘画。因此,我建议您不要在rect等字段中存储您在致电paint()期间收到的Graphics对象。如果您想重新绘制窗口的一部分,最好告诉Swing窗口的哪个部分需要重新绘制,然后让它调用您的paint()方法。

在您的mouseClicked()方法中,我删除了对rect.fillRect()的呼叫,并将呼叫转移到repaint(),直到方法结束。我还修改了paint()方法来绘制一个填充的矩形,如果该单元格是活的而另一个是未填充的矩形。做完这些之后,你的代码似乎就可以工作了,因为我可以点击一些单元格,并且它们会变黑。

我有改进代码的一些建议。我会留下最后两个为你的练习:

  • 我建议添加行j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);main()。当你关闭窗口时,这一行使应用程序正常退出。
  • 此刻,你的代码,每次一个单细胞的变化重新绘制整个75 × 75格。应该可以更改代码,以便仅重新绘制已更改的单元格。你可以pass a Rectangle to the repaint() method,它告诉Swing'只有我的组件的这部分需要重新绘制'。在paint方法中,您可以使用the getClipBounds() method of the Graphics class获取此矩形,并使用它来确定要重绘的单元。
  • drawRect只绘制矩形的轮廓。如果一个单元格死亡,您的paint方法将不会从网格中清除现有的黑色矩形。您可以通过将死细胞绘制为顶部带黑色轮廓矩形的白色填充矩形来解决此问题。
+0

非常感谢您的帮助!我现在几乎完成了游戏的实现,我只需要完成实际游戏的算法,但GUI部分已完成。再次感谢,男士。 – NickD720 2012-04-30 00:16:16

0

你确定CellGrid对象已经充满了细胞?我不是Java专家,但我没有看到你的代码初始化...

+0

是的,CellGrid对象在其构造函数中填充了Cell对象。我刚刚得到了程序的GUI部分。谢谢! – NickD720 2012-04-30 00:16:58