【问题标题】:reading PNG using ImageIO input null exception使用 ImageIO 读取 PNG 输入空异常
【发布时间】:2019-11-24 23:50:38
【问题描述】:

我正在尝试为我的 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 有效。谢谢!

【问题讨论】:

    标签: java javax.imageio


    【解决方案1】:

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

    第二点,你的异常处理被破坏了。 Exceptions 包含 4 个有用的东西(类型、消息、堆栈跟踪和因果链)。

    你扔掉了 4 样东西中的 3 样。不要那样做;要么实际处理它(记录或打印错误 NOT 处理它!),要么继续处理它(将throws IOException 放在你的方法/构造函数签名上),或者如果这也不好,去catch (Whatever e) { throw new RuntimeException(e); } 不是很好,但比 e.printStackTrace() 好很多。

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

    如果没有错误的堆栈跟踪,我们将无法帮助您。

    如果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 的那个 jar 中查看/foo/botfred/Images/lolface.png 为您的图像。

    *) 原因是 getClass() 根据实例化对象的实际类型,而不是您正在查看的代码。所以,如果你子类化,事情就会破裂。或许 pacman 目前没有子类化,但目前有关键字。也许有一天会这样。要是突然断了就惨了最好从一开始就学习好习惯;始终使用myclassname.class.getResource,因为这与您要完成的任务相匹配(即:使用存储在与此代码所在的类文件相同的位置的资源)。

    【讨论】:

    • 感谢您的详细解答!我只是尝试了 pacman.class.getResource 并且错误仍然存​​在。我将尝试按照您接下来描述的方式处理异常并回复您。 pacman 类位于 Pacman/src/pacman.java 中,PNG 位于 Pacman/Images/asd.png 编辑:运行 Sys.println 生成:file:/C:/*censored*/eclipse-workspace/Pacman/bin /pacman.class
    • 我想我看到了这个问题。 Images 文件夹不在我所有其他类所在的 bin(或 src)文件夹中。两个文件夹位于同一层。所以我理解它的方式是现在它正在寻找与 pacman.class 相同的文件夹内的图像文件夹,当我希望它找到的文件夹是一层?
    • 把图片和java源文件放在同一个地方(所以,src/Images/asd.png,而不是/Images/asd.png); eclipse 会自动将它们复制到那里的 bin 中。不可能使用 getResource 并“向上一层”,但让 eclipse 复制它们会起作用。
    猜你喜欢
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 2012-09-15
    相关资源
    最近更新 更多