1

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);
    }
}
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
Kaj
  • 2,445
  • 3
  • 23
  • 34
  • 2
    "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[*Painting in AWT and Swing: The Paint Methods*](http://www.oracle.com/technetwork/java/painting-140037.html#callbacks). – trashgod Dec 10 '12 at 16:44
  • _How do I let the paint methods of all this classes paint to the same JPanel_ You don't! This is really the worst design you can choose. You are mixing models and views (see also MVC pattern). You should rather create differents views and nest those panels inside each other. This is the purpose of having a graphical hierarchy (each child paints a subregion of its parent). – Guillaume Polet Dec 10 '12 at 16:49

1 Answers1

7

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.

Community
  • 1
  • 1
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
  • 1
    IMO, Entity should also be a JComponent and override `paintComponent` and should be a child of GamePanel. – Guillaume Polet Dec 10 '12 at 16:53
  • @GuillaumePolet +1 I guess that would depend on OPs choice of game design, but yes that would be an option. – David Kroukamp Dec 10 '12 at 16:55
  • 1
    @GuillaumePolet Or 'paint in an image' as shown [here](http://stackoverflow.com/a/13796268/418556). I only tend to extend components for custom painting these days when I intend to put components over the top of it (very, very rare) or need 1000 FPS(?) performance (but that is looking like 'Full-screen exclusive mode' all the way). – Andrew Thompson Dec 10 '12 at 17:05