Hey,

We are creating a 2d (top-down) game that consists of 30 x 20 'tiles' of 30px large. The tiles should be drawn on a class that inherits (extends) JPanel, let's call it Level. The tiles are also classes, and there are also entities which represent the player and monsters. Each of these classes has a draw method which calls a method in Level which takes care of drawing the images.

We use a GridBagLayout that uses a bunch of JLabels in a 2d array. Basically, if a label is not yet present at some position x, y, we create a new label with the correct image, and show it in the grid at position x, y.

The code is like this (with some details omitted):
Code:
public JLabel[][] grid = new JLabel[30][20];

public void drawAtXY(String file, int x, int y) {

        ImageIcon symbol = new ImageIcon();

        // New gridbag properties
        GridBagConstraints c = new GridBagConstraints();
        // set contraint to horizontal aligment
        c.fill = GridBagConstraints.HORIZONTAL;

        // filename
        String filenaam = "sprites/" + file + ".gif";       
        symbol = new ImageIcon(filenaam);
        
        // check if the component exists, if yes remove it
        if (this.isAncestorOf(grid[x][y])) {
            this.remove(grid[x][y]);
        }

        // create a new label
        JLabel j = new JLabel(symbol);  // pass symbol to get image into the label
        j.setPreferredSize(new Dimension(30, 30));
        grid[x][y] = j;

        // we add a mouse listener here to j

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = x;
        c.gridy = y;
        this.add(grid[x][y], c);

        this.validate();
    }
The file parameter is the name of the image, the x and y parameters are the coordinates of the tile to draw (not the actual position in pixels, but rather from 0 to 30 (x) and 0 to 20 (y)).


This seems to work fine for us. In .NET I would have done it very differently by overriding the Paint method (and I know this can be done in java too) and invalidating only the region that needs to be painted, but we didn't get that to work the way we wanted, and we ended up with this solution. I know using manual painting with a Graphics object may be faster, but this method is fast enough for the game. So I hope we can keep using this method.


Now, the problem is that the actual JPanel (Level) is slightly bigger (one tile on each side) then necessary. It should be 30*30 wide and 30*20 high, but it is actually 30*32 and 30*22. The reason for this is that we want to have a permanent wall around the level, which is simply a background image to the JPanel.

So, I tried to custom draw the background image onto the panel like this
Code:
    @Override public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (backgroundImage != null) {
            g.drawImage(backgroundImage, 0, 0, null);
        }
    }
(backgroundImage is loaded in constructor, and not null, confirmed)


Finally the problem: it doesn't seem to draw the image. Either that or something is blocking it from view.

The Level JPanel draws its tiles in the middle, leaving a border of exactly 30 pixels on each side (which is correct, though I have no idea WHY it's doing that, I can't see where we are telling it to do that). But the border is completely black, because that is the backgroundColor of the JPanel. If I make the background a different color the border is that color too.

I can't understand this. If the background color is showing, then I don't think something is blocking it, so why is the image not showing?

Thanks!