将图片添加到jar文件

6

我想给我的JFrame设置图标。我按照以下步骤进行:

Image icon = Toolkit.getDefaultToolkit().getImage("src/images/icon.jpg");
this.setIconImage(icon);

当我从NetBeans运行这段代码时,它可以正常工作。但是当我尝试从jar文件运行这段代码时,在我的JFrame中不会显示图像。我已经尝试将图像作为资源加载:

this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/src/images/icon.jpg")));

但是当我运行这段代码时,它出现了NullPointerException错误。
 Uncaught error fetching image:
java.lang.NullPointerException
        at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:99)
        at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:113)
        at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:240)
        at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
        at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)

我该如何完成这项工作?

编辑: 感谢大家, 问题已通过将图像指定为

Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("images/icon.JPG"))

看起来有些奇怪,如果它能像以下这样就更好了

this.setIconImage(new ImageIcon(pathToIcon).getImage());

你的JAR文件结构是什么,即图像在JAR文件中的确切位置是哪里? - Sanjay T. Sharma
8个回答

4

假设您的JAR文件有一个名为images的顶级目录,您可以使用以下任一方法:

  1. getClass().getResource("/images/icon.jpg") 或者
  2. getClass().getClassLoader().getResource("images/icon.jpg")

3

查看URLImageSource的源代码,似乎getConnection抛出NPE的原因是它的url为null。这让我怀疑

getClass().getResource("/src/images/icon.jpg")

返回了null。如果无法找到具有该路径名的资源,则会这样做。

我猜问题在于您的路径不正确。

为了证明/反驳这一点,您应该在JAR文件上运行jar tvf,并查找与"icon.jpg"匹配的行。相应的路径名是否与您正在使用的路径名相同?如果不是,请使用getResource调用中匹配行中的路径名,它应该可以工作。或者,如果文件根本没有显示,请查看NetBeans构建配置,告诉它将什么放入JAR文件中。(我不是NetBeans用户,所以我不知道您需要查看哪里...)


如果这完全没有帮助您,另一个可能性是getClass().getResource(...)正在使用不知道包含图像的JAR文件的类加载器。(对我来说,这似乎非常不可信...)


1
jar tvf 显示 icon.jpg 位于 images/icon.jpg,但是 getClass().getResource("/images/icon.jpg") 和 getClass().getResource("images/icon.jpg") 都不起作用。但是 getClass().getClassLoader().getResource("images/icon.jpg") 可以正常工作。 - maks
我有同样的问题,但我是在主方法内部执行的,所以 "getClass()" 不起作用。我应该放什么?我尝试创建一个主类的新实例,但当我尝试时,它给了我一个异常。 - Ephraim
1
尝试使用 YourMainClass.class.getClassLoader().getResource(resourePath) - Stephen C

2

getResource()方法从类路径加载资源,而不是操作系统路径。在编译后,你的类路径将不包括/src文件夹,而只包括其内容。因此,最好使用/images/icon.jpg

此外,你可能会发现这个讨论有些有用。


0
JFrame f = new JFrame("Edit Configure File");
//Image image = ImageIO.read(getClass().getResource("images/ctx.Icon"));
f.setIconImage(new ImageIcon("images/ctx.PNG").getImage());//this works for me finally
//f.setIconImage(image);
//f.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/ctx.PNG")));

0

假设您可以导入javax.imageio.ImageIO,那么这应该可以解决问题:

Image icon = ImageIO.read(this.getClass().getResource("/src/images/icon.jpg"));
this.setIconImage(icon);

它在指定的位置找不到这样的文件,但是它确实存在。 - maks
嗯..你可以试着将图片文件移动到 src 目录以外,但与其在同一级别的文件夹中。例如:"/resources/images/icon.jpg"。 - jberg

0
.."/src/images/icon.jpg"..  

地址中的“/src”前缀似乎有些可疑。许多应用程序都会提供单独的“src”和“build”目录,但通常最终生成的Jar文件中不使用“src”前缀。我建议尝试...

.."/images/icon.jpg".. 

同时三次检查图像是否位于代码期望找到它的Jar位置。


0

为了使其正常工作,您应该从相对于某个固定类的目录访问图像。例如,如果图像文件保存在与Toolkit.class相同级别的目录“images”中,则

this.setIconImage(Toolkit.getDefaultToolkit().getImage(Toolkit.class.getResource("images/icon.jpg"))); 应该可以工作。


0
你可以在主源代码中简单地创建一个包,并将你的图像放入这个包中。然后,在你的主类中调用这些图像,如下所示: ImageIcon a = new ImageIcon(MainClass.class.getResource("/Package/Image.jpg"));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接