从源文件夹加载图像返回为null

时间:2015-02-13 00:52:24

标签: java swing file-io null embedded-resource

您好我从资源文件夹导入图像时遇到问题。我看了很多谷歌(或者我认为),我不知道我做错了什么。

感谢所有帮助

以下是我的java项目的图片:

Here is my picture

这是我的Game代码:

public Game(){

    handler = new Handler();
    this.addKeyListener(new KeyInput(handler));

    new Window(WIDTH, HEIGHT, "Testing", this);

    BufferedImageLoader loader = new BufferedImageLoader();
    level = loader.loadImage("/level.png");

    hud = new HUD();
    spawn = new Spawn(handler, hud);
    r = new Random();
    walls = new WallsMap(handler);
    cam = new Camera(0, 0);

    walls.render();  
    handler.addObject(new Player(WIDTH/2-32, HEIGHT/2-32, ID.Player, handler));
}

最后这是我的BufferedImageLoader课程:

    public class BufferedImageLoader {

    private BufferedImage image;

    public BufferedImage loadImage(String path){
        try {
            image =  ImageIO.read(getClass().getClassLoader().getResourceAsStream(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }
}

2 个答案:

答案 0 :(得分:4)

要解决您的特定问题,这两个选项中的任何一个都应该有效,以便可以正确定位资源:

  • 从您的loadImage方法中删除对getClassLoader()的调用,以便调用只是getClass().getResourceAsStream(path) -OR -
  • "/level.png"删除斜杠,以便您对loadImage的调用看起来像loader.loadImage("level.png")

但是,总的来说,我同意mastercork889,最好将资源整理到软件包中。

编辑:

回应mastercork889的评论说我的答案应该是AND而不是OR,我想我应该详细说明为什么它确实是异或。我本来只是评论过,但我还是太新了,不能堆栈溢出来被允许发表评论,这无论如何都是相当多的信息:)

删除对getClassLoader()的调用是有效的,因为您正在使用getResourceAsStream()类中的Class方法,该方法在委派给getResourceAsStream()方法之前执行了额外的工作ClassLoader班。

来自the Java API

  

在委托之前,使用此算法从给定的资源名称构造绝对资源名称:

     
      
  • 如果名称以'/'('\ u002f')开头,则资源的绝对名称是'/'后面的名称部分。
  •   

由于您的资源不在包中,并且位于源文件夹的顶层(看起来res是“Eclipse源文件夹”),因此level.png部分位于斜杠将以绝对的方式充分识别资源的位置。

OR

"/level.png"删除斜杠也有效,因为当对象的类加载器(应该是系统类加载器)查找资源时,它将尝试以绝对方式解析您的资源。开头斜杠的特殊处理是getResourceAsStream()Class方法特有的行为,而不是ClassLoader

AND不起作用的原因是因为如果从getResourceAsStream()调用Class方法并删除斜杠,那么它将尝试在同一个包中找到资源 关联的类位于。如果您选择使用AND选项,则需要将level.png移动到com.plat.gfx包中。

作为最后一点,我已经构建了一个小型测试程序,其格式与您的示例相同,一旦我按照其中一个建议进行操作,它对我有用。

资源,类和类加载器的微妙之处可能非常棘手。祝你的项目好运!

答案 1 :(得分:2)

不要担心将图像放在特定文件夹中。而是将它们也放在特定包装下的src文件夹中:com.plat.res

我发现将图像放在特定的包中会使包层次结构看起来更有效率,而且不像意大利面条那样。

还有关于包约定的说明:domain-extension.domain.main-program.etc。我的包层次结构如下所示:

com.brennytizer.jumg
com.brennytizer.jumg.res
com.brennytizer.jumg.engine
com.brennytizer.jumg.level
com.brennytizer.jumg.level.maps

如果您没有域名,请写下您认为您的域名(如果您将来要购买),或者只使用您的(向后)名称:

我的名字是Jarod Brennfleck,正在编写程序foobar,我的程序包将是:brennfleck.jarod.foobar

使用ImageIO课程后,请使用ImageIO.read(Game.class.getResourceAsStream("/com/plat/res/leve.png"));课程:{{1}}