GUI因图像加载而不断崩溃?

时间:2014-01-09 02:15:49

标签: java image swing jframe awt

我目前正在尝试为一个类创建游戏,我决定尝试加载GUI并显示背景图像。

但是,我决定创建一个单独的ImageLoader类,它具有一个缓存已经加载过的图像并存储和/或返回新的BufferedImages的HashMap。这样做的主要目的是轻松有效地访问即将实施的多个敌方实体/导弹的精灵。

现在Game类没有完成,但它应该运行,它确实如此!只是不像我预期的那样。

我希望它能够运行并显示带有背景图像的GUI,但GUI会显示一瞬间然后崩溃。

这是Game类(在runGameLoop方法中绘制图像)

import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

public class Game extends Canvas{

private JFrame frame;
private BufferStrategy strat;
private boolean stillPlaying;


public Game(){
    frame = new JFrame("Pirate Game!");

    frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });

    frame.getContentPane().add(this);
    setIgnoreRepaint(true);
    frame.setSize(800,600);
    setBounds(0,0,800,600);
    frame.pack();
    frame.setResizable(false);
    frame.setVisible(true);
    this.createBufferStrategy(2);
    strat = getBufferStrategy();
    stillPlaying = true;
}

public static void main(String[] args) {
    Game g = new Game();
    g.runGameLoop();
}

private void runGameLoop() {
    long initLoop = System.currentTimeMillis();
    //while(stillPlaying){
        long change = initLoop - System.currentTimeMillis();
        initLoop = System.currentTimeMillis();
        Graphics2D gfx = (Graphics2D) strat.getDrawGraphics();
        BufferedImage sourceImage = ImageLoader.getImageLoader().getImage("resources/Untitled.jpg");
        gfx.drawImage(sourceImage,0,0,null);
    //}
}

}

这是ImageLoader类

import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.HashMap;

import javax.imageio.ImageIO;


public class ImageLoader {

private HashMap<String,BufferedImage> storedImages = new HashMap<String,BufferedImage>();
private static ImageLoader single = new ImageLoader();

public static ImageLoader getImageLoader() {
    return single;
}

public BufferedImage getImage(String place) {
    BufferedImage image=null;
    if (storedImages.containsKey(place))
        return storedImages.get(place);
    else{
        try{
            URL location =  this.getClass().getClassLoader().getResource(place);
            if(location == null)
                System.exit(0);

            image = ImageIO.read(location);
        }
        catch(Exception e){
            System.out.println(e);
            System.exit(0);
        }

        storedImages.put(place,image);
        return storedImages.get(place);
    }
}


}

感谢您的帮助!我接受批评。

1 个答案:

答案 0 :(得分:2)

您的图片应与尝试加载它们的类位于同一个包中。一个简单的解决方法是只复制所有图像(如果您使用的是IDE),右键单击该包并粘贴。只要你只使用图像文件名作为路径,即“mypic.png”,它应该可以正常工作。


修改

所以我让它停止关闭。我所做的就是改变这个

URL location =  this.getClass().getClassLoader().getResource(place);

URL location =  this.getClass().getResource(place);

唯一的问题是,图像不是绘画。我不确定Canvas是如何工作的,AWT,我只是熟悉Swing,因此我将其更改为JPanel并覆盖了paintComponent方法。并做了一些其他微妙的变化。你可以看看。如果您有任何问题,请告诉我。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Game extends JPanel {

    private JFrame frame;
    private BufferStrategy strat;
    private boolean stillPlaying;

    public Game() {
        frame = new JFrame("Pirate Game!");

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        frame.getContentPane().add(this);
        setIgnoreRepaint(true);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
        stillPlaying = true;
    }

    public static void main(String[] args) {
        Game g = new Game();
        g.runGameLoop();
    }

    private void runGameLoop() {
        long initLoop = System.currentTimeMillis();
        // while(stillPlaying){
        long change = initLoop - System.currentTimeMillis();
        initLoop = System.currentTimeMillis();
        //Graphics2D gfx = (Graphics2D) strat.getDrawGraphics();
        //BufferedImage sourceImage = ImageLoader.getImageLoader().getImage(
                //"stackoverflow.png");
        //gfx.drawImage(sourceImage, 0, 0, null);
        // }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        BufferedImage sourceImage = ImageLoader.getImageLoader().getImage(
                "stackoverflow.png");
        g.drawImage(sourceImage, 0, 0, this);
    }

    public Dimension getPreferredSize() {
        return new Dimension(800, 600);
    }

}

另一种可行的方法是,resources位于src文件夹中。也许不是之前

enter image description here

然后是您之前使用的代码片段

BufferedImage sourceImage = ImageLoader.getImageLoader().getImage(
                "resources/stackoverflow.png");

.....

URL location = this.getClass().getClassLoader().getResource(place);

注意,在上面的方案中,当使用getClass().getResource()时,如果没有classLoader(),则您的路径应以/

开头