2012-04-29 12 views
5

Ich möchte damit beginnen zu sagen, dass dies eine Aufgabe ist. Ich möchte nicht, dass mir der Löffel der Antwort gefüttert wird, aber ich würde gerne wissen, was meine Probleme verursacht.Java: Füllen eines Rechtecks ​​in einem Raster

Ich implementiere gerade Conways Game of Life. Durch Klicken auf die Zelle sollte die Farbe geändert werden, um anzuzeigen, dass die Zelle in einen aktiven Zustand versetzt wurde. Wenn Sie erneut darauf klicken, sollte es zur Standardfarbe zurückkehren.

Wenn ich irgendwo in das Fenster klicke, löst das Programm eine Null-Zeiger-Ausnahme in Zeile 56 aus. Seit dem letzten Tag sind sie hier festgefahren, so dass jede Hilfe geschätzt wird. Vielen Dank!

Heres der Code:

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

Welche Linie ist Linie 56? Wenn ich den Code kopiere/eingefügt habe, war es int column = e.getX()/7; was nicht richtig aussieht –

+0

ich Wette Zeile 56 ist _rect.fillRect (e.getX(), e.getY(), 7,7); _ –

+0

Wie @guido sagt, stellen Sie sicher, dass das Grafikobjekt, 'rect' wird vor dem Zugriff initialisiert oder hat eine gültige Referenz. – Rupak

Antwort

3

Das Problem hier ist, dass Ihr rect Feld nie auf etwas festgelegt ist, so bleibt es als null. Der Aufruf von rect.drawRect verursacht die NullPointerException, die Sie sehen.

Wenn ich mich richtig erinnere, Swing Graphics Objekte nicht wirklich wie Sie auf sie malen, wenn sie nicht erwarten, dass Sie ein Gemälde zu tun. Ich würde daher empfehlen, das Graphics Objekt, das Sie während eines Anrufs an paint() in einem Feld wie rect erhalten, zu verstauen. Wenn Sie einen Teil des Fensters neu streichen wollen, ist es besser Swing zu sagen, welcher Teil des Fensters neu gezeichnet werden muss und dann Ihre paint() Methode aufzurufen.

Innerhalb Ihrer mouseClicked() Methode habe ich den Anruf auf rect.fillRect() entfernt und den Anruf an repaint() an das Ende der Methode verschoben. Ich änderte auch die paint() Methode, um ein gefülltes Rechteck zu zeichnen, wenn die Zelle am Leben war und eine ungefüllte ansonsten. Nachdem dies geschehen war, schien dein Code zu funktionieren, indem ich auf einige Zellen klicken konnte und sie schwarz wurden.

Ich habe ein paar Vorschläge für Verbesserungen an Ihrem Code. Ich werde die letzten beiden als Übungen für Sie verlassen:

  • Ich würde empfehlen, die Linie j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);-main() hinzufügen. Diese Zeile bewirkt, dass die Anwendung ordnungsgemäß beendet wird, wenn Sie das Fenster schließen.
  • Im Moment wird bei jeder Änderung einer einzelnen Zelle der gesamte 75-Zoll-Raster neu gezeichnet. Es sollte möglich sein, den Code so zu ändern, dass nur die geänderte Zelle neu gezeichnet wird. Sie können pass a Rectangle to the repaint() method, die sagt Swing "nur dieser Teil meiner Komponente muss neu lackiert werden". In der paint Methode können Sie dieses Rechteck unter Verwendung the getClipBounds() method of the Graphics class erhalten und es verwenden, um zu bestimmen, welche Zelle oder Zellen neu streichen.
  • drawRect zeichnet nur den Umriss eines Rechtecks. Wenn eine Zelle stirbt, löscht Ihre paint Methode das vorhandene schwarze Rechteck nicht aus dem Raster. Sie können dies beheben, indem Sie tote Zellen als weiß gefülltes Rechteck mit einem schwarzen Umriss-Rechteck an der Spitze zeichnen.
+0

Vielen Dank für die sehr hilfreiche Antwort! Ich habe jetzt eine fast vollständige Umsetzung des Spiels, ich muss nur den Algorithmus für das eigentliche Spiel beenden, aber der GUI-Teil ist fertig. Danke nochmal, Mann. – NickD720

0

Sind Sie sicher, dass die CellGrid Objekte hat mit Zellen gefüllt worden? Ich bin kein Java-Experte, aber ich sehe nicht in Ihrem Code diese Initialisierung ...

+0

Ja, das CellGrid-Objekt ist im Konstruktor mit Cell-Objekten gefüllt. Ich habe den GUI-Teil des Programms gerade herausgefunden. Vielen Dank! – NickD720

Verwandte Themen