web-dev-qa-db-fra.com

Chargement de ressources à l'aide de getClass (). GetResource ()

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.

20
Luhar

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.

14
helios

getClass().getResource(path) charge les ressources depuis le chemin d'accès aux classes, et non depuis un chemin de système de fichiers.

15
matt b

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. 

6
J.E.Tkaczyk

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();
    }
}

 enter image description here

sortie:

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