Фон, перекрывающий видение моей другой JLabels - PullRequest
1 голос
/ 18 июня 2019

Я создаю очень простую игру с JFrame и JLabels, мне удалось заставить ее работать, но во время размещения фона я обнаружил проблему.Изображение, которое я установил в качестве фона, покрывает мои другие JLabels (они все еще работают позади, но вы не можете их видеть).

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, а затем в главном, создавая JFrame и добавляя его… если нет способа решить эту проблему, я изменю его, но хотел бы сохранить его таким, как сейчас.Я пытался поменять местами:

frame.add (игра);frame.add (background);

но результаты таковы:

game -> background -> вы можете видеть только фон, но все равно можете играть в игру

background -> game -> вы можете видеть только мини-окно (без размера, только минимизировать, максимизировать и закрыть), но все равно можете играть в игру.

Также попытался создать фоновое изображение вКласс игры, но это не работает.Заранее спасибо.

1 Ответ

0 голосов
/ 18 июня 2019

Панель содержимого JFrame по умолчанию использует BorderLayout, что означает, что add(game) поместит компонент Game в центр BorderLayout.BorderLayout может иметь только один центральный компонент за раз, поэтому add(background) заменяет старый центральный компонент (игру) на фоновый JLabel.

Простое решение состоит в том, чтобы не использовать JLabel для фона, и простозакрасьте фон в вашем методе рисования:

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

Для этого потребуется закрытое поле типа BufferedImage (или просто изображение) в вашем классе Game, которое вы можете установить в конструкторе этого класса.

Обратите внимание, что вы почти всегда должны переопределять paintComponent , а не рисовать:

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

Все подробности относительно рисования компонентов Swing см. https://www.oracle.com/technetwork/java/painting-140037.html.

Обновление : может показаться, что ваш background JLabel определял размер содержимого JFrame при вызове метода JFrame pack().

Как только фоновый JLabel был удален, единственнымоставшийся компонент (экземпляр класса Game) должен определить свой собственный предпочтительный размер, чтобы при вызове метода JFrame pack() онзнать, какого размера должно быть содержимое JFrame.Вы можете сделать это, явно указав классу Game свой предпочтительный размер:

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

Для этого потребуется img типа BufferedImage, поскольку методы getWidth и getHeight с нулевым аргументом не существуют вКласс изображения.

...