Risk-like game: JPanel paint & MouseEvent problems

Hi,

I’m trying to code a Risk game like this:

  • the Game class adds a JFrame, on which I want to add a Background (image, …) and several Territories (png image with transparency).
  • each Territory has a specific position on the Background, and is non transparent on Territory & transparent on Territory. I add a MouseListener that doesn’t work yet.
  • Problems:
    • only the Territory is painted ; no other paintComponent is ever called. It seems that only the last frame.add(…) is done.
    • how to do to select only non transparent pixels of a Territory ?

Here is the actual code:


public class Game
{
    private World world;
    private ArrayList<Territory> territories;
    private JFrame frame;
    ...

    public Risk()
    {
        frame = new JFrame("Risk");
        territories = new ArrayList<Territory>();
    }

    public void load(String filename)
    {
        loadConfigFile(filename); // load territories from xml filename
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100,100,800,600);
        frame.setPreferredSize(new Dimension(800,600));
        frame.setResizable(false);

        // add World and Territories
        frame.add(new World());      
        for(int i=0; i<territories.size(); i++)
            frame.add(territories.get(i));

        frame.validate();
        frame.pack();
        frame.setVisible(true);
    }
}


class World extends JPanel implements MouseListener
{
    private BufferedImage bg;
    
    public World()
    {
        setOpaque(false);

        // loading background
        try
        {
            bg = ImageIO.read(new File("map.png"));
        }
        catch (IOException e) 
        {
            System.out.println(e);
        }
        
        addMouseListener(this);
    }
    ...
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(bg,0,0,this);
    }
}


class Territory extends JPanel implements MouseListener
{
    private BufferedImage image;
    ...
    
    public Territory(...)
    {
        ...
        setOpaque(false);
        
        try
        {
            image = ImageIO.read(new File(imgName));
            
        }
        catch (IOException e) 
        {
            System.out.println(e);
        }
 
        addMouseListener(this);
    }
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        // draws territory
        g.drawImage(image, (int)imagePosition.getX(), (int)imagePosition.getY(), this);
       ...
    }
    ....
}

Thanks in advance,
Ludo

We had that topic a couple of times:

http://www.java-gaming.org/forums/index.php?topic=3772.msg35496#msg35496

Thank you. But it doesn’t say to me why paintComponent() is not called.

Your problem is that you are calling frame.add() and not frame.getContentPane().add(). I am suprised that you haven’t received an exception while running to this effect.

You also have another problem. You haven’t set the size of your panels, so they are set to 1x1 by the layout manager. You need to override getPreferredSize() to return the size that you want your JPanel to be displayed at.


public Dimension getPreferredSize() {
  return new Dimension(image.getWidth(), image.getHeight());
}

Thank you,

I ever tried to replace add() by getContentPane.add(). The Interface RootPaneContainer Java doc says :

Is the problem coming from the layout ? Do I need to remove the layout ?
Actually there is only one call to paintComponent of the last Territory added to the JFrame ContentPane.

Thank you. But it doesn’t say to me why paintComponent() is not called.

Yes, it doesn’t. I also didn’t bother to take a closer look, because you made it way more complicated than it needs to be.

Incorrect. It can become more visible, just not less. public modifier will still work.

this is about shadowing. I apologize for the mistake. but well it can be safer to keep protected features for the API stability purposal.