Search code examples
javaswingpaintgraphics2d

Paint component over background


I have a little problem drawing some images. I am using a JDialog to display the background and a separated class to display the cards (using sprites).

The background displays well but the JPanel don't.

Here is my code :

public Main(java.awt.Frame parent, boolean modal) {
    super(parent, modal);
    initComponents();

    //Call the board to draw cards
    Board plateau = new Board(); 

    this.add(plateau);
}

/**
 * Paint the background
 *
 * @param g
 */
@Override
public void paint(Graphics g) {  
    try {      
        Graphics2D g2 = (Graphics2D) g;

        this.background_image = ImageIO.read(new File(this.background));
        Graphics2D big = this.background_image.createGraphics();
        Rectangle rectangle = new Rectangle(0, 0, 20, 20);
        g2.setPaint(new TexturePaint(this.background_image, rectangle));

        Rectangle rect = new Rectangle(0, 0, this.getWidth(), this.getHeight());
        g2.fill(rect);
    } catch (IOException ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }
}

And the class that should draw the cards :

@Override  
public void paint(Graphics g) {
    try {
        this.image = ImageIO.read(new File("Ressources/images/cardsprite.gif"));

        //4 lines
        for (int i = 0; i < 4; i++) {
            //13 rows
            for (int j = 0; j < 13; j++) {
                //Split one card
                BufferedImage temp = this.image.getSubimage(j * this.CARD_WIDTH,
                        i * this.CARD_HEIGHT, this.CARD_WIDTH, this.CARD_HEIGHT);

                g.drawImage(temp, j * this.CARD_WIDTH,
                        i * this.CARD_HEIGHT, this);
            }
        }


    } catch (IOException ex) {
        Logger.getLogger(Board.class.getName()).log(Level.SEVERE, null, ex);
    }

If I put the cards drawing class into the paint method of the Main, it works fine.

Am I missing something ?

Thank you


Solution

  • Essentially, you are breaking the paint chain, which is preventing your "main" class from painting any of it's children.

    Start by taking a look at Painting in AWT and Swing for an overview of the paint process.

    You, also, shouldn't be overriding paint, but instead, should be overriding paintComponent from something that extends JComponent.

    Take a look at Performing Custom Painting for more details.

    Basically, you should create a "back ground" panel, which is responsible for painting the background and then add the component responsible for painting the cards on top of it, making sure that it is transparent (setOpaque(false)) so the background shows through.

    If you're not doing any dynamic effects, you could even us a JLabel for the background pane.

    You should avoid doing anything in any paintXxx method that could be potentially time consuming, like loading images. The paint process should be optimised to allow it to run as fast as possible...