2012-04-29 18 views
5

Me gustaría comenzar diciendo que esto es una tarea. No quiero que me suministren la cuchara de respuesta, pero me gustaría saber qué está causando mis problemas.Java: rellenar un rectángulo en una cuadrícula

Actualmente estoy implementando Conway's Game of Life. Hacer clic en la celda debería cambiar el color, para representar que la celda se cambia a un estado activo. si vuelve a hacer clic, debería volver al color predeterminado.

Cuando hago clic en cualquier parte de la ventana, el programa arroja una Excepción del puntero nulo en la línea 56. Se han quedado atascados en esto durante el último día, por lo que se agradece cualquier ayuda. ¡Gracias!

Aquí está el código:

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

¿Qué línea es la línea 56? Cuando copié/pegué el código, fue int column = e.getX()/7; que no se ve bien –

+0

apuesto a que la línea 56 es _rect.fillRect (e.getX(), e.getY(), 7,7); _ –

+0

Como dice @guido, asegúrese de que el objeto gráfico, 'rect' se inicializa o tiene una referencia válida, antes de acceder a ella. – Rupak

Respuesta

3

El problema aquí es que su campo rect nunca se establece en nada, por lo que se mantiene como null. Llamar al rect.drawRect causará la NullPointerException que está viendo.

Si no recuerdo mal, a los objetos Swing Graphics realmente no les gusta que los pintes cuando no esperan que estés pintando. Por lo tanto, recomendaría no esconder el objeto Graphics que recibe durante una llamada al paint() en un campo como rect. Si desea volver a pintar una parte de la ventana, es mejor decirle a Swing qué parte de la ventana necesita volverse a pintar y luego deje que llame a su método paint().

Dentro de su método mouseClicked(), eliminé la llamada al rect.fillRect() y moví la llamada al repaint() hasta el final del método. También modifiqué el método paint() para dibujar un rectángulo lleno si la celda estaba viva y una vacía de lo contrario. Después de hacer esto, su código pareció funcionar, en el sentido de que podía hacer clic en algunas celdas y se volverían negras.

Tengo algunas sugerencias para mejorar su código. Voy a dejar los dos últimos como ejercicios para usted:

  • lo recomiendo añadiendo la línea j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);-main(). Esta línea hace que la aplicación se cierre correctamente cuando cierra la ventana.
  • Por el momento, su código está repintando toda la cuadrícula 75 × 75 cada vez que cambia una celda. Debería ser posible cambiar su código para que repinte solo la celda modificada. Puede pass a Rectangle to the repaint() method, que le dice a Swing 'solo esta parte de mi componente necesita ser repintada'. En el método paint, puede obtener este rectángulo usando the getClipBounds() method of the Graphics class y usarlo para determinar qué celda o celdas se volverán a pintar.
  • drawRect solo dibuja el contorno de un rectángulo. Si una celda muere, su método paint no borrará el rectángulo negro existente de la cuadrícula. Puede solucionar esto dibujando celdas muertas como un rectángulo relleno de blanco con un rectángulo negro en la parte superior.
+0

¡Muchas gracias por la respuesta tan útil! Ahora tengo una implementación casi completa del juego, solo necesito finalizar el algoritmo para el juego real, pero la parte de la GUI está lista. Gracias de nuevo, hombre. – NickD720

0

¿Seguro CellGrid los objetos se ha llenado de las células? No soy experto en Java, pero no veo en su código esta inicialización ...

+0

Sí, el objeto CellGrid está lleno de objetos Cell en su constructor. Obtuve la parte de la GUI del programa resuelta hace un momento. ¡Gracias! – NickD720

Cuestiones relacionadas