Приложение Java Paint теряет значение NullPointer при очистке поверхности рисования

Моя проблема заключается в следующем: я пытаюсь сделать приложение для рисования в Java. Я получаю этот код ошибки:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at areacalc.DrawArea.clear(Form.java:67)
    at areacalc.DrawArea.mouseMoved(Form.java:115)

когда я очищаю поверхность рисования.

Вот мой код, не могли бы вы помочь мне избежать нулевого указателя? Где я должен разместить обработчики событий, чтобы не получить нулевой указатель?

Спасибо вам большое! С уважением, Стэнли.

упаковка арекалка;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.JFrame;

class DrawArea extends JComponent implements MouseListener, MouseMotionListener
{   
    private Image image;
    private Graphics2D g2;        
    private int currentX, currentY, oldX, oldY, X, Y;
    private ArrayList<Integer[]> points = new ArrayList<Integer[]>();
    private boolean stopped = false;
    public boolean crtl_pressed = false;

    public DrawArea()
    {   
        setDoubleBuffered(false);       
        initEventHandlers();
    }

    public void initEventHandlers()
    {
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    public double length(int x1, int x2)
    {
        return Math.abs(x1-x2);
    }

    protected void paintComponent(Graphics g)
    {
        //System.out.println("paintComponent");

        if (image == null)
        {
            image = createImage(getSize().width, getSize().height);
            g2 = (Graphics2D) image.getGraphics();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            clear();            
        }

        g.drawImage(image, 0, 0, null); 
    }

    public void clear()
    {
        g2.setPaint(Color.black);
        g2.fillRect(0, 0, getSize().width, getSize().height);
        repaint();
    }

    @Override
    public void mousePressed(MouseEvent e) 
    {       
    if(e.getButton() == MouseEvent.BUTTON1&&(!stopped))
      {
          oldX = e.getX();
          oldY = e.getY();

          if((currentX!=oldX)&&(currentY!=oldY)&&(currentX!=0)&&(currentY!=0))
          {
              g2.setPaint(Color.green);
              Integer i[] = { currentX, currentY, e.getX(), e.getY() };
              points.add(i);
              g2.drawLine(currentX, currentY, e.getX(), e.getY());
              repaint();
          }
      }
      else if(e.getButton() == MouseEvent.BUTTON3&&points.size()>0)           
      {
          g2.setPaint(Color.green);
          g2.drawLine(currentX, currentY, e.getX(), e.getY());

          if(points.size()>0)
                {
                    Integer i[] = points.get(0);
                    g2.drawLine(e.getX(), e.getY(), i[0], i[1]);
                }

          repaint();
          stopped = true;
      }
    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
        if((!stopped))
        {               
            //label.setText(e.getX() + ";" + e.getY());

            currentX = oldX;
            currentY = oldY;

            clear();    

            for(int j = 0; j < points.size(); j++)
            {
                g2.setPaint(Color.green);
                Integer i[] = points.get(j);
                g2.drawLine(i[0], i[1], i[2], i[3]);
                repaint();
            }

            if((currentX!=0)&&(currentY!=0))
            {
                g2.setPaint(Color.yellow);

                if(!crtl_pressed)
                {
                    if(points.size()>0)
                    {
                        Integer i[] = points.get(0);
                        g2.drawLine(e.getX(), e.getY(), i[0], i[1]);
                    }

                    g2.drawLine(currentX, currentY, e.getX(), e.getY());
                }                       
                else
                {
                    if(length(currentX, e.getX())>=length(currentY, e.getY()))
                    {
                        if(points.size()>0)
                        {
                            Integer i[] = points.get(0);
                            g2.drawLine(e.getX(), currentY, i[0], i[1]);

                        }

                        g2.drawLine(currentX, currentY, e.getX(), currentY);
                    }
                    else
                    {
                        if(points.size()>0)
                        {
                            Integer i[] = points.get(0);
                            g2.drawLine(currentX, e.getY(), i[0], i[1]);
                        }                           

                        g2.drawLine(currentX, currentY, currentX, e.getY());
                    }
                }                       

                repaint();
            }
        }
    }

    public void mouseDragged(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mouseClicked(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
}

public class Form extends JFrame implements ActionListener
{

    public Form() 
    {
        initUI();
    }

    private void initUI() 
    {    
        setTitle("Area Calculator");
        setSize(600, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        Container content = getContentPane();
        content.setLayout(new BorderLayout());
        DrawArea drawArea = new DrawArea();
        content.add(drawArea, BorderLayout.CENTER);

        addKeyListener(
            new KeyAdapter()
            {
                public void keyPressed(KeyEvent e)
                {
                    if(e.getKeyCode() == KeyEvent.VK_CONTROL);
                        //drawArea.crtl_pressed = true;
                }

                public void keyReleased(KeyEvent e)
                {
                    if(e.getKeyCode() == KeyEvent.VK_CONTROL);
                        //drawArea.crtl_pressed = false;
                }
        });
    }

    private void doDrawing(Graphics g) 
    {
        Graphics2D g2d = (Graphics2D) g;

        g2d.setPaint(Color.blue);

        g2d.drawLine(20, 20, 500, 500);
    }

    public void paintComponent(Graphics g) 
    {
        paintComponent(g);
        doDrawing(g);
    }

    @Override
    public void actionPerformed(ActionEvent e) 
    {
        repaint();
    }
}

1 ответ

Если clear() называется раньше paintComponent()переменная g2 не инициализирована.

Вы можете инициализировать ваш экземпляр g2 в конструкторе, но я не уверен, что это работает для вас, потому что вам нужен размер окна.

Другой вариант - вставить

if (g2 == null) return;

в качестве первой строки clear,

Похоже, что это реализация двойной буферизации. Я уверен, что Google поможет вам найти хорошие примеры для альтернативных реализаций без этой проблемы.

Другие вопросы по тегам