JPanel paintComponent 无法正常工作

JPanel paintComponent not working properly

我了解到,如果您覆盖

protected void paintComponent(Graphics g)

您可以将图像绘制为延伸 javax.swing.JPanel 的 class 的背景。 在我的代码中,我有 2 个相同的 Class 扩展 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);

    }

创建和添加 CardPanel 的方法

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();

    }

调用最后一个方法将卡片图像添加到面板,这部分有效。现在我的问题: this is how it looks.(还有一些其他的缺陷,比如卡的位置,但这是以后我可以自己解决的问题) 如您所见,底部的面板 (pCardPanel) 没有背景图像。任何想法为什么会这样?提前致谢

You can get an image painted as the background of a class that extends javax.swing.JPanel

背景通常意味着图像填充整个面板,面板的大小与图像的大小相同。因此,当您绘制图像时,代码应为:

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

因此图像始终绘制在面板的左上角。

将面板添加到框架后,布局管理器将设置面板的位置。

just with a different position

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

我猜问题是 "y" 值超出了面板的大小,所以您看不到图像。

这是您的首选大小并没有考虑到您试图在 (0, 0) 以外的某个位置绘制图像这一事实,在这种情况下,首选大小应该类似于:

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

但是,您不想这样做,因为每个组件都应该独立于其他组件。它不应该知道或关心您正在尝试将两个面板 above/below 彼此放置。它应该只关心绘制自己的图像,让布局管理器担心设置每个面板的位置。

所以您真正想要做的只是在 (0, 0) 处绘制图像,然后让布局管理器确定面板的位置。

您已经在使用 BorderLayout。因此,布局管理器的工作是将组件在 "SOUTH" 中的位置设置为某个非零 "y" 值。