在 .jar 文件中找不到图像

Images cannot be found in .jar file

这个问题经过编辑以包含所有问题。下面会补上新图links

我的程序 运行 在 NetBeans 中运行良好,当 运行 从 NetBeans 编译的 jar 文件中加载时无法加载程序。我在 Java 1.6_45 上编译,这只是为了兼容性,因为这是一个面向学校的程序,适用于几乎从未收到任何升级或更新的旧机器。

无论如何,因为当我尝试将它作为 .jar 文件时该程序从未加载,我很担心并查找了制作 jar 的手动方法 运行。我尝试了命令提示符命令 java-罐子PhysicsEquations.jar ,我将其直接复制到我的用户文件夹中,这样我就不必担心 classpaths.

这是我收到的错误消息(下面,第一个 link),一个 IllegalArgumentException。我不确定该怎么做,我已经研究了几天,现在正在尝试不同的事情。如果可以更好地解释,我愿意重试任何事情。

这是整个 EquationImage class(只有几行,请多多包涵)。在其他代码中,我所做的只是调用构造函数,例如 EquationImage fma = new EquationImage("fma.jpg");,然后使用 setBounds(x,y,width,height); 将其添加到一个面板,该面板已添加到我的 CardLayout 中,其中包含所有方程式。

package physicsequations;
...
public class EquationImage extends JPanel {
    public EquationImage() {
    }

    public EquationImage(String filename) {
        try {
            System.out.println(filename);
            imageBuffer = ImageIO.read(getClass().getResourceAsStream("images/" + filename));
        }
        catch(IOException e) {
            JOptionPane.showMessageDialog(null, "EquationImage could not find/load the file \n" + filename, "Error Message", JOptionPane.PLAIN_MESSAGE);
        }
    }

    @Override
    protected void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        graphics.drawImage(imageBuffer, 0, 0, null);
    }

    private BufferedImage imageBuffer = null;
}

在代码和错误消息中值得注意的是,构造函数确实收到了一个文件名。在 NetBeans 中,编译器能够正确找到所有图像。但是,在我使用 'Clean and Build' 的 jar 中,我是否实际看到有错误的 JOptionPane 可能会有所不同。

我被要求提供我的代码的文件路径。

在项目中,我有文件夹 PhysicsEquations。 PhysicsEquations 有文件夹 dist、build、nbproject 和 src。 PhysicsEquations 也有文件构建和 manifest.mf。

src 有文件夹 physicsequations,EquationImage 所在的包。

physicsequations 有五个文件和一个文件夹 'images'。这些文件是 Main、EquationPanel、EquationImage、BadInputException 和 Variable。

images 有我所有的图片,包括 Physics.jpg,这是我在 Main:

中使用的图标
String imagePath = "physics.jpg";
InputStream imgStream = Main.class.getResourceAsStream("images/" + imagePath);
BufferedImage myImg = null;
try {
    myImg = ImageIO.read(imgStream);
}
catch(IOException e) {
    JOptionPane.showMessageDialog(null, "The program has failed to load file physics.jpg from the source package.", "Error Message", JOptionPane.ERROR_MESSAGE);
}
setIconImage(myImg);

在 jar 本身中,我打开 jar 并有 2 个文件夹:META-INF 和 physicsequations。在 physicsequations 文件夹中,有 101 class 个文件,以及一个名为 images 的文件夹。该文件夹包含我在项目中使用的所有 17 张图片。下面是 jar 中 META-INF 中 manifest.mf 文档的文本。 (有人可以向我解释为什么它说 1.8 吗?我的项目属性中有 1.6...

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Created-By: 1.8.0_31-b13 (Oracle Corporation)
Class-Path: 
X-COMMENT: Main-Class will be added automatically by build
Main-Class: physicsequations.Main

http://i.stack.imgur.com/IqgzE.jpg
http://i.stack.imgur.com/rHaDa.jpg
http://i.stack.imgur.com/j5Npw.jpg
http://i.stack.imgur.com/Yt2O3.jpg

我希望所有 link 都提交,因为它说我有 10 个代表的限制。

通过查看您的 first linked image which states you are trying to load the resource "fma.jpg" and IllegalArgumentException: input == null and your last image,它清楚地表明您的项目中包含的文件名为 fma.JPG 我认为很清楚发生了什么(PS:None 你的图像,据我所知,显示了一个名为 "physics.jpg""Physics.jpg""physics.JPG" 的文件,但我认为这里的问题是一样的):

任何使用 Class.getResource(...)Class.getResourceAsStream(...) 的资源查找 区分大小写 。它可能在您从文件系统 运行ning 时起作用,因为正常的 Windows 文件系统不区分大小写,并且无论如何都会解析文件。但是,在 JAR 内部时,匹配区分大小写,查找将不起作用。

你有两个选择:

  • 要么将您的文件重命名为更常见的小写扩展名标准(即,将 "fma.JPG" 重命名为 "fma.jpg")。
  • 或者更改代码以实际查找 JAR 中的资源(即将代码从 "fma.jpg" 更改为 "fma.JPG")。

要验证一切是否正确,您可以运行命令:

jar tf yourjar.jar 

t 选项列出文件内容的 table)。它将产生类似于 the following example:

的输出
META-INF/
META-INF/MANIFEST.MF
TicTacToe.class
TicTacToe.class
TicTacToe.java
audio/
audio/beep.au
audio/ding.au
audio/return.au
audio/yahoo1.au
audio/yahoo2.au
example1.html
images/
images/cross.gif
images/not.gif 

验证列表中的名称和代码是否完全相同,并且拼写匹配。


PPS:关于1.8参考:

Created-By: 1.8.0_31-b13 (Oracle Corporation)

这只是创建 JAR 的 jar 命令的版本(通常与包含它的 JDK 的版本相同)。这可能不同于用于构建项目的 (javac) 版本,或构建所需的 JDK 库版本。