I'm using a custom JLayeredPane. I have several Shapes which needed to be drawn on different layers in the JLayeredPane.
To test this I create a JPanel and ask its graphics. Then I draw a test rectangle on that JPanel (preparing the graphics) and in my paintComponent method from the JLayeredPane I finally draw everything. But this fails (NullPointerException).
public class MyCustomPanel extends JLayeredPane {
// test
JPanel testpane;
Graphics g2;
// test
// constructor
public MyCustomPanel() {
testpane = new JPanel();
this.add(testpane, new Integer(14));
g2 = testpane.getGraphics();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2.drawRect(10, 10, 300, 300);
}
}
// run:
//Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
// at view.MyCustomPanel.paintComponent(MyCustomPanel.java:65)
Why can't I draw on such a JPanel from within my JLayeredPane? I can draw directly on my JLayeredPane from within my paintComponent method but that's on the default Panel from the JLayeredPane. I need to create and draw on several layers which are added in my JLayeredPane.
What am I doing wrong? :s
You should use g2
casting the Graphics
that is passed to you:
Graphics2D g2 = (Graphics2D)g;
Why don't you try decoupling things?
class InnerPanel extends JPanel
{
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.drawRect(....);
}
}
class MyLayered extends JLayeredPane()
{
MyLayered()
{
this.add(new InnerPanel(), 14);
}
}
this makes more sense..
Also because you are trying to do something that doesn't agree with Swing behaviour.
Swing will care by itself to call the appropriate paint
methods over things that must be displayed, and to go with this protocol you should tell Graphics
objects what to draw when Swing asks it to your objects (calling the paint
) method, not when you want to do it.
In this way whenever Swing wants to draw your JLayeredPane
you just draw things on a Graphic
object of other things without considering that Swing will call their appropriate methods when it's the right time to do so.
In conclusion: you can't draw something on a Graphic
object when you want it. You can do it just inside methods invoked by Swing, because otherwise Graphics
of these objects doesn't mean anything