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" 值。
我了解到,如果您覆盖
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" 值。