Swing/ClassLoader のバックアップの現在との差分(No.1)
TITLE:ClassLoaderでリソースのURLを取得
ClassLoaderでリソースのURLを取得
編集者:Terai Atsuhiro~
作成日:2006-05-22
更新日:2021-03-30 (火) 11:07:32
概要
クラスパスからのエントリ(相対パス風)を使って、ClassLoader
からURL
を取得します。
Screenshot
Advertisement
概要
リソースをクラスパス相対パスで指定し、ClassLoaderを使ってURLを取得します。サンプルコード
#spanend
#spanadd
URL url = getClass().getClassLoader().getResource("example/test.png");
#spanend
#spanadd
// URL url = Thread.currentThread().getContextClassLoader().getResource("example/test.png");
#spanend
#spanadd
// URL url = getClass().getResource("test.png");
#spanend
#spanadd
JLabel icon = new JLabel(new ImageIcon(url));
#spanend
#spanadd
JLabel path = new JLabel(url.toString());
#spanend
#spanadd
View in GitHub: Java, Kotlin#screenshot
解説
ClassLoader
を使用して、位置に依存しない方法でリソース(URL
)を取得します。
サンプルコード
URL url = getClass().getClassLoader().getResource("example/test.png"); //URL url = getClass().getResource("test.png"); JLabel icon = new JLabel(new ImageIcon(url)); JLabel path = new JLabel(url.toString());
- 例えば
new ImageIcon(String filename)
のようにファイルパスを文字列で指定した場合、このファイルパスが位置(カレントディレクトリ)に依存しているため、実行時に別のディレクトリから起動したり、jar
ファイルにまとめたりするとファイルが参照できなくなる
- &jnlp;
- &jar;
- &zip;
以下、
.\target\classes\example\test.png
にある画像ファイルのURL
をクラスパスからのエントリ(相対パス風)を使って取得する場合を考えます。
解説
ClassLoaderを使用した場合、クラスパスからの相対パスでリソースを指定することができます。 上記のサンプルに添付しているバッチファイルでは、クラスパスは次のように設定しています。java -classpath ".\target\classes" example.MainPanel
例えば、.\target\classes\example\test.pngにある画像ファイルのURLを相対パスで取得する場合を考えます。
ClassLoader#getResource
メソッドを使用する場合は、以下のようにクラスパスからのエントリを使用します。このエントリは、相対パス風で頭に/
は付けず、/
区切りで記述します。
上記のサンプルを添付のバッチファイルから実行したときのクラスパスは、以下のように設定されています。
java -classpath ".\target\classes" example.MainPanel
#spanend
#spanadd
getClass().getClassLoader().getResource("example/test.png");
#spanend
#spanadd
// ただし、getClass().getClassLoader().getResource("./example/test.png");
#spanend
#spanadd
// だとjar内にパッケージした場合で失敗する
#spanend
#spanadd
ClassLoader#getResourceメソッドを使用する場合は、以下のようにクラスパスからの相対パス(/区切り)を引数にします。
getClass().getClassLoader().getResource("example/test.png"); //getClass().getClassLoader().getResource("./example/test.png"); //だとjar内にパッケージした時うまくいかない。
- -
ClassLoader
からでは無く、Class#getResource
メソッドを使う方法もあります。この場合、エントリ名がメソッド内で以下のように変換されます。
getClass().getResource("test.png");
- 相対パス風(頭に
/
が付かない)の場合-
.
が/
に変換された、modified_package_name
が名前の前に補完される - 例えば、
com.example.Test
クラスなら、com/example/
- このサンプルでは
example.MainPanel
クラスなので、example/
が補完されて、example/test.png
になる
-
#spanend
#spanadd
getClass().getResource("test.png"); //or MainPanel.class.getResource("test.png");
#spanend
#spanadd
// getClass().getClassLoader().getResource("example/test.png");と同じ
#spanend
#spanadd
コメント
- 絶対パス風(頭に
/
が付く)の場合-
modified_package_name
は補完せず、頭の/
は削除される
-
#spanend
#spanadd
getClass().getResource("/test.png");
#spanend
#spanadd
// getClass().getClassLoader().getResource("test.png");と同じ
#spanend
#spanadd
// 上記の相対パスと同じリソースを取得する場合は、
#spanend
#spanadd
// getClass().getResource("/example/test.png");としなくてはならない
#spanend
#spanadd
- - クラスパス上に同名のリソースが複数存在する場合は、最初に見つかったものが使用されます。
-
src.zip
をダウンロードして適当な場所に展開する -
c:\temp\example\test.png
という画像ファイルを別途用意する - 展開したフォルダにある
run.bat
のクラスパスを以下のように変更(c:\temp
を最初に追加)
#spanend
#spanadd
set MAIN_CLASS=example.MainPanel
#spanend
#spanadd
rem set CLASSPATH=.\target\classes
#spanend
#spanadd
set CLASSPATH=c:\temp;.\target\classes
#spanend
#spanadd
-
ant
などでコンパイルして、修正したrun.bat
で実行
src.zip
に元々入っていた適当な場所/test.png
ではなく、file:/C:/temp/example/test.png
というURL
がgetResource
で取得できます。