4864


Java アプリケーションで BGM を流したいと思い､次のクラスを作りました｡

[code]

    import java.applet.Applet;
    
    public class Sound {
        java.applet.AudioClip ac;
        public Sound() {
            // TODO 自動生成されたコンストラクター・スタブ
            ac = Applet.newAudioClip(getClass().getClassLoader().getResource("res/BGMn.wav"));
        }
    
        public void loop(){
            ac.loop();
        }
        public void stop(){
            ac.stop();
        }
        public void play(){
            ac.play();
        }
    }
    
[/code]

しかし､ main スレッドで呼び出したところ､次のようなエラーが出てしまいました｡

[code]

    Exception in thread "main" java.lang.NullPointerException
    at sun.applet.AppletAudioClip.<init>(Unknown Source)
    at java.applet.Applet.newAudioClip(Unknown Source)
    at boss.Sound.<init>(Sound.java:9)
    at boss.Main.init(Main.java:68)
    at boss.Main.main(Main.java:45)
    
[/code]

`getResource()` のパスが間違っていると思われるのですが､いろいろ試してみてもできませんでした｡ パスには何を指定すれば良いのでしょうか｡

**ディレクトリ構造:**

[code]

    Project
      src
        package
          Main.java
          Sound.java
      res
        BGMn.wav
    
[/code]

**.classpath:**

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <classpath>
      <classpathentry kind="src" path="src"/>
      <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
      <classpathentry kind="output" path="bin"/>
    </classpath>
    
[/code]


CC BY-SA 3.0
2015-01-19T15:47:05.690
4858
2015-01-19T21:02:39.377
2015-01-19T21:02:39.377
4978
7232
question
java classloader
JavaアプリケーションでBGMを流したい｡ (getResource() が null を返す)


大雑把に説明しますと`.classpath`ファイルの通り、`kind="src"`で指定されている`src`ディレクトリ配下にあるファイルが、コンパイル後`kind="output"`で指定されている`bin`ディレクトリに格納されます。

**コンパイル後のディレクトリ構成(現状):**

[code]

    Project
      bin
        package
          Main.class
          Sound.class
      res
        BGMn.wav
    
[/code]

※`src`ディレクトリは省略

つまりこのままだとコンパイル後に`bin`ディレクトリに`BGMn.wav`が含まれませんし、実行時に`Sound`クラスからwavファイルを参照することもできません。

`res`ディレクトリを`src/package`配下に移動してください。  
そうすれば`Sound`クラスから`"res/BGMn.wav"`でwavファイルを参照できます。

**ディレクトリ構成(修正後):**

[code]

    Project
      src
        package
          Main.java
          Sound.java
          res
            BGMn.wav
      bin
        package
          Main.class
          Sound.class
          res
            BGMn.wav
    
[/code]


CC BY-SA 3.0
2015-01-19T18:08:38.633
4863
2015-01-19T18:27:48.510
2015-01-19T18:27:48.510
3068
3068
4858
answer


リソースファイルがみつからないのは実行時にres以下のファイルがパスの通ったディレクトリへコピーされていないからだと思われます。

あなたのプロジェクトではbinディレクトリにビルド結果が出力されそこにパスが通った状態で実行されるようになっていると思います。（特に指定せずにプロジェクトを作成するとそうなります。）しかし、src以外のファイルは標準設定ではbinへコピーされないのでgetResourceが失敗する結果になります。

Project->Properties->Java Build
PathのSourceタグでresディレクトリーを追加することでresディレクトリにおいたリソースファイルがbinへコピーされるようになります。どこにコピーされるかはProject->Clean...を実行してビルドしなおした状態でbinディレクトリの下を観察してみてください。

またいちいちresをソースディレクトリーとして設定しなくても、例えばMain.javaと同じ場所(src/package/.)へリソースファイルを置くと`Main.class.getResource("BGMn.wav")`でアクセスできるので簡単です。


CC BY-SA 3.0
2015-01-19T18:09:45.920
4864
2015-01-19T18:09:45.920
4417
4858
answer