Carregando resources usando getClass (). GetResource ()

Eu estou tentando carregar uma imagem para usar como um ícone no meu aplicativo. O método apropriado de acordo com este tutorial é:

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

Então, coloquei a localização do arquivo e passei-o como um parâmetro para essa function. Isso não funcionou, ou seja, imgURL era nulo. Quando tentei criar o ImageIcon passando explicitamente no caminho:

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

Funcionou muito bem! Assim, o aplicativo pode pegar a imagem de um caminho explicitamente definido, mas não pegou a imagem usando getResources (). Nos dois casos, o valor da variável path é o mesmo. Por que isso não funcionaria? Como os resources são encontrados pelo carregador de classs?

Obrigado.

Você pode solicitar um caminho neste formato:

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

Até mesmo os bytes para criar as classs na memory são encontrados desta maneira:

 my.Class -> /my/Class.class 

e getResource lhe dará uma URL que pode ser usada para recuperar um InputStream .

Mas … Eu recomendo usar diretamente getClass().getResourceAsStream(...) com o mesmo argumento, porque ele retorna diretamente o InputStream e não precisa se preocupar com a criação de um object URL (provavelmente complexo) que precisa sabe como criar o InputStream.

Resumindo: tente usar getResourceAsStream e algum construtor do ImageIcon que use um InputStream como um argumento.

Classloaders

Tenha cuidado se seu aplicativo tiver muitos classloaders. Se você tiver um aplicativo autônomo simples (sem servidores ou coisas complexas), não se preocupe. Eu não acho que é o caso desde ImageIcon foi capaz de encontrá-lo.

Editar: caminho de class

getResource é – como diz o mattb – para carregar resources do caminho de class (do seu diretório .jar ou caminho de class). Se você está empacotando um aplicativo, é bom tê-lo completamente, então você pode include o arquivo de ícone dentro do jar do seu aplicativo e obtê-lo dessa maneira.

getClass().getResource(path) carrega resources do caminho de class, não de um caminho do sistema de arquivos.

Como noobie fiquei confuso com isso até que percebi que o chamado “caminho” é o caminho relativo ao MyClass. arquivo de class no sistema de arquivos e não o MyClass. arquivo java . Meu IDE copia os resources (como xx.jpg, xx.xml) para um diretório local para o MyClass.class. Por exemplo, dentro de um diretório pkg chamado “target / classs / pkg. O local do arquivo de class pode ser diferente para IDEs diferentes e dependendo de como a compilation é estruturada para o seu aplicativo. Você deve primeiro explorar o sistema de arquivos e localizar o local o arquivo MyClass.class e o local copiado do recurso associado que você está tentando extrair.Em seguida, determine o caminho relativo ao arquivo MyClass.class e escreva-o como um valor de string com “pontos” e “barras”.

Por exemplo, aqui está como eu disponibilizo um arquivo app1.fxml para meu aplicativo javafx em que o “MyClass.class” relevante é implicitamente “Main.class”. O arquivo Main.java é onde esta linha de código de chamada de recurso está contida. No meu caso específico, os resources são copiados para um local no mesmo nível da pasta do pacote que o contém. Ou seja: /target/classs/pkg/Main.class e /target/classs/app1.fxml. Então, parafraseando … a referência relativa “../app1.fxml” é “iniciar a partir de Main.class, subir um nível de diretório, agora você pode ver o recurso”.

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

Observe que nesta cadeia de caminho relativo “../app1.fxml”, os dois primeiros pontos fazem referência ao diretório que inclui Main.class e o único “.” indica uma extensão de arquivo a seguir. Depois que esses detalhes se tornarem uma segunda natureza, você vai esquecer por que isso era confuso.

getResource por exemplo:

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

insira a descrição da imagem aqui

saída:

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