如何在JFrame上显示带有图像的两个JPanel,并且两个img都可见?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在JFrame上显示带有图像的两个JPanel,并且两个img都可见?相关的知识,希望对你有一定的参考价值。
我试图将水族馆(这是一个延伸JPanel
和包含水族馆img的类)设置为背景,并在顶部放一条鱼(这也是一个延伸JPanel
并包含鱼img的类)。
问题是它在水族箱顶部只显示一个图像而不是鱼(水族箱或鱼,取决于哪个首先添加到JFrame
)。
主要
public class Core {
JFrame window;
JLabel label;
ImageIcon img;
Aquarium aquarium = new Aquarium();
JavaFish javaFish = new JavaFish();
public void start() {
window = new JFrame();
window.setPreferredSize(new Dimension(600, 400));
window.setVisible(true);
window.setTitle("Java Game");
aquarium.add(javaFish);
window.add(aquarium);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Core c = new Core();
c.start();
}
}
水族馆
public class Aquarium extends JPanel {
private BufferedImage img;
//Initiate aquarium width
public int width;
//Initiate aquarium height
public int height;
@Override
protected void paintComponent(Graphics g) {
width = getSize().width;
height = getSize().height;
try {
img = ImageIO.read(new File("img/AquariumBackground.png"));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Image not fount!");
}
g.drawImage(img, 0, 0, width, height, this);
}
}
鱼
public class JavaFish extends JPanel {
BufferedImage img;
int xPos = 50;
int yPos = 50;
public JavaFish() {
this.setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
BufferedImage JavaFish = LoadImage("img/JavaFish.png");
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(JavaFish, xPos, yPos, 100, 100, null);
repaint();
}
BufferedImage LoadImage(String FileName) {
img = null;
try {
img = ImageIO.read(new File (FileName));
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
}
答案
问题是它在水族箱顶部只显示一个图像而不是鱼(水族箱或鱼,取决于首先添加到JFrame中的鱼)。
默认情况下,JPanel
使用FlowLayout
,它尊重添加到其中的任何组件的首选大小。
默认情况下,JFrame
使用BorderLayout
,如果没有指定约束,则组件会添加到CENTER
的BorderLayout
中,这意味着组件会自动调整大小以填充框架的空间。
因此,添加到框架的组件将调整大小以填充框架。添加到面板的组件的大小为(0,0),因此无需绘制任何内容。
所以一些自定义绘画技巧:
- 覆盖面板的
getPreferredSize()
方法以返回图像的大小,以便布局管理器可以完成其工作 - 调用super.paintComponent(..)作为第一个语句,以确保清除背景。
- 不要在paintComponent()方法中读取图像。只要Swing确定需要重新绘制组件,就可以调用此方法,因此不能有效地继续读取图像。相反,应该在类的构造函数中读取图像。
- 不要在绘画方法中调用repaint()。这将导致无限的绘画循环。
此外,在使框架可见之前,应将组件添加到框架中。
综上所述,Alerra在评论中建议在同一个面板中绘制两个图像是一个好主意。它简化了绘画,您甚至可以通过保留要绘制的图像列表来轻松绘制多条鱼。然后你只需绘制背景,然后遍历ArrayList来绘制单个鱼。
查看Custom Painting Approaches的工作示例。该示例仅绘制Rectangle,但概念是相同的。
以上是关于如何在JFrame上显示带有图像的两个JPanel,并且两个img都可见?的主要内容,如果未能解决你的问题,请参考以下文章