2012-04-29 52 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