当我们将程序写好,并进行打包成Jar文件时,通常都带有各种资源,这些资源可以是图像或者声音文件,也可以是别的如文本文件或二进制文件等,这些资源都和代码密切相关。例如在一个JPanel类上显示一些可能变化的信息,通常都是讲这些信息先写在文本文件上,而不是硬写入JPanel中,因为信息可能会变。而这文本文件就是这个程序的资源。
获得这些资源的位置有两种方式:
- 针对图像和影音的,使用包含这代码的类调用getResource(......)方法,然后利用getImage或者getAudioClip方法进行读取。例如TextPanel.class.getResource(......)或者this.getClass().getResource(.......)
- 针对其他文件类型的,使用包含该文件代码的类调用getResourceAsStream(......)方法,使用过程类似上一条示例。
不管是getResource(......)方法还是getResourceAsStream(......)方法,这里的“.......”是指资源位置的地方,这个是整个使用过程中最容易出错的地方。
那么这两种方法的资源路径该如何写呢?
修改:以下所有内容为资源没有放入Jar包中时的情况,如果将资源同代码一起打包进Jar包中,请看 《关于在打包Jar文件时遇到的资源路径问题(二)》
正如我在 《关于在打包Jar文件时遇到的资源路径问题(二)》中最后总结的,这些方法都必须根据实际情况进行选择:
如果是资源需要经常修改,那么就可以使用本文所介绍的方法,将可执行Jar包和资源分离,这样易于改动,而不需要将Jar包解压修改后在复原;
如果是某些资源不需要修改,那么就可以使用《关于在打包Jar文件时遇到的资源路径问题(二)》中的方式,将资源和字节码文件一起打包进Jar包中,这样易于将应用程序移动,
当然,如果结合这两者方式,对固定资源和常修改资源进行分类处理,能获得更好的效果。
==============================正文开始====================================================
(1). 当在项目中有使用自定义包的情况下,一定要使用绝对资源位置(位置最前面要加“/”):
1.1 当在Eclipse调试过程中,即还未打包成Jar文件之前的运行时:
需要认识到getResource方法和getResourceAsStream的默认根目录都是当前Project项目的二进制bin文件夹中,也就是说我往“.......”写入的路径都是从XXX(Project)/bin文件夹开始的。
例如:
我的一个程序ImageViewer在包fjdingsd.com.cnblogs中,而这个包在E:\Java_Program\GUIproject\bin文件夹中,所以我写的路径应该为:/XXX(资源名)
有如下代码:
URL picUrl = this.getClass().getResource("/palette.gif");
Image image = new ImageIcon(picUrl).getImage();
这个资源文件的放置应该如下图所示:
(请忽略那个com文件夹)
这里将palette.gif图片放到了GUIproject项目下的bin文件夹中,正如代码所示,/palette.gif地址就是以项目下的bin文件夹开始,当然我们也可以将该资源放到这个文件夹下的子目录中,例如创建一个pictures文件夹,将palette.gif放入,那么代码就该修改为:
chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("/pictures/palette.gif");
对应的文件放置:
这里请注意:
填写资源位置时应该使用“/”作为分隔符,而不要理睬系统实际使用的哪种目录分隔符,在Windows系统中,资源加载器会自动将 “/” 装换成“\” 。
另外在在Eclipse调试运行过程中,必须以“/”作为最开头,这也称作绝对资源位置,如果不以“/”作为开头,那么程序运行就会出错:
其实也很好理解,就是默认的地址XXX(Project)/bin文件夹的结尾没有“/”,所以我们要加入“/”,这样最终路径才能是XXX(Project)/bin文件夹 /pictures/palette.gif。
==========================================================
1.2 当程序打包成可执行Jar包时:
这个时候资源就不是放XXX(Project)/bin文件夹下了,而是根据Jar包的位置来作为根目录:
例如代码中写着:
URL picUrl = this.getClass().getResource("/palette.gif");
Image image = new ImageIcon(picUrl).getImage();
那么palette.gif就该与Jar包同一个目录下,而Jar包可以在任何目录中:
这样点开程序就能运行了,如果资源路径前没有加“/”,则无论怎么点Jar包都不会有反应。
同理,如果代码是这么写着:
chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("/pictures/palette.gif");
那么就可以在Jar包所在目录下建立子目录来放置资源文件,资源文件就该放入相应子目录中:
最后getResourceAsStream的资源路径也是一样的。
==============================第一种情况介绍结束分割线=================================
(2). 当该项目没有建立包时,也就是使用默认包(缺省值)时,不一定使用绝对资源位置:
(图:建立项目默认包情况)
2.1 当在Eclipse调试过程中,即还未打包成Jar文件之前的运行时:
此时无论是getResource方法还是getResourceAsStream方法,资源位置可以是绝对资源位置,也可以是相对资源位置(最前面不加“/”):
chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("palette.gif");
亦或:
chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("/palette.gif");
都是可以的。
注意:但是palette.gif依然必须放在从XXX(Project)/bin文件夹中,也就是类文件class所在的目录中。
2.2 当程序打包成可执行Jar包时:
资源位置代码的编写同2.1中描述的一样,无论是使用绝对资源位置还是相对资源位置,都是可以的。
而当打包成可执行Jar包时,资源在文件中的放置如1.2中的方法完全相同。
====================================================================================