J'essaie de charger une image à utiliser comme icône dans mon application. La méthode appropriée selon ce tutorial est:
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;
}
}
J'ai donc placé l'emplacement du fichier et l'ai transmis en tant que paramètre à cette fonction. Cela ne fonctionnait pas, c’est-à-dire qu’imgURL était nul. Quand j'ai essayé de créer l'ImageIcon en passant explicitement le chemin:
ImageIcon icon = new ImageIcon(path,"My Icon Image");
Cela a très bien fonctionné! Ainsi, l’application peut récupérer l’image à partir d’un chemin explicitement défini, mais ne l’a pas récupérée à l’aide de getResources (). Dans les deux cas, la valeur de la variable de chemin est la même. Pourquoi ça ne marcherait pas? Comment les ressources sont-elles trouvées par le chargeur de classe?
Merci.
Vous pouvez demander un chemin dans ce format:
/package/path/to/the/resource.ext
Même les octets pour créer les classes en mémoire se trouvent de cette façon:
my.Class -> /my/Class.class
et getResource
vous donnera une URL qui peut être utilisée pour récupérer une InputStream
.
Mais ... je recommanderais d'utiliser directement getClass().getResourceAsStream(...)
avec le même argument, car il renvoie directement InputStream et vous n'avez pas à vous soucier de la création d'un objet URL (probablement complexe) qui doit savoir comment créer InputStream.
En bref: essayez d'utiliser getResourceAsStream
et un constructeur de ImageIcon
qui utilise un InputStream
comme argument.
Classloaders
Faites attention si votre application compte de nombreux chargeurs de classe. Si vous avez une application autonome simple (pas de serveur ou des choses complexes), vous ne devriez pas vous inquiéter. Je ne pense pas que ce soit le cas à condition que ImageIcon
soit capable de le trouver.
Edit: classpath
Comme le dit Mattb, getResource
sert au chargement de ressources depuis le classpath (à partir de votre répertoire .jar ou classpath). Si vous regroupez une application, il est agréable d'avoir tout à fait, de sorte que vous pouvez inclure le fichier d'icône dans le pot de votre application et l'obtenir de cette façon.
getClass().getResource(path)
charge les ressources depuis le chemin d'accès aux classes, et non depuis un chemin de système de fichiers.
En tant que noobie, j'ai été dérouté par cela jusqu'à ce que je réalise que le "chemin" correspond au cheminrelatifdu fichier MyClass. class dans le système de fichiers et non à MyClass. Java fichier. Mon IDE copie les ressources (telles que xx.jpg, xx.xml) dans un répertoire local de MyClass.class. Par exemple, dans un répertoire pkg appelé "target/classes/pkg. L'emplacement du fichier de classe peut être différent pour différents IDE et en fonction de la structure de la construction pour votre application. Vous devez tout d'abord explorer le système de fichiers et trouver l'emplacement de le fichier MyClass.class et l'emplacement copié de la ressource associée que vous cherchez à extraire, puis déterminez le chemin relatif au fichier MyClass.class et écrivez-le sous forme de valeur de chaîne avec "points" et "barres obliques".
Par exemple, voici comment je mets un fichier app1.fxml à la disposition de mon application javafx où le "MyClass.class" approprié est implicitement "Main.class". Le fichier Main.Java est l'endroit où cette ligne de code appelant une ressource est contenue. Dans mon cas spécifique, les ressources sont copiées dans un emplacement du même niveau que le dossier du package englobant. C'est-à-dire: /target/classes/pkg/Main.class et /target/classes/app1.fxml. Donc, pour paraphraser ... la référence relative "../app1.fxml" est "commencez à partir de Main.class, montez d’un niveau de répertoire, vous pouvez maintenant voir la ressource".
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("../app1.fxml"));
Notez que dans cette chaîne de chemin d'accès relatif "../app1.fxml", les deux premiers points font référence au répertoire contenant Main.class et à l'unique "." indique une extension de fichier à suivre. Une fois que ces détails sont devenus une seconde nature, vous oublierez pourquoi c'était déroutant.
getResource par exemple:
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();
}
}
sortie:
test1: file:/home/szb/projects/test/bin/szb/testGetResource/test.css
test2: file:/home/szb/projects/test/bin/szb/testGetResource/test.css