URL kürzen

kruemelkeksfan

Aktives Mitglied
Hi Leute,
Ich schreibe gerade ein kleines Programm das auch Sound wiedergeben soll. Dafür brauche ich eine URL. Ich weiß aber nicht, in welchen Ordner der User meine Software legt, gibt es für solche Fälle eine Möglichkeit die URL von der class-Datei aus zu beschreiben, so wie beim ImageIcon-Konstructor, der einen String in der Form "ordner/datei.png" verlangt?

LG Max
 

Flown

Administrator
Mitarbeiter
Also das geht ziemlich einfach, wenn du von deiner Klasse ausgehst wo die main-Methode aufgerufen wird, kannst du das mit den Systemproperties auslesen.

Java:
System.getProperty("user.dir");
 

Flown

Administrator
Mitarbeiter
Entschuldig ein Blick in die API oder Google hätte es dir auch gesagt.

Für dich [JAPI]System#getProperties()[/JAPI]

user.dir User's current working directory

Die Methode [JAPI]System#getProperty(java.lang.String)[/JAPI] gibt dir einen String mit der aktuellen URL zurück.
 

kruemelkeksfan

Aktives Mitglied
funktioniert nicht :noe:

Code:
System.out.println (System.getProperty ("user.dir") + "/" + "shot.mp3");

		try
			{
			shot = Applet.newAudioClip (new URL ((System.getProperty ("user.dir") + "/" + "shot.mp3")));
			}
		catch (MalformedURLException murle)
			{
			System.out.println ("Fatal Error. Make sure all game files are in the right place. If not reinstall the game.");
			}

Ausgabe:

Maximilians-MacBook-Pro:classes maxmacbook$ java Starter
/Users/maxmacbook/Desktop/DeadStorm/classes/shot.mp3
Fatal Error. Make sure all game files are in the right place. If not reinstall the game.
Maximilians-MacBook-Pro:classes maxmacbook$

Die Datei shot.mp3 liegt definitiv im Ordner classes.
Ich komm einfach nicht weiter -.-
 

kruemelkeksfan

Aktives Mitglied
Maximilians-MacBook-Pro:classes maxmacbook$ java Starter
/Users/maxmacbook/Desktop/DeadStorm/classes/shot.mp3
Fatal Error. Make sure all game files are in the right place. If not reinstall the game.
java.net.MalformedURLException: no protocol: /Users/maxmacbook/Desktop/DeadStorm/classes/shot.mp3
at java.net.URL.<init>(URL.java:567)
at java.net.URL.<init>(URL.java:464)
at java.net.URL.<init>(URL.java:413)
at GameLoop.<init>(GameLoop.java:52)
at GameWindow.<init>(GameWindow.java:34)
at Starter.main(Starter.java:27)
Exception in thread "Thread-3" java.lang.NullPointerException
at GameLoop.run(GameLoop.java:260)
at java.lang.Thread.run(Thread.java:695)
Maximilians-MacBook-Pro:classes maxmacbook$
 

hauptDev

Bekanntes Mitglied
Die Pfade die der Klasse java.net.URL übergeben werden müssen immer absolut angegeben (und mit Protokoll) werden.

Du solltest über die File-Klasse den relativen Pfad angeben und [STRIKE]dann über die Methode toURL() dir den absoluten Pfad als URL zurückgeben lassen.[/STRIKE] siehe unten.

Java:
entfernt, da deprecated

Edit:
Oh, ich sehe gerade, die Methode toURL() ist deprecated, also besser nicht nutzen.

So ist's besser:
Java:
File f = new File(System.getProperty("user.dir") + File.seperator + "shot.mp3");
shot = Applet.newAudioClip (f.toUI().toURL());
Unschöner, aber richtiger. Jetzt muss ich erstmal gucken, warum das so ist :)


Edit 2:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6179468

Ist wohl schon seit 1.6 deprecated.
Grund:
"Usage note: This method does not automatically escape characters that are illegal in URLs.
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
@hauptDev du hast einen kleinen Schreibfehler:
Java:
f.toURI().toURL()

So sollte es funktionieren.
 

kruemelkeksfan

Aktives Mitglied
OK, soweit so gut. Erst mal bekomm ich keine Fehlermeldungen mehr. Beim Anschlagen der Leertaste bleibt mein Lautsprecher trotzdem noch stumm wie ein Fisch :(

Und wenn ich schon mal dabei bin dumme Fragen zu stellen: Ich hab grad noch mal die API gewälzt, wie Flown schon eher vorgeschlagen hatte und komm jetzt irgendwie nicht dahinter, was der Unterschied zwischen URL, URI und File ist. Nach meinem Verständnis geben alle einen Dateipfad an, wofür drei Klassen, die dasselbe machen? Ist URL Betriebssystemgebunden und File unabhängig? Oder wo liegt der Sinn?
Und wo lag der Fehler bei der Lösung, wo ich die URL direkt erstellen wollte? Warum klappt das nicht?

Mein Code sieht jetzt so aus:

Code:
shotURL = new File ((System.getProperty ("user.dir") + File.separator + "shot.mp3"));

		try
			{
			shot = Applet.newAudioClip (((shotURL.toURI ()).toURL ()));
			}
		catch (MalformedURLException murle)
			{
			murle.printStackTrace();
			}

Ist das i.O. oder kann ich die Exception jetzt weglassen? shotURL wird mit den anderen Instanzvariablen zusammen ganz oben deklariert. Der Ausschnitt stammt selbstverständlich aus dem Konstruktor meiner Spielschleife.
 

Flown

Administrator
Mitarbeiter
So jetzt einmal wegen deinem Audiofile. Die Java Sound API unterstützt kein "mp3" Format. Aber ich habe den Link gefunden, der dir zeigt das du mit JavaFX mp3 abspielen kannst.

Es gibt zu einem keine dummen Fragen nur dumme Antworten. Zum anderen ist File eine Javaabstrahierung zum handlen von physischen oder logischen Files auf einen Betriebssystem.
Die URI identifiziert eindeutig die Ressource und wie&wo sie zu finden ist. URL ist eine Untergruppe der URI. Wenn du genaueres wissen willst, dann sie dir den Wikipediabeitrag an.
 

kruemelkeksfan

Aktives Mitglied
Ich würde den Code gern lassen, wie er ist und habe zu diesem Zwecke meine mp3 in wav umgewandelt und, Überraschung!, es geht trotzdem nicht. Zum haareausraufen ist das, ich dachte, das Programm sei so gut wie fertig :(
 

Flown

Administrator
Mitarbeiter
Also entschuldige gerade für den Java 8 Code, bin gerade am herumexperimentieren, aber du kannst es auch über den ClassPath machen. Hab jetzt etwas getestet und bei mir funktioniert dieser Code:

Java:
package audio;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.GridLayout;
import java.net.URL;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class AudioClipTest {
	
	private AudioClip clip;
	private final String WAV_PATH = "resource/test.wav";
	
	public static void main(String[] args) {
		new AudioClipTest();
	}
	
	public AudioClipTest() {
		JFrame frame = new JFrame("AudioClipTest");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationByPlatform(true);
		frame.setLayout(new GridLayout(3, 1));
		
		JLabel label = new JLabel();
		
		URL u = this.getClass().getResource(WAV_PATH);
		label.setText(u.toString());
		clip = Applet.newAudioClip(u);
		
		JButton playButton = new JButton("Play me");
		playButton.addActionListener(e -> clip.play());
		JButton stopButton = new JButton("Stop me");
		stopButton.addActionListener(e -> clip.stop());
		
		frame.add(playButton);
		frame.add(stopButton);
		frame.add(label);
		
		frame.pack();
		frame.setResizable(false);
		frame.setVisible(true);
	}

}
 

kruemelkeksfan

Aktives Mitglied
Auf diese art rummst und kracht es in meinem spiel, dass es eine wahre freude ist :applaus: , funktioniert hervorragend, vielen, vielen Dank! :toll: Wenn ich das richtig sehe, lag des Rätsels lösung jetzt in der getClass.getResource - Methode, oder? Ich wälz gleich noch mal die ApI, um mein Programm dann auch selbst zu verstehen :D
Noch eine letzte Frage: warum haben AudioClips so einen anderen Konstruktor, ohne Leerzeichen und mit vorangestelltem Packagenamen?
 

Flown

Administrator
Mitarbeiter
Also zu deiner ersten Frage:

Noch eine letzte Frage: warum haben AudioClips so einen anderen Konstruktor, ohne Leerzeichen und mit vorangestelltem Packagenamen?

Ich nehme an du möchtest wissen, warum das AudioClip von dem Applet statisch erzeugt wird. Das liegt daran das AudioClip nur ein Interface ist und das Applet kann ein AudioClip mit einer konkreten Implementierung liefern.

Und warum muss ich die exception nicht mehr abfangen? Vorher ließ es sich ohne catch nicht kompilieren...

Weil du vorher eine URI gehabt hast und die Methode
Code:
.toURL()
wirft eine Exception (eigentlich sogar 2, aber die IllegalArgumentException ist eine RuntimeException und muss nicht abgefangen werden).
 

Ähnliche Java Themen

Neue Themen


Oben