【问题标题】:Only one image shows up when i load a list of images加载图像列表时仅显示一张图像
【发布时间】:2013-09-06 17:45:07
【问题描述】:

我正在编写一个塔防游戏,我需要将加载了缓冲图像的 JPanel 列表放置到 JFrame 上。我正在使用 for 循环将 JPanel 放置到 JFrame 上,但是,当我运行程序时,只显示列表中的最后一个 JPanel。我已经检查以确保图像没有被放置在另一个上,并且它们被放置在三个不同的位置。

这是创建 JFrame 的类的代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.List;
import java.util.ArrayList;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;    

public class GameScreen extends JPanel 
                    implements MouseListener {

    private ArrayList< JPanel > images;
    private TDGame currentGame;
    private JFrame frame;
    private static final int width = 700;
    private static final int length = 700;

    public void mouseExited(MouseEvent e) {
        this.repaint();
    }
    
    public void mouseEntered(MouseEvent e) {
        this.repaint();
    }
    
    public void mouseReleased(MouseEvent e) {
        this.repaint();
    }
    
    public void mousePressed(MouseEvent e) {
        this.repaint();
    }
    
    public void mouseClicked(MouseEvent e) {
        this.repaint();
    }
    
    public GameScreen() {
        super();
        images = new ArrayList<JPanel>();
        currentGame = new TDGame();
        frame = new JFrame("Tower Defense");
        frame.setSize(width, length);
        frame.setVisible(true);
        frame.pack();
        frame.getContentPane().add(this,BorderLayout.CENTER);
        currentGame.EnemyForce.add(currentGame.EnemyForce.size(),
                                new BasicEnemy(0, 0, LoadImage()));
        currentGame.EnemyForce.add(currentGame.EnemyForce.size(),
                                new BasicEnemy(250, 250, LoadImage2()));
        currentGame.EnemyForce.add(currentGame.EnemyForce.size(),
                                new BasicEnemy(0, 0, LoadImage1()));

        this.repaint();
    }

    public BufferedImage LoadImage() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("Saturn-Intruder.png"));
        } catch (IOException e) {
        }
        return img;
    }
    
    public BufferedImage LoadImage1() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("Level1-TD.jpeg"));
        } catch (IOException e) {
        }
        return img;
    }
    
    public BufferedImage LoadImage2() {
        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("BlackBird-Intruder.jpeg"));
        } catch (IOException e) {
        }
        return img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        for(int i = 0; i < currentGame.Defense.size(); i++) {
            frame.add(currentGame.Defense.get(i));
        }

        for(int i = 0; i < currentGame.EnemyForce.size(); i++) {
            frame.add( currentGame.EnemyForce.get(i));
        }

        for(int i = 0; i < currentGame.ShotsFired.size(); i++) {
            frame.add(currentGame.ShotsFired.get(i));
        }
    }
}

这是我将 JPanel 放置到 JFrame 上的代码:

import java.awt.*;
import javax.swing.*;
import java.awt.image.BufferedImage;

public class BasicEnemy extends Entity {
    JPanel ePanel;
    Graphics g;

    public BasicEnemy(double x, double y, BufferedImage image) {
        super(x, y, image);
        ePanel = new JPanel();
        ePanel.setVisible(true);
    }

    protected void paintComponent(Graphics g) {
        g.drawImage(getImage(), (int)(getXCoord()),
                            (int)(getYCoord()), null);
    }
}

我该如何解决这个问题,以便放置所有图像,而不仅仅是一个?

【问题讨论】:

  • 1) 为了尽快获得更好的帮助,请发帖 SSCCE。 2) 源代码中的一个空白行总是就足够了。 { 之后或} 之前的空行通常也是多余的。 3)请学习常用的Java naming conventions(特别是用于名称的大小写)的类、方法和属性名称,并始终如一地使用它们。 4) 对代码块使用一致且符合逻辑的缩进。代码的缩进是为了帮助人们理解程序流程。
  • 1) 不要设置顶级容器的大小。而是布局内容并致电pack()。 2) 到部署时,这些资源可能会变成embedded-resource。在这种情况下,资源必须由URL 而不是File 访问。请参阅标签的info page,了解形成URL 的方法。 3) 不要在paintComponent(..) 方法中添加组件 这本身会触发repaint() 和无限循环。 4) 绘制图像时,使用ImageObserver,而不是null
  • 事实上,我越看那个资源,我就越认为你应该把它扔掉,重新开始,用新的学习资源。这是无法挽救的。
  • 即使您不应该在您的绘制方法中添加组件,添加更多组件只是将它们放置在边框布局的中心位置,这意味着只有最后添加的组件是可见的

标签: java image swing jframe jpanel


【解决方案1】:

我不知道为什么你的游戏只显示一张图片。但随着这款游戏的进一步发展,我强烈建议您不要在自己的 JPanel 中添加每张图片。

我会用你的源代码做什么才能让它工作。

  • 从 BasicEnemy(以及所有其他类似的类)中删除 JPanel
  • 将 GameScreen.paintComponent 中的所有 for 循环更改为读取

    for(...) { currentGame.EnemyForce.get(i).paintComponent(g); }

  • 在 GameScreen 的构造函数中,在 frame.setVisible(true); 之前添加 frame.add(this);

如果您打算在 Swing 中使用图形,则永远不应将作为游戏一部分的单个元素保存在 JCompondents 中。你应该使用你的 GameScreen 作为你的“画布”,并且在 paintComponent 内部使用 Graphics 对象来绘制你所有的游戏内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 2021-11-30
    • 2010-12-06
    相关资源
    最近更新 更多