使用ImageIO输入读取PNG空异常

时间:2019-11-24 23:50:38

标签: java javax.imageio

我正在尝试为我的Java课程创建 Pacman 的基本实现,并且已经创建了一个测试项目,以使运动正常运行(目前)。我将尝试在面板上移动JLabel,并尝试将JLabel的图标设置为已加载到项目中的PNG文件。 PNG文件位于名为 Images 的文件夹中,而我所有其他类都位于同一项目的 src 文件夹中。当我尝试从 src 文件夹类读取PNG文件时,出现以下错误:

Exception in thread "main" java.lang.IllegalArgumentException: input == null!
    at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1400)
    at pacman.<init>(pacman.java:16)
    at screen.<init>(screen.java:9)
    at driver.main(driver.java:6)

driver创建一个screen对象,然后创建一个pacman对象,并且错误指向下面的pacman类:

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;

public class pacman {
    Point pacLoc= new Point(0,0);
    Direction pacDir=Direction.RIGHT;
    int pacLives;
    static int count=1;
    int pacID;
    BufferedImage pactest;

    @SuppressWarnings("unused")
    pacman(){
        pacID=count;
        switch(pacID) {
        case 1:
            try {
                pactest=ImageIO.read(getClass().getResource("Images/lolface.png"));
            } catch(IOException a1) {
                a1.printStackTrace();
            }
            pacLoc.setLocation(100,100);
            break;
        case 2:
            try {
                pactest=ImageIO.read(getClass().getResource("Images/whyface.png"));
            } catch(IOException a1) {
                a1.printStackTrace();
            }
            pacLoc.setLocation(100,200);
            break;
        }
        count++;
    }
}

(我认为)该错误源于ImageIO找不到PNG文件。我是否必须以某种方式将它们导入我的pacman类中?在这种情况下,导入语法是什么?我应该提到,我正在使用Eclipse IDE,并且为简单起见,正尝试避免使用任何外部库。

编辑:

目前其他2个课程还不太大,因此如果有帮助,我也可以在这里发布。

编辑2:

使用ImageIO.read(pacman.class.getResource("lolface.png"));代替Images/lolface.png是可行的。谢谢!

1 个答案:

答案 0 :(得分:0)

getClass().getResource()不正确;正确的语法是pacman.class.getResource(...),其中pacman是您自己的类名*。

第二点,您的异常处理已中断。异常包含4个有用的东西(类型,消息,堆栈跟踪和因果链)。

您要扔掉4件事中的3件事。不要那样做或者实际处理它(记录或打印错误是处理!),或者将其向前扔(在方法/构造函数签名上放throws IOException),或者如果这不好, ,请选择catch (Whatever e) { throw new RuntimeException(e); },虽然效果不佳,但比e.printStackTrace()好很多。

您不必导入任何东西; import是别名类型名称(import com.foo.Bar;的意思是:随时在文件Bar中写入并指示一种类型,请想象它改为读取com.foo.Bar。它既不会将Bar类加载到内存中也无法运行其中的任何代码,都与资源无关。

没有错误的堆栈记录,我们无济于事。

IF 这是一个以case 1开头的行或以case 2开头的行中的nullpointerexception,是的,因为找不到资源。

假设您解决了以上问题(pacman.class.getResource而不是getClass().getResource),并且这种情况仍在发生:getResource的工作方式是相对于包含pacman.class的目录。即使该类位于jar文件中。因此,假设您有/home/BotFred/workspace/com.botfred.pacman/build/com/botfred/pacman/pacman.class,则它期望图像位于/home/BotFred/workspace/com.botfred.pacman/build/com/botfred/pacman/Images/lolface.png

如果您不确定从何处加载pacman类,则始终可以执行以下操作来找出:

System.out.println(pacman.class.getResource("pacman.class"));

打印结果将类似于file:///home/BotFred/workspace/com.botfred.pacman/build/com/botfred/pacman/pacman.classjar:file:///home/BotFred/pacman.jar!com/foo/botfred/pacman.class(这表明jar所在的位置,然后在其中,因为jar只是zip文件,放在哪里;然后它将在里面查看com / foo / botfred / Images / lolface.png中的那个jar作为您的图片。

*)原因是getClass()取决于实例化对象的实际类型,而不取决于您正在查看的代码。因此,如果您继承了子类,事情就会崩溃。 pacman可能当前没有被子类化,但是其中的关键词当前却已被继承。也许有一天。如果突然中断,那会很烂。最好从一开始就学习好习惯;始终使用myclassname.class.getResource,因为它与您要完成的任务相匹配(即:使用存储在该代码所在的类文件所在位置的资源)。