我正在尝试将水族馆(这是扩展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;
}
}
答案 0 :(得分:1)
问题在于,它仅显示一个图像,而不是在水族馆顶部显示鱼(水族馆或鱼,具体取决于首先将哪个图像添加到JFrame)。
默认情况下,JPanel
使用FlowLayout
时要遵守添加到其中的任何组件的首选大小。
默认情况下,JFrame
使用BorderLayout
,如果您未指定约束,则组件会添加到CENTER
的{{1}}中,这意味着该组件会自动调整大小以填充框架的空间。
因此,添加到框架的组件的大小将被设置为可填充框架。添加到面板的组件的大小为(0,0),因此无需绘制任何内容。
一些自定义绘画技巧:
重写面板的BorderLayout
方法以返回图像的大小,以便布局管理器可以完成其工作
调用super.paintComponent(..)作为确保清除背景的第一条语句。
不要在paintComponent()方法中读取图像。每当Swing确定需要重新粉刷组件时都可以调用此方法,因此继续读取图像效率不高。相反,应该在类的构造函数中读取图像。
不要在绘画方法中调用repaint()。这将导致无限的绘画循环。
此外,在使框架可见之前,应将组件添加到框架中。
如上所述,Alerra在评论中建议在同一面板上绘制两个图像是一个好主意。它可以简化绘制过程,甚至可以通过保留要绘制的图像的ArrayList来轻松绘制多条鱼。然后,您只需绘制背景,然后遍历ArrayList即可绘制单个鱼。
查看Custom Painting Approaches以获取有效示例。该示例仅绘制Rectangle,但是概念相同。