Coulis
Coulis

Reputation: 194

JLabel over another JLabel not working

I've been trying to put a JLabel over another one for my Roguelike. Unfortunaly, it doesn't seems to work. Here's my code so far :

public void updateDraw(int direction){
    int[] pos = Dungeon.getPos();

    for(int i=pos[1]-(DISPLAY_Y_SIZE/2) ; i<pos[1]+(DISPLAY_Y_SIZE/2) ; i++){
        for(int j=pos[0]-(DISPLAY_X_SIZE/2) ; j<pos[0]+(DISPLAY_X_SIZE/2) ; j++){
            labelGrid[i-(pos[1]-(DISPLAY_Y_SIZE/2))][j-(pos[0]-(DISPLAY_X_SIZE/2))].setIcon(tiles[Dungeon.getMapTile(i,j)].getIcon());      
        }
    }

    labelGrid[DISPLAY_Y_SIZE/2][DISPLAY_X_SIZE/2].add(character);

    this.repaint();
}

I've read some solutions to other problems, and they all do it by simply adding the JLabel to the other one. it doesn't work as intended here, any idea why ?

PS : I don't want to use a JLayeredPane for my JPanel.

Upvotes: 0

Views: 91

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 208944

One Alternative

Don't create your game environment using components (i.e. JLabels). Instead, you can paint all your game objects.

For instance, if you're doing something like:

JLabel[][] labelGrid = JLabel[][];
...
ImageIcon icon = new ImageIcon(...);
JLabel label = new JLabel(icon);
...
for(... ; ... ; ...) {
   container.add(label);
}

You could instead get rid of the labels all together, and also use Images instead of ImageIcons, then you can just paint all the images to a single component surface. Maybe something like:

public class GamePanel extends JPanel {
    Image[][] images = new Image[size][size];
    // init images

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image,/*  Crap! How do we know what location? Look Below */);
    }  
}

So to solve this problem with the locations (i.e. the x and y, oh and the size also), we could use some good old OOP abstractions. Create a class that wraps the image, the locations, and sizes. For example

class LocatedImage {
    private Image image;
    private int x, y, width, height;
    private ImageObserver observer;


    public LocatedImage(Image image, int x, int y, int width, 
                                     int height, ImageObserver observer) {
        this.image = image;
        ...
    }

    public void draw(Graphics2D g2d) {
        g2d.drawImage(image, x, y, width, height, observer);
    }
}

Then you can use a bunch of instances of this class in your panel. Something like

public class GamePanel extends JPanel {
    List<LocatedImage> imagesToDraw;
    // init images
    // e.g. imagesToDraw.add(new LocatedImage(img, 20, 20, 100, 100, this));

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g.create();
        for (LocatedImage image: imagesToDraw) {
            image.draw(g2d);
        }
        g2d.dispose();
    }  
}

Once you have this concept down, there are many different possibilities.

Upvotes: 2

Related Questions