Search code examples
javaswingjframejpanelpaintcomponent

paintComponent clears the JPanel when paint an image


I have this code:

package game;

import java.awt.Graphics;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Draw {

Object block;

public Draw(JFrame frame, Object object) {
    this.block = object;

    JPanel pane = new JPanel() {
        private static final long serialVersionUID = 3869097656854760151L;

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            try {
                g.drawImage(ImageIO.read(new File(object.getTexture())), object.getX(), object.getY(), object.getWidth(),
                        object.getHeight(), null);
            } catch (IOException e) {
                System.err.println("Image '" + object.getTexture() + "' could not be found!");
            }
        }
    };

    frame.add(pane);
}
}

and I call the class here:

package game;

import javax.swing.JFrame;

public class Frame {

private final int X_SIZE = new vena.util.Computer().screenWidth();
private final int Y_SIZE = new vena.util.Computer().screenHeight();

public Frame() {
    JFrame f = new vena.util.Frame().frame("2D Game", X_SIZE - X_SIZE   /   5,  Y_SIZE - Y_SIZE / 5, true, false, false,
            "res/icon.png");

    new Draw(f, new Object(0, 0, 100, 100, "grass"));
    new Draw(f, new Object(100, 0, 100, 100, "grass"));

    f.setVisible(true);
}

public static void main(String[] args) {
    new Frame();
}
}

It renders when I call the image with

new Draw(f, new Object(0, 0, 100, 100, "grass"));

But when I call the image another time, next to it

new Draw(f, new Object(100, 0, 100, 100, "grass"));

it only renders the second image, and removes the first one. I have noticed that this doesn't occur when I call g.drawImage() twice in the paintComponent method. Is there a way so that I can call the Draw class as many times as I want, without clearing the JPanel?


Solution

  • The default layout manager of the content pane of a frame is the BorderLayout. When you add components to a BorderLayout and you don't specify a constraint the component goes to the CENTER. Only the last component added can be displayed in the CENTER.

    If you want multiple components on the frame then you can change the layout manager. Try

    f.setLayout( new FlowLayout() );
    

    to see the difference.

    I have noticed that this doesn't occur when I call g.drawImage() twice in the paintComponent method.

    Yes, if you are trying to paint images at specific locations on the frame then you should really be overriding paintComponent() to paint each image.