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

我试图将一个水族馆(它是一个扩展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;

    }

}



炎炎设计
浏览 185回答 1
1回答

繁花不似锦

问题是它只显示一个图像,而不是水族箱顶部的鱼(水族箱或鱼,取决于首先将哪个图像添加到 JFrame)。默认情况下 aJPanel使用 a FlowLayout,它尊重添加到它的任何组件的首选大小。默认情况下 aJFrame使用 a BorderLayout,如果您不指定约束,组件将添加到CENTER的BorderLayout,这意味着组件会自动调整大小以填充框架的空间。因此,您添加到框架的组件将调整大小以填充框架。添加到面板的组件的大小为 (0, 0),因此无需绘制任何内容。所以一些自定义绘画技巧:覆盖getPreferredSize()面板的方法以返回图像的大小,以便布局管理器可以完成其工作调用 super.paintComponent(..) 作为确保背景被清除的第一条语句。不要在paintComponent() 方法中读取图像。每当 Swing 确定需要重新绘制组件时,都可以调用此方法,因此继续读取图像效率不高。相反,应该在类的构造函数中读取图像。不要在绘画方法中调用 repaint() 。这将导致无限的绘画循环。此外,在使框架可见之前,应将组件添加到框架中。综上所述,Alerra 在评论中建议在同一面板中绘制两个图像是一个好主意。它简化了绘画,您甚至可以通过保留要绘制的图像的 ArrayList 轻松绘制多条鱼。然后您只需绘制背景,然后遍历 ArrayList 以绘制单个鱼。查看自定义绘画方法以获取工作示例。例子只画了Rectangle,但是概念是一样的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java