-4

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.

Andrew Li
  • 55,805
  • 14
  • 125
  • 143
  • 3
    Mind including more of the stack trace? – mre Jul 10 '11 at 23:30
  • 2
    Also, why are you getting the `Graphics` object of the `JComponent` and then drawing outside of `paintComponent(...)`? You should be overriding `paintComponent(...)` and doing the drawing therein. – mre Jul 10 '11 at 23:36
  • 1
    You should conisder making your class a runnable and running it from `javax.swing.SwingUtilities.invokeLater()`. This will give you event queue sanity. Use of `instanceof` in routine coding is not the best stylistic move. – ncmathsadist Jul 11 '11 at 00:19
  • 2
    As little bunny foo foo and camickr are telling you, your problem is that your Graphics object is null since if you try to get your JPanel's Graphics object via getGraphics, it won't be stable and is liable to be null. If you don't understand their advice, just ask and they or we will help clarify things for you, for if/when you do understand this, it will lead you to solve your problem. Also, it's not a wise thing to bite the hands that feed you. Just saying. – Hovercraft Full Of Eels Jul 11 '11 at 01:02
  • Regarding your recent new information: I don't see anything in that code that explains your problem and I suspect that the problem is elsewhere. I again second camickr's recommendation that you create and post an [SSCCE](http://sscce.org). Please see the link as it will explain better what this is and why it's important and how to create one. Often the process of creating an sscce will help you see the solution yourself, so it won't be a wasted exercise. – Hovercraft Full Of Eels Jul 11 '11 at 19:13
  • Also, you have yet to address my comments regarding your remarks to camickr. Now would be a good time to do so. – Hovercraft Full Of Eels Jul 11 '11 at 19:16
  • Also, the MouseInfo isn't going to work as you need a MouseListener/MouseMotionListener -- you need something that will fire when the mouse changes, which is what listeners are for. – Hovercraft Full Of Eels Jul 11 '11 at 21:24
  • Also, I know what you're doing wrong and how to fix it, but since you refuse to reply to any of my comments, I guess you're on your own. Lots of luck. – Hovercraft Full Of Eels Jul 11 '11 at 23:21

3 Answers3

2

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);
}
Jason Rae
  • 2,583
  • 5
  • 25
  • 34
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.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • 4
    @OmerEltoum: Where does camickr's answer insult or belittle you? If you'd get rid of the attitude and instead listen to camickr's advice, you might just learn something. – Hovercraft Full Of Eels Jul 11 '11 at 00:44
1

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?

Logan
  • 2,445
  • 4
  • 36
  • 56