Laden von Ressourcen mit getClass (). GetResource ()

Ich versuche ein Bild zu laden, das in meiner Anwendung als Symbol verwendet wird. Die geeignete Methode gemäß diesem Tutorial ist:

protected ImageIcon createImageIcon(String path, String description) { java.net.URL imgURL = getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL, description); } else { System.err.println("Couldn't find file: " + path); return null; } } 

Also platzierte ich den Speicherort der Datei und übergab ihn als Parameter an diese function. Das hat nicht funktioniert, dh imgURL war null. Ich habe versucht, ImageIcon zu erstellen, indem ich den Pfad explizit übergeben habe:

 ImageIcon icon = new ImageIcon(path,"My Icon Image"); 

Es hat super funktioniert! So kann die Anwendung das Bild von einem explizit definierten Pfad aufnehmen, aber das Bild nicht mit getResources () aufnehmen. In beiden Fällen ist der Wert der Pfadvariablen derselbe. Warum würde es nicht funktionieren? Wie werden Ressourcen vom classnlader gefunden?

Vielen Dank.

   

Sie können einen Pfad in diesem Format anfordern:

 /package/path/to/the/resource.ext 

Sogar die Bytes zum Erstellen der classn im Speicher werden auf diese Weise gefunden:

 my.Class -> /my/Class.class 

und getResource gibt Ihnen eine URL, mit der Sie einen InputStream abrufen können.

Aber … Ich würde empfehlen, getClass().getResourceAsStream(...) mit demselben Argument zu verwenden, da es direkt den InputStream zurückgibt und sich keine Sorgen über die Erstellung eines (wahrscheinlich komplexen) URL-Objekts machen muss weiß, wie man den InputStream erstellt.

Kurz gesagt: Versuchen Sie es mit getResourceAsStream und einem Konstruktor von ImageIcon , der einen InputStream als Argument verwendet.

classnlader

Sei vorsichtig, wenn deine App viele classnlader hat. Wenn Sie eine einfache eigenständige Anwendung haben (keine Server oder komplexe Dinge), sollten Sie sich keine Sorgen machen. Ich denke nicht, dass dies der Fall ist, vorausgesetzt, ImageIcon konnte es finden.

Bearbeiten: classnpfad

getResource ist – wie Mattb sagt – zum Laden von Ressourcen aus dem classnpfad (aus Ihrem .jar- oder classpath-Verzeichnis). Wenn Sie eine App bündeln, ist es schön, sie zusammen zu haben. Sie können also die Symboldatei in den Krug Ihrer App aufnehmen und auf diese Weise erhalten.

getClass().getResource(path) lädt Ressourcen aus dem classnpfad, nicht aus einem Dateisystempfad.

Als Noobie war ich verwirrt, bis ich erkannte, dass der sogenannte “Pfad” der Pfad zur MyClass ist. classndatei im Dateisystem und nicht die MyClass. Java- Datei. Meine IDE kopiert die Ressourcen (wie xx.jpg, xx.xml) in ein lokales Verzeichnis der MyClass.class. Zum Beispiel in einem pkg-Verzeichnis mit dem Namen “target / classes / pkg. Der Speicherort der class-Datei kann für verschiedene IDEs unterschiedlich sein und abhängig davon, wie der Build für Ihre Anwendung strukturiert ist. Sie sollten zuerst das Dateisystem untersuchen und den Speicherort von Kopieren Sie die MyClass.class-Datei und den kopierten Speicherort der verknüpften Ressource, die Sie extrahieren möchten, und bestimmen Sie dann den Pfad relativ zur MyClass.class-Datei und schreiben Sie diesen als Zeichenfolgenwert mit “dots” und “slashes”.

Hier ist zum Beispiel, wie ich eine app1.fxml-Datei für meine Javafx-Anwendung zur Verfügung stelle, wo die relevante “MyClass.class” implizit “Main.class” ist. In der Main.java-Datei ist diese Zeile mit Ressourcenaufrufcode enthalten. In meinem speziellen Fall werden die Ressourcen an einen Speicherort auf der gleichen Ebene wie der umschließende Paketordner kopiert. Das ist: /target/classes/pkg/Main.class und /target/classes/app1.fxml. Also paraphrasieren … der relative Verweis “../app1.fxml” ist “Start von Main.class, gehe auf eine Verzeichnisebene, jetzt kannst du die Ressource sehen”.

 FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("../app1.fxml")); 

Beachten Sie, dass in dieser relativen Pfadzeichenfolge “../app1.fxml” die ersten beiden Punkte auf das Verzeichnis verweisen, das Main.class und das einzelne “.” weist auf eine Dateiendung hin, der Sie folgen müssen. Nachdem diese Details zur zweiten Natur geworden sind, werden Sie vergessen, warum es verwirrend war.

getResource durch ein Beispiel:

 package szb.testGetResource; public class TestGetResource { private void testIt() { System.out.println("test1: "+TestGetResource.class.getResource("test.css")); System.out.println("test2: "+getClass().getResource("test.css")); } public static void main(String[] args) { new TestGetResource().testIt(); } } 

Bildbeschreibung hier eingeben

Ausgabe:

 test1: file:/home/szb/projects/test/bin/szb/testGetResource/test.css test2: file:/home/szb/projects/test/bin/szb/testGetResource/test.css