BBB
BBB

Reputation: 305

paintComponent deletes the previously painted components

I am writing a simple painting program. I have created a JPanel, and have over written "public void paintComponent(Graphics g)", I have also created the appropriate Listeners. The problem is that everytime I draw a new shape, my previous one vanishes, Does anyone know how I can keep the previous shapes in their place? I can take the super.paintComponent(g) away, but then the Jpanel's layout will be distorted. Any suggestion is highly appreciated. :) this is my paintComponent method:

public void paintComponent(Graphics g)
{
    super.paintComponent(g);


    int width = xend-xstart;
    int height = yend - ystart;
    if(width<0)
        width *= -1;
    if(height <0)
        height *= -1;
    if(color!= null && shape !=null){
    if(fill.isSelected())
    {
        g.setColor(color);
        if(shape.equals("Rectangle"))
            g.fillRect(xstart, ystart, width, height);
        if(shape.equals("Square"))
            g.fillRect(xstart, ystart, width, width);
        if(shape.equals("Circle"))
            g.fillOval(xstart,ystart,width ,width);

    }
    }

} 

Upvotes: 3

Views: 678

Answers (2)

user949300
user949300

Reputation: 15729

Andrew Thompson's answer is the "typical" way to do what you want. However, if you want to plunge deeper into the depths of Swing...

One of the things that super.paintComponent() does (eventually) is get to JComponent.paintComponent(), which calls ComponentUI.update(). The Javadocs say (italics added by me):

"By default this method will fill the specified component with its background color (if its opaque property is true) and then immediately call paint."

So, try calling setOpaque(false). However, that often leads to other issues, such as when you really do want to erase what was drawn before.

Upvotes: 0

Andrew Thompson
Andrew Thompson

Reputation: 168825

To draw multiple "Rectangle", "Square" or "Circle" objects it will be necessary to add them to a collection (e.g. ArrayList‌​) and each call to paintComponent(Graphics), iterate the collection and draw each one.

Either that or draw the shapes in a BufferedImage and draw the image instead.

..wouldnt this affect the efficiency as I draw more and more shapes? because then the paintComponent has to draw many shapes everytime I call repaint();

There are 3 answers that I can give to that. Here they are:

  1. Yes it would.
  2. But no, there would have to be thousands before causing visible slow-down.
  3. In the event that performance is a problem. Use the BufferedImage. That way only one more shape is drawn to the image for each newly added shape, no matter how many ..millions have previously been rendered to it.

..also I need to write an undo function and a List will be useful in that case too

It does sound like the list is the way to go for this use-case.

Upvotes: 4

Related Questions