背景与我其他JLabel的愿景重叠

时间:2019-06-18 15:59:26

标签: java background jlabel

我正在使用JFrame和JLabels创建一个非常简单的游戏,我设法使其正常运行,但是在放置背景图像时却发现了问题。我设置为背景的图像覆盖了我的其他JLabel(它们仍然在后面工作,但您看不到它们)。

public class Game extends JPanel {

    Player p1 = new Player(this, 'a');
    Player p2 = new Player(this, 'r');

    public Game() {}

    public void move() {}
    public void gameOver() {}

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        p1.paint(g2d);
        p2.paint(g2d);
    }

    public static void main(String[] args) throws InterruptedException, IOException {

        BufferedImage img = ImageIO.read(new File(not relevant));
        JFrame frame = new JFrame("Window");
        JLabel background = new JLabel(new ImageIcon(img));
        Game game = new Game();


        frame.add(game);
        frame.add(background);


        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        while (true) {
            game.move();
            game.repaint();
            Thread.sleep(10);
        }
    }

}

我认为问题出在使用我的类Game(其中的“运行”游戏的类)作为JPanel,然后在Main中创建一个JFrame并将其添加...如果没有办法解决这个问题,我会更改它,但希望保持现在的状态。 我尝试过交换:

frame.add(游戏); frame.add(background);

但是结果是:

游戏->背景->您只能看到背景,但仍然可以玩游戏

background-> game->您只能看到一个迷你窗口(没有大小,只能最小化,最大化和关闭),但仍然可以玩游戏。

也尝试在Game类中创建背景图像,但是它不起作用。 预先感谢。

1 个答案:

答案 0 :(得分:0)

JFrame的内容窗格默认情况下使用BorderLayout,这意味着add(game)将把Game组件放置在BorderLayout的中心。 BorderLayout一次只能有一个中心组件,因此add(background)用背景JLabel替换了旧的中心组件(游戏)。

一个简单的解决方案是避免使用JLabel作为背景,而只需使用绘制方法绘制背景即可:

g2d.drawImage(img, 0, 0, this);
p1.paint(g2d);
p2.paint(g2d);

这将在Game类中需要一个BufferedImage类型的私有字段(或只是Image),您可以在该类的构造函数中进行设置。

请注意,您几乎应该始终覆盖paintComponent而不是绘画:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    // ...
}

有关Swing组件绘制的所有详细信息,请参见https://www.oracle.com/technetwork/java/painting-140037.html

更新:您的background JLabel似乎在调用JFrame的pack()方法时正在定义JFrame内容的大小。

一旦移除了背景JLabel,剩下的唯一组件(Game类的实例)必须定义其自己的首选大小,以便在调用JFrame的pack()方法时,它将知道JFrame内容的大小。您可以通过让Game类明确报告其首选大小来做到这一点:

@Override
public Dimension getPreferredSize() {
    return new Dimension(img.getWidth(), img.getHeight());
}

这将要求img的类型为BufferedImage,因为在Image类中不存在零参数的getWidth和getHeight方法。