JPanel paintComponent не работает должным образом - PullRequest
0 голосов
/ 16 июня 2020

Я узнал, что если вы переопределите

protected void paintComponent(Graphics g)

, вы можете получить изображение, нарисованное как фон класса, расширяющего javax.swing.JPanel. В моем коде у меня есть 2 экземпляра одного и того же класса, расширяющего JPanel с почти точно таким же кодом, только с другой позицией и фоновым изображением во втором JPanel, и хотя один получает фон, другой нет. Вот мой код:

public class CardPanel extends JPanel {

    private int x, y, width, height;
    private BufferedImage background;

    public CardPanel(int x, int y, int width, int height, BufferedImage background) {

        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.background = background;

        createCardPanel();

    }

    private void createCardPanel() {

        setPreferredSize(new Dimension(width, height));
        setMaximumSize(new Dimension(width, height));
        setMinimumSize(new Dimension(width, height));
        setFocusable(false);
        setOpaque(true);

    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        g.drawImage(background, x, y, null);

    }

}

И как я его использую:

pCardPanel = new CardPanel();
dCardPanel = new CardPanel();

Объявление CardPanels

private void createCardPanels(String imgPath) {

        BufferedImage background = ImageLoader.loadImage(imgPath);

        pCardPanel = new CardPanel(0, (height - Card.CARD_HEIGHT), width, Card.CARD_HEIGHT, background.getSubimage(0, (height - Card.CARD_HEIGHT), width, Card.CARD_HEIGHT));
        dCardPanel = new CardPanel(0, 0, width, Card.CARD_HEIGHT, background.getSubimage(0, 0, width, Card.CARD_HEIGHT));

        this.add(pCardPanel, BorderLayout.SOUTH);
        this.add(dCardPanel, BorderLayout.NORTH);

    }

Метод создания и добавления CardPanels

createCardPanels("/textures/background.png");

Использование метода

public void addCardImage(BufferedImage img, boolean playerCard) {

        JLabel imgLabel = new JLabel();
        ImageIcon icon;
        icon = new ImageIcon(img);
        imgLabel.setIcon(icon);
        cardImages.add(imgLabel);
        if (playerCard)
            pCardPanel.add(imgLabel);
        else
            dCardPanel.add(imgLabel);
        display.pack();

    }

Этот последний метод вызывается для добавления изображений карточек на панель, эта часть работает. Теперь к моей проблеме: вот как это выглядит. (есть и другие fl aws, такие как положение карты, но это будет более поздняя проблема, которую я могу исправить сам) Как видите, панель на внизу (pCardPanel) нет фонового изображения. Есть идеи, почему это может быть так? Заранее спасибо

1 Ответ

1 голос
/ 16 июня 2020

Вы можете получить изображение, нарисованное как фон класса, расширяющего javax.swing.JPanel

Фон обычно подразумевает, что изображение заполняет всю панель и размер панель такая же, как и размер изображения. Поэтому, когда вы рисуете изображение, код должен быть:

g.drawImage(background, 0, 0, null);

Таким образом, изображение всегда отображается в верхнем левом углу панели.

Когда панель добавляется к кадру, менеджер макета установит расположение панели.

просто с другой позицией

pCardPanel = new CardPanel(0, (height - Card.CARD_HEIGHT),

Я думаю, проблема в том, что значение «y» находится за пределами размер панели, поэтому вы не видите изображение.

Это ваш предпочтительный размер не учитывает тот факт, что вы пытаетесь нарисовать изображение в каком-либо месте, кроме (0, 0) в в этом случае предпочтительный размер должен быть примерно таким:

setPreferredSize(new Dimension(x + width, y + height));

Однако вы не хотите этого делать, поскольку каждый компонент должен быть независимым от других компонентов. Он не должен знать или заботиться о том, что вы пытаетесь расположить две панели выше / ниже друг друга. Он должен просто позаботиться о рисовании собственного изображения и позволить менеджеру компоновки задавать расположение каждой панели.

Итак, что вы действительно хотите сделать, это просто нарисовать изображение в точке (0, 0) и позволить Диспетчер компоновки определяет расположение панели.

Вы уже используете BorderLayout. Таким образом, задача менеджера по расположению - установить расположение компонента в «ЮГ» на некоторое ненулевое значение «y».

...