views:

185

answers:

3

I'm extending JPanel to make a custom drawing panel, but am getting a NullPointerException and can't work out why. I've removed code until it's pretty bare, but the error is still occuring.

package testdraw;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;

public class DrawPanel extends JPanel {

    public DrawPanel() {
        this.Draw();
    }

    public void Draw(){
        Graphics g = this.getGraphics();
        Graphics2D g2d = (Graphics2D) g;

        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        rh.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_SPEED);

        g2d.setRenderingHints(rh);
    }
}

I'm getting the error:

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

from the line where I call the setRenderingHints method. Any help appreciated.

A: 

You're calling "Draw" in the constructor. You should wait until it's fully constructed and visibile before calling getGraphics.

Paul Tomblin
Thank you, I should have guessed that.
VirtualMe
I'm sorry, but it's not only a question of draw being called in constructor. It's rather the fact your draw method do not comply with Swing framework behaviour. See my answer for more details.
Riduidel
@Riduidel, what I said is perfectly accurate. I didn't tell him *where* he should be calling his Draw() method from, but that doesn't make it wrong to tell him not to call it from the constructor.
Paul Tomblin
+1 This answer is useful.
trashgod
@Paul TomblinYes, you're writing, calling the draw method in the constructor is obviously wrong.However, when called outside of the container, this method may result in the NullPointerException since, as far as I know, the Graphics holded by a component is only set once the component is displayable, as the Component javadoc states (http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Component.html#getGraphics()). And, considering the fact this Draw method is totally uncorrelated to the Swing framework, @VirtualMe may call it without ever having made the component displayable.
Riduidel
+1  A: 

The null comes from when you call Graphics g = this.getGraphics(); As Paul said, you shouldn't call this in the constructor because the panel doesn't exist yet. It might be better to put this code in an overridden paintComponent() method

chama
Good idea, I shall peruse the Javadoc.
VirtualMe
+1 For more on how paintComponent() works, see http://java.sun.com/products/jfc/tsc/articles/painting/index.html
trashgod
A: 

Usually, the draw method is not called by the panel itself, but rather from the Java2D framework. As a consequence, it is not a Draw() with no parameters method, but rather the paint(Graphics g) method. In this case, the Graphics will never be null, and will always be a graphics2D (as far as you use a Java2 VM).

Riduidel
I'm sorry, but what relevance is it that he called his method "Draw"? He could have called it "FooBarBlatz" for all the difference that makes, as long as he called it after the JPanel was visible.
Paul Tomblin
Yes, precisely, but in such a case, having a Draw method separated from the paint one will be not only useless, but also bug-prone (to my mind).
Riduidel