Search code examples
javaswinggraphicspaintcomponent

Paint from different classes


I'm trying to make a game in Java (school project) and I have the following setup:

A main class, extended with JFrame, a 'Game' class, extended with JPanel.

Now from within this main class, I make calls to a class 'Player' and a class 'Map'.. The class 'Map' exists of two subclasses 'Blocks' and 'Bombs'.

But I'm wondering.. How do I let the paint methods of all this classes paint to the same JPanel (of the class Game)?

I gave every class the method 'public void paint(Graphics g)' and do the painting.. But only the painting of the class 'Game' shows up when i run the program, not the painting from the subclasses.

How do I implement this?

By example, I reduced my code to this:

Main class:

    BomberGame game = new BomberGame();
        add(game);
        setSize(400, 400);
        setTitle("Bomber");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.show();

    }

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

Game class:

    package bomberb1;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


import java.util.ArrayList;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class BomberGame extends JPanel {
    public BomberGame() {;
        BomberMap map = new BomberMap(this);
    }

    public void paint(Graphics g) {
        g.drawRect(10, 10, 10, 10);
        g.setColor(Color.red);
        g.fillRect(10, 10, 10, 10);
    }
}

Map class:

    package bomberb1;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
import javax.swing.SwingUtilities;
public class BomberMap{
    BomberGame game;
    public BomberMap(BomberGame game) {
        this.game = game;
    }
    public void paint(Graphics g) {
        g.drawRect(30, 30, 20, 20);
    }
}

Solution

  • In the Entity class (which could be Map player etc) to be drawn have a draw method that accepts a Graphics object thus allowing it to access the Graphics object of the JPanel and draw to it, something like:

    class GamePanel extends JPanel {
    
        Entity e=new Entity;
    
        @Override
        protected paintComponent(Graphics g) {
            super.paintComponent(g);
    
            e.draw(g);//call draw method for entity and pass graphics object
        }
    
    }
    
    class Entity {
    
       //will draw whats necessary to Graphics object
        public void draw(Graphics g) {
            //draw to the graphics object here
        }
    }
    

    Other suggestions:

    • Do not extend JFrame class unnecessarily
    • override JPanel paintComponent() and not paint() (+1 to trashGod comment)
    • Swing components should be created and manipulated on Event Dispatch Thread via SwingUtilities.invokeLater(..) block.

    UPDATE:

    As @GuillaumePolet stated a better game design would be implementing JPanels as parent class for most of the game entities see this similar answer for more.