NullPointer в getGraphics () в JPanel - PullRequest
0 голосов
/ 02 мая 2018

Привет, я получаю исключение NullPointerException при попытке использовать объект Graphics внутри paintComponent, и я не могу понять, почему. Он по-прежнему рисует то, что я хочу один раз, но после этого выдает исключение. Вот код

public class RacePanel extends JPanel implements MouseListener, ActionListener
{

private static final int PANEL_WIDTH = 640;
private static final int PANEL_HEIGHT = 400;
private Timer time;
boolean firstTime;
private Rabbit hare;

public RacePanel()
{
    setSize(PANEL_WIDTH, PANEL_HEIGHT);
    setVisible(true);
    firstTime = true;
    addKeyListener(new Key());
    addMouseListener(this);
    hare = new Rabbit();
    time = new Timer(40, this);
    time.start();
}

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    setBackground(Color.WHITE);

    g.setColor(Color.RED);
    g.drawLine(0, this.getHeight(), this.getWidth()/4, this.getHeight()/2);
    g.drawLine(this.getWidth()/4, this.getHeight()/2, 2*this.getWidth()/4, this.getHeight());
    g.drawLine(2*this.getWidth()/4, this.getHeight(), 3*this.getWidth()/4, this.getHeight()/2);
    g.drawLine(3*this.getWidth()/4, this.getHeight()/2, this.getWidth(), this.getHeight());
    g.setColor(Color.PINK);
    g.fillOval(hare.getPosition(), this.getHeight()-10, 10, 10);


}
@Override
public void actionPerformed(ActionEvent arg0)
{
    Graphics g = getGraphics();
    paintComponent(g);
    hare.move();

}
public static void main(String[] args) 
{
    RacePanel panel = new RacePanel();
    panel.setVisible(true);
    JFrame frame = new JFrame();
    frame.getContentPane().add(panel);
    frame.setMinimumSize(panel.getSize());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.addKeyListener(panel.new Key());
    frame.pack();
    frame.setVisible(true);
}
}

Как только он попадет в g ​​= getGraphics (), g станет нулевым, и вызов super.paintComponent (g) вызовет исключение. Я скопировал большую часть кода анимации из одного из моих предыдущих проектов, и там все отлично работает, поэтому я довольно озадачен, почему это не работает.

1 Ответ

0 голосов
/ 02 мая 2018

Этот ...

@Override
public void actionPerformed(ActionEvent arg0)
{
    Graphics g = getGraphics();
    paintComponent(g);
    hare.move();

}

НЕ работает как обычай рисовать в Swing. НИКОГДА нет причин, по которым вам следует звонить paintComponent (или даже paint) напрямую, они вызываются подсистемой рисования.

Начните с просмотра Выполнение пользовательской рисования и Рисование в AWT и Swing для получения более подробной информации о том, как работает система рисования

Если вы хотите, чтобы пользовательский интерфейс обновлялся, вы должны позвонить repaint, что запланирует прохождение рисования на некоторое время в будущем

Возможно, вы также захотите взглянуть на Как использовать привязки клавиш , что поможет решить проблемы с надежностью, связанные с KeyListener

Если вы предпочитаете «полный» контроль над процессом рисования, вы можете рассмотреть BufferStrategy и BufferCapabilities , хотя это полный сдвиг в мышлении

...