NullPointerException at Graphics.drawOval [duplica

2019-09-22 04:53发布

问题:

This question already has an answer here:

  • What is a NullPointerException, and how do I fix it? 12 answers

The question is simple. I have created a class named "handler" and within its constructor it contains a parameter for "c", a JComponent. When this constructor is called on a certain JComponent, preferably a JPanel, an oval is drawn at the mouse's current coordinates. This is the source code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class Handler implements MouseListener, MouseMotionListener {

Graphics g;

public Handler() {}

public Handler(JComponent c) {

    if (c instanceof JPanel) {
        g = c.getGraphics();
        g.drawOval(mx, my, 5, 5);
    }

    if (c != null) {
        c.addMouseListener(this);
        c.addMouseMotionListener(this);
    }
}

int mx, my;


public void mouseClicked(MouseEvent e) {
    mx = e.getX();
    my = e.getY();
}

public void mousePressed(MouseEvent e) {
    mx = e.getX();
    my = e.getY();
}

public void mouseReleased(MouseEvent e) {
    mx = e.getX();
    my = e.getY();
}

public void mouseExited(MouseEvent e) {}

public void mouseEntered(MouseEvent e) {}

public void mouseMoved(MouseEvent e) {
    mx = e.getX();
    my = e.getY();
}

public void mouseDragged(MouseEvent e) {}
}

However, this error is thrown:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

Do you guys have any idea about this? If so, please post a solution.

Edit 1
I've done something new. This is my entire new code:

import javax.swing.*;
import java.awt.*;

public class Handler extends JPanel {

   int mx = MouseInfo.getPointerInfo().getLocation().x;
   int my = MouseInfo.getPointerInfo().getLocation().y;


public Handler(BorderLayout bl) {
    this.setLayout(bl);
}

public void paintComponent(Graphics g23) {
    Graphics2D g2 = (Graphics2D) g23;
    g2.drawOval(mx, my, 30, 30);
    }
}

I've reworked the code greatly. Now, it extends JPanel and serves as a replacement to JPanel. So instead of instantiating a new JPanel, I'd call Handler's constructor. It also implements paintComponent, yet the oval still isn't being drawn. It yields no errors, however.

回答1:

This is because the graphics component you are passing to handler is an unrealized component, so getGraphics() is returning null. A component will not have a graphics object if it is not visible on the screen, so it must first be visible for it to work. I added this code to a main() method and called your sample code and it worked:

public static void main(String[] args){
    JPanel jpanel = new JPanel();
    JFrame jframe = new JFrame();
    jframe.add(jpanel);
    jframe.setVisible(true);
    jpanel.setVisible(true);
    Handler handler = new Handler(jpanel);
}


回答2:

I have thoroughly researched this question and have found no solution,

Read the section from the Swing tutorial on Custom Painting..

You should not be using the getGraphics() method. This kind of painting is NOT permanent. As soon a Swing determines the component needs to be repainted you will lose the painting.

If you need more help then post your SSCCE here. We dpm't have time to guess what you code is like by chasing code snippets all over the web.



回答3:

You haven't mentioned how the Handler is created. Moreover, the values of mx,my gets initilized once the Mouse is Clicked, Pressed or released. What if your Handler Class is getting called before any of these events occurs and hence mx,my are null? Have you checked it?