Jar Export Bilddateien

[QUOTE=L-ectron-X]Kannst du mal genau zeigen, wie die Verzeichnisse zueinander stehen?
Das ist wichtig, um den korrekten Pfad in der Anweisung zum Bilderladen angeben zu können.[/QUOTE]

Diese Ordner sind in der jar:
img -> Dort sind die Bilder.
paketname -> Dort sind die .class und die .java Dateien
META-INF

Das meinte ich nicht, das konnte ich oben bereits lesen.
Was ich meine ist, dass es einen Unterschied macht, wo die Bilder (in welchem Package/Verzeichnis) die Bilder liegen.
Was immer funktionieren sollte, ist den absoluten Pfad zur Referenz zu verwenden. Ist im Wiki auch beschrieben.

Ja aber dann kann ein anderer Benutzer bei dem die jar File nicht gleich liegt die Bilder ja nicht sehen.

Doch, die Bilder liegen im jar-File und werden aus den Verzeichnissen des Jar-Files referenziert.
getClass().getResource(…) liefert den Pfad in Abhängigkeit zur eingebundenen Quelldatei aus dem Jar-File.
Wie gesagt, im Wiki steht alles. Ansonsten poste bitte mal ein KSKB (Kurzes selbstständiges kompilerbares Beispiel).

Edit von L-ectron-X:
Datei von Filehoster gezogen und hier hochgeladen.

Deinem Code entsprechend so sollte es dann aussehen:

Image image = ImageIO.read(getClass().getResource("../img/Hintergrund.gif"));

Ist aber alles im Wiki zu lesen und wird in der Richtung mein letzter Post sein.

Ich mach’ es nochmal einfach…

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public final class BaseURL {
	private static final String JAR_SIG = ".jar!/";
	private static final String CONCAT = ".class";
	private static final File CURRENT = new File(".");

	public static URL getJarURL(Class<?> clazz) {
		URL rc = clazz.getResource(clazz.getSimpleName() + CONCAT);
		String name = clazz.getName().replace('.', '/').concat(CONCAT);
		name = rc.toString().replace(name, "");
		try {
			rc = new URL(null, name);
			return rc;
		} catch (MalformedURLException e) {
			throw new RuntimeException("jar dir could not be determined");
		}
	}

	public static URL getCodeBase(Class<?> clazz) {
		URL rc = getJarURL(clazz);
		if (rc.getProtocol().equals("jar")) {
			String name = rc.toString();
			int i = name.indexOf(JAR_SIG);
			name = name.substring(4, i);
			try {
				rc = new URL(null, name);
				rc = new URL(rc, "./");
			} catch (MalformedURLException e) {
				throw new RuntimeException("code base could not be determined");
			}
		}
		return rc;
	}

	public static URL getDocumentBase() {
		try {
			String rc = getAbsoluteFile(CURRENT).toURI().toURL()
					.toString();
			return new URL(null, rc.substring(0, rc.length() - 2));
		} catch (MalformedURLException e) {
			throw new RuntimeException("document base could not be determined");
		}
	}

	public static File getAbsoluteFile(File f) {
		try {
			f = f.getCanonicalFile();
		} catch (IOException e) {
			f = f.getAbsoluteFile();
		}
		return f;
	}
}```
1. "getJarURL()" liefert das Root-Verzeichnis des Jars in welchem sich die übergebende Klasse befindet. Vergleichbar mit "getClass().getClassLoader().getRessource("path/file.dat")".
2. "getCodebase()" liefert das Verzeichnis in welchem sich das Archiv befindet, dass die übergebende Klasse enthält.
3. "getDocumentBase()" liefert das Verzeichnis, in welchem die aktuelle Anwendung ausgeführt wird.
4. "getAbsolutFile()" umschifft einen Windows betreffenden "Bug" durch welchen Links (".lnk") auf Verzeichnisse teils als Datei und teils als Verzeichnis gehandelt werden.

Das Ganze verwendet URLs, weil man so (wie beim Applet, blos ohne AccessControlException) keine expliziten FileStreams geschweige denn die Klasse File mehr benötigt. Dateiinfos bekommt man per "<URL>.openConnection()" und einen InputStream per "<URL>.openStream()". Es stelltsich nie wieder die Frage, was verwendet werden muss; "getRessource()" über Classloader oder nur Class, Pfadrelativ oder nicht, File-Klassen oder sonstwas, alles ist URL-Absolut (logisch ;)). Je mehr man diese Utility-Klasse verwendet, desto mehr gewöhnt man sich dran.
Pfade ändern kann man übrigens mit "new URL(getIrgendNeURL(), "mypath/myfile.file");

http://s7.directupload.net/file/d/3339/nx8nq9m5_png.htm

Unhandled exception type IOException kommt als Fehlermeldung.

Die Meldung besagt, dass Du mögliche Exception abfangen und behandeln musst. Einfach mal nach java exception handling oder java try catch suchen. So schwer ist das nicht.

Damit das Bild geladen werden kann, ist eingentlich nicht viel nötig. Und die Lösung wurde schon mehr als einmal gepostet.


import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

public class Hintergrund {
	Image hintergrund;
	Random random = new Random();
	
	public Hintergrund() {
		try {
			hintergrund = ImageIO.read(this.getClass().getResourceAsStream("/img/Hintergrund.gif"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void draw(Graphics g) {
		if (hintergrund==null)
			return;
		for (int x = 75; x <= 675; x += 150)
			for (int y = 75; y <= 675; y += 150)
				g.drawImage(this.hintergrund, x, y, null);
	}
...```

Vielen dank an für die Hilfe an alle.
Hab meinen Fehler gefunden. Ich hab nicht bedacht das es in Eclipse nicht funktioniert und es nur als jar funktioniert.

Mit der Vorgehensweise wie in meinem Beispielcode funktioniert es immer solange das Package über den ClassPath zu finden ist - auch innerhalb Eclipse.

Das sollte innerhalb von Eclipse und im JAR genau gleich funktionieren. Wo kommt das “img” Verzeichnis den genau her?

Am besten legt man sich für Ressourcen ein Verzeichnis über “New -> Source Folder” an. Alle Elemente darin können dann über getResource/getResourceAsStream gefunden werden. Sowohl im JAR als auch innerhalb von Eclipse.

Viele Grüße
Fancy

Jetzt funktioniert es zwar in Eclipse aber die jar File lässt sich nicht mehr öffnen. Außerdem funktionieren die Animationen der gifs nicht mehr…

Warum sich das jar nicht mehr öffnet? Keine Ahnung. Starte es mit java -jar … via Konsole da sollte eine Fehlermeldung zu sehen sein.

Animierte gifs mittels ImageIO zu laden geht meines Wissens so nicht. Kann mich aber auch irren, ich nutze ImageIO nicht.

Auf jeden Fall geht es über den Weg ImageIcon:


import java.awt.Graphics;
import java.awt.Image;
import java.util.Random;

import javax.swing.ImageIcon;

public class Hintergrund {
	Image hintergrund;
	Random random = new Random();

	public Hintergrund() {
		this.hintergrund = new ImageIcon(getClass().getResource("/img/Hintergrund.gif")).getImage();
	}
...```

Ja, endlich funktioniert alles…
Vielen dank _Michael deine Tipps haben perfekt funktioniert.
Kann dann denke ich geschlossen werden.