我试图将一个水族馆(它是一个扩展JPanel并包含水族馆 img 的类)设置为背景,并在顶部设置一条鱼(它也是一个扩展 aJPanel并包含鱼 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; }}
1 回答
繁花不似锦
TA贡献1851条经验 获得超4个赞
问题是它只显示一个图像,而不是水族箱顶部的鱼(水族箱或鱼,取决于首先将哪个图像添加到 JFrame)。
默认情况下 aJPanel
使用 a FlowLayout
,它尊重添加到它的任何组件的首选大小。
默认情况下 aJFrame
使用 a BorderLayout
,如果您不指定约束,组件将添加到CENTER
的BorderLayout
,这意味着组件会自动调整大小以填充框架的空间。
因此,您添加到框架的组件将调整大小以填充框架。添加到面板的组件的大小为 (0, 0),因此无需绘制任何内容。
所以一些自定义绘画技巧:
覆盖
getPreferredSize()
面板的方法以返回图像的大小,以便布局管理器可以完成其工作调用 super.paintComponent(..) 作为确保背景被清除的第一条语句。
不要在paintComponent() 方法中读取图像。每当 Swing 确定需要重新绘制组件时,都可以调用此方法,因此继续读取图像效率不高。相反,应该在类的构造函数中读取图像。
不要在绘画方法中调用 repaint() 。这将导致无限的绘画循环。
此外,在使框架可见之前,应将组件添加到框架中。
综上所述,Alerra 在评论中建议在同一面板中绘制两个图像是一个好主意。它简化了绘画,您甚至可以通过保留要绘制的图像的 ArrayList 轻松绘制多条鱼。然后您只需绘制背景,然后遍历 ArrayList 以绘制单个鱼。
查看自定义绘画方法以获取工作示例。例子只画了Rectangle,但是概念是一样的。
添加回答
举报
0/150
提交
取消