簡體   English   中英

如何在 JFrame 上顯示兩個帶有圖像的 JPanel,並且兩個 img 都可見?

[英]How can I display two JPanels with images on a JFrame, and both of the img to be visible?

我試圖將一個水族館(它是一個擴展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 ,如果您不指定約束,則組件將添加到BorderLayoutCENTER ,這意味着組件會自動調整大小以填充框架的空間。

因此,您添加到框架的組件將調整大小以填充框架。 添加到面板的組件的大小為 (0, 0),因此無需繪制任何內容。

所以一些自定義繪畫技巧:

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

  2. 調用 super.paintComponent(..) 作為確保背景被清除的第一條語句。

  3. 不要在paintComponent() 方法中讀取圖像。 每當 Swing 確定需要重新繪制組件時,都可以調用此方法,因此繼續讀取圖像效率不高。 相反,應該在類的構造函數中讀取圖像。

  4. 不要在繪畫方法中調用 repaint() 。 這將導致無限的繪畫循環。

此外,在使框架可見之前,應將組件添加到框架中。

綜上所述,Alerra 在評論中建議在同一面板中繪制兩個圖像是一個好主意。 它簡化了繪畫,您甚至可以通過保留要繪制的圖像的 ArrayList 輕松繪制多條魚。 然后您只需繪制背景,然后遍歷 ArrayList 以繪制單個魚。

查看自定義繪畫方法以獲取工作示例。 例子只畫了Rectangle,但是概念是一樣的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM