當我們將程序寫好,並進行打包成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(資源名)
有如下代碼:
1 URL picUrl = this.getClass().getResource("/palette.gif"); 2 Image image = new ImageIcon(picUrl).getImage();
這個資源文件的放置應該如下圖所示:
(請忽略那個com文件夾)
這里將palette.gif圖片放到了GUIproject項目下的bin文件夾中,正如代碼所示,/palette.gif地址就是以項目下的bin文件夾開始,當然我們也可以將該資源放到這個文件夾下的子目錄中,例如創建一個pictures文件夾,將palette.gif放入,那么代碼就該修改為:
1 chooser.setAccessory(new PreImageViewer(chooser)); 2 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中的方法完全相同。
====================================================================================