0

Hi Experts: I have a class which extends JPanel now ShapePanel (Sp) this gets added to a normal JPanel (Container) which inturn gets Added To JFrame (Window). In the paintComponent method i draw a shape.... but the shape never persists after rendering. In the debugger i can see that it gets re-drawn every time i resize or something like that.

Now i overloaded the JPanel's (Sp's) paintComponent and added this

    super.paintComponent(g);        

    ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)this.getGraphics());
    //for(Shape s : ArrayOfShapes)
    {
        if(s instanceof Rectangle)
                SdG.Paint((Rectangle)s);
            else if(s instanceof Triangle)
                SdG.Paint((Triangle)s);
            else
                SdG.Paint((Circle)s);
    } //s is a custom-shape object

the graphics object comes from (obviously) the JPanel....

But the drawn image never stays on the panel - you see it for a split second and its gone...

I have done some searching but to no avail.

The actual Drawing

public ShapeDrawerGui(Graphics2D _g)
{
    g = _g;
    g.setColor(Color.Black);
}

@Override
public void Paint(Circle c) 
{
    g.drawArc(0, 0, 50, 50, 0, 360);
}

@Override
public void Paint(Triangle t) 
{        
    Polygon p = new Polygon();
    p.addPoint(0, 25);
    p.addPoint(0 , 50);
    p.addPoint(50, 50);       
    g.drawPolygon(p);
}

@Override
public void Paint(Rectangle r) 
{
    g.drawRect(0, 0, 50, 50);
}

Kind regards

Markus

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Markus
  • 133
  • 2
  • 13
  • You have `Paint()` method with uppercase P - ouch.. well, that is not an issue. – ring bearer Mar 19 '12 at 16:47
  • Did you try changing `ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)this.getGraphics());` to `ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)g);` – ring bearer Mar 19 '12 at 16:51
  • 1
    *"the graphics object comes from (obviously) the JPanel"* An [SSCCE](http://sscce.org/) usually makes things obvious. – Andrew Thompson Mar 19 '12 at 17:07
  • @AndrewThompson: I can't Believe it but it worked.... then what is the difference between this.getGraphics and the g, they are one it the same aren't they? – Markus Mar 19 '12 at 18:21

2 Answers2

2

..what is the difference between this.getGraphics and the g ..?

A GUI should repaint when it is told to do so, and use the Graphics object supplied to the paint(Graphics) or paintComponent(Graphics) method. That method could be called at any time by the GUI, to repaint after being behind another window, for example.

When you make a call to getGraphics() you are provided with a non-persistent graphics object that will disappear next paint.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • +1 I overlooked that. @Markus: you may also have to invoke `repaint()` if you change an otherwise unbound property. – trashgod Mar 19 '12 at 18:44
1

Here's the problem:

super.paintComponent(g);        

ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)this.getGraphics());

the g and the SdG are two different objects, and counter-intuitively, the g that belongs to your specialized panel is NOT the one that is always drawing to it.

Depending on what your program is doing, they can BOTH be used to draw to the canvas, however, the g will always be drawn last and persist after the SgD is done painting. even though the Graphics2D you retrieved SgD DOES belong to the component you want to paint to, ( getGraphics() ) that doesn't mean it is the Graphics that is used to paint the canvas.

I know this is counter intuitive. Each jJXXX has an associated Graphics object that is used to draw to it but that doesn't mean it WILL be used by Swing to draw to it no matter what.

The graphics coming to you through the parameter in paintComponent is NOT the same graphics as the one you get from getGraphics(), even though paintComponent() is a method on the same object as you're invoking getGraphics on.

If you want to see this, just set a boolean to this statement first line in paintComponent(Graphics g):

boolean sameObject = (g== getGraphics())

and print out sameObject. You'll see the word false.

So both are being used to draw to the screen. You see it because at that time your canvas's g is doing the drawing. Then micro-second later, the g you're receiving as a parameter is doing the drawing, and it draws last.

The one that draws last wins. It's sort of a reverse show-down.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Swing God
  • 11
  • 1