odtwarzanie wav poza środowiskiem netbeans

napisałem w netbeans clase :
public class Formatka extends javax.swing.JFrame {

/** Creates new form Formatka */
public Formatka() {
initComponents();
}
// tutaj kod stworzony przez NB.....

// i znowu mój kod
Odtwarzaj graj = new Odtwarzaj();
private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {
this.jLabel1.setText("Uhahaha, uhahaha");
this.jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/foto/spacja.jpg")));
this.jLabel2.setText("");

graj.play("src/dzwieki/smiech01.wav");

}
//kod nb.
}

Dźwięk jest odtważany tylko w srodowisku NB.
Jak uruchamiam z jar-a to wyskakuje błąd:
java.io.FileNotFoundException: \dzwieki\smiech01.wav (System nie może odnaleźć określonej ścieżki)
at java.io.FileInputStream.open(Native Method)
Używam NB 6.5 pl, w wersji 6.1 miałem to samo.
Plik wav znajduje się w tym samym folderze co clasy.
Bez tego src/ w NB nie działa tak jak i z jara.
Jaka powinna byc prawidłowa ścieżka?

Opcje przeglądania komentarzy

Wybierz preferowany sposób wyświetlania komentarzy i klinij na "Zapisz ustawienia", aby aktywować zmiany.
Witold Szczerba's picture

spakuj projekt i udostępnij

...to będzie można pomóc. W międzyczasie poczytaj o tym jak działa metoda getResource z java.lang.Class i o classpath.
Jedne co na pewno mogę stwierdzić, to że ten "/src/dzwieki..." na pewno jest źle zrobione. Jeśli działa to chyba tylko przez przypadek.

projekt w zip

http://pamysz.republika.pl/Dzwieki.zip
pewnie przypadek, ale dlaczego?
Też mi się ta ścieżka nie podoba, jakaś taka z sufitu. I z tąd moje dociekania.
Tworzę ręcznie folder foto, prawym klawiszem w oknie projektu, albo tworzę folder z new file, to go nie widzi.
Dopiero jak podam mu we właściwościach elementu którego dotyczy "image width project" package ...nazwę foldera(/-u), ew. Import to project... - to wykonuje poprawnie, ale tylko grafikę.
I skąd nagle to src/.. przy dzwięku.
W NB 6.1 był troche inny interfejs, i teraz nie pamiętam jak doszedłem do tego src/..., coś mieszałem we właściwościach folderu, bo pierwotnie plik był w osobnym folderze wav tak jak i grafika w foto i działał przez src/dzwieki/wav/..., ale teraz po kliknieciu prawym mam inne menu i już nie pamiętam.
A NB 6.5 instalowałem na NB 6.1 bez kasowania ustawień NB.
A problem podałem też na google, bo nie mogłem się zarejestrować na jdn. Dopiero drugi link przysłany przez jdn zadziałał. A czytając twoje i ant-a odpowiedzi na tym forum miałem nadzieję na waszą reakcję.

Witold Szczerba's picture

zasada jest prosta

Jeśli plik do którego chcesz się odnieść jest dołączany do aplikacji wewnątrz plików JAR, lub inaczej: jeśli jest osiągalny jako zasób na tzw. ścieżce klas (classpath) to odwołuj się do takiego pliku przez klasa.getResource(String path).

Przeczytaj w JavaDoc jak działa metoda getResource w klasie java.lang.Class. W skrócie, jeśli plik np. sound.wav umieścisz w tym samym miejscu, gdzie jest klasa MojaKlasa, wtedy możesz zrobić:
MojaKlasa.class.getResource("sound.wav")
albo wewnątrz metody w tej klasie:
getClass().getResource("sound.wav");
i dostaniesz wskaźnik na ten właśnie plik. Jeśli zrobisz getResource("/sound.wav") wtedy taki plik będzie szukany w najniższym dostępnym katalogu, przykładowo:
plik JAR, po rozpakowaniu wygląda tak:
META-INF
sound.wav
pl/mojprogram/MojaKlasa.class

Często takie pliki ładuje się do katalogu resources w głównym katalogu projektu, przykładowo:
pl/mojprogram/resources/sound.wav
pl/mojprogram/MojaKlasa.class

Wtedy do pliku możesz odwołać się przez:
MojaClasa.class.getResource("resources/sound.wav");
lub wewnątrz metody w klasie:
getClass().getResource("resources/sound.wav");

Wszystko co pisałem o getResource działa także z getResourceAsStream, ale ta metoda zwraca strumień i jeśli będziesz z niego korzystał - to nie zapomnij o jego poprawnym zamknięciu, gdy zostanie już odczytany, a to wiąże się z try/finally. Z tego względu, jak masz do wyboru, to wybieraj getResource, które zwraca obiekt typu URL. Wtedy to nie ty będziesz z tego tworzył InputStream, a więc nie ty się będziesz martwił o jego poprawne zamknięcie, gdy będzie już niepotrzebny (przynajmniej tak jest w teorii).

ant's picture

NetBeans odpala projekt

NetBeans odpala projekt ustawiając CWD na katalog tegoż projektu, dlatego z IDE wszystko jest widoczne. A rozwiązanie jest oczywiście takie jak piszesz: Class.getResourceAsStream zamiast FileInputStreama. Trzeba tylko zadbać - IDE powinno to zrobić - o to, żeby przekopiować podczas budowania projektu wszystkie zasoby nie będące klasami z src do classes.