2012-04-29 3 views
5

Я хотел бы начать с того, что это задание. Я не хочу, чтобы ложка ответа подавалась мне, но я хотел бы знать, что вызывает мои проблемы.Java: заполнение прямоугольника на сетке

В настоящее время я использую игру жизни Конвея. Щелчок по ячейке должен изменить цвет, чтобы отобразить, что ячейка переключается в живое состояние. если щелкнуть снова, он должен вернуться к цвету по умолчанию.

Когда я нажимаю в любом месте окна, программа выдает исключение Null Pointer Exception в строке 56. Застряли в этом в течение последнего дня или около того, поэтому любая помощь оценивается. Благодаря!

Heres код:

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; который выглядит неправильно –

+0

i bet line 56 is _rect.fillRect (e.getX(), e.getY(), 7,7); _ –

+0

Как говорит @guido, убедитесь, что графический объект 'rect' инициализируется или имеет действительную ссылку, прежде чем обращаться к ней. – Rupak

ответ

3

Проблема в том, что поле rect никогда не устанавливается ни на что, поэтому оно остается null. Вызов rect.drawRect вызовет возникновение NullPointerException.

Если я правильно помню, объекты Swing Graphics вам не очень нравятся, если вы не собираетесь рисовать их. Поэтому я рекомендовал бы против штамповки объекта Graphics, который вы получаете во время вызова paint(), в поле, такое как rect. Если вы хотите перекрасить часть окна, лучше сказать 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

0

Вы уверены, что CellGrid объекты были заполнены клетками? Я не эксперт по Java, но я не вижу в вашем коде этой инициализации ...

+0

Да, объект CellGrid заполняется объектами Cell в его конструкторе. Я получил часть графического интерфейса программы, разработанную только сейчас. Благодаря! – NickD720

Смежные вопросы