为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 JFrame 上显示两个带有图像的 JPanel,并且两个 img 都可见?

如何在 JFrame 上显示两个带有图像的 JPanel,并且两个 img 都可见?

炎炎设计 2021-09-15 10:25:32
我试图将一个水族馆(它是一个扩展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,如果您不指定约束,组件将添加到CENTERBorderLayout,这意味着组件会自动调整大小以填充框架的空间。

因此,您添加到框架的组件将调整大小以填充框架。添加到面板的组件的大小为 (0, 0),因此无需绘制任何内容。

所以一些自定义绘画技巧:

  1. 覆盖getPreferredSize()面板的方法以返回图像的大小,以便布局管理器可以完成其工作

  2. 调用 super.paintComponent(..) 作为确保背景被清除的第一条语句。

  3. 不要在paintComponent() 方法中读取图像。每当 Swing 确定需要重新绘制组件时,都可以调用此方法,因此继续读取图像效率不高。相反,应该在类的构造函数中读取图像。

  4. 不要在绘画方法中调用 repaint() 。这将导致无限的绘画循环。

此外,在使框架可见之前,应将组件添加到框架中。

综上所述,Alerra 在评论中建议在同一面板中绘制两个图像是一个好主意。它简化了绘画,您甚至可以通过保留要绘制的图像的 ArrayList 轻松绘制多条鱼。然后您只需绘制背景,然后遍历 ArrayList 以绘制单个鱼。

查看自定义绘画方法以获取工作示例。例子只画了Rectangle,但是概念是一样的。


查看完整回答
反对 回复 2021-09-15
  • 1 回答
  • 0 关注
  • 184 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信