Загрузка ресурсов с помощью getClass(). GetResource()

Я пытаюсь загрузить изображение для использования в качестве значка в своем приложении. Соответствующим способом в соответствии с этим 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;
    }
}

Итак, я поместил местоположение файла и передал его как параметр этой функции. Это не сработало, т.е. ImgURL был нулевым. Когда я попытался создать ImageIcon, явным образом передал путь:

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

Он отлично поработает! Таким образом, приложение может получить изображение из явно определенного пути, но не подобрало изображение, используя getResources(). В обоих случаях значение переменной пути одинаково. Почему бы не работать? Как ресурсы найдены загрузчиком классов?

Спасибо.

Ответ 1

Вы можете задать путь в этом формате:

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

Даже байты для создания классов в памяти найдены следующим образом:

my.Class -> /my/Class.class

и getResource предоставит вам URL-адрес, который можно использовать для извлечения InputStream.

Но... Я бы рекомендовал напрямую использовать getClass().getResourceAsStream(...) с тем же аргументом, потому что он возвращает непосредственно InputStream и не должен беспокоиться о создании (возможно, сложного) URL-объекта, который должен знать, как создать InputStream.

Короче: попробуйте использовать getResourceAsStream и некоторый конструктор ImageIcon, которые используют входной поток в качестве аргумента.

загрузчики классов

Будьте осторожны, если в вашем приложении много загрузчиков классов. Если у вас есть простое автономное приложение (без серверов или сложных вещей), вы не должны беспокоиться. Я не думаю, что в этом случае ImageIcon был способен найти его.

Изменить: classpath

getResource is -as mattb says- для загрузки ресурсов из пути к классам (из вашего каталога .jar или classpath). Если вы добавляете приложение в приложение, хорошо бы иметь его, поэтому вы можете включить файл значка в банку своего приложения и получить его таким образом.

Ответ 2

getClass().getResource(path) загружает ресурсы из пути к классам, а не из пути файловой системы.

Ответ 3

Как noobie я был смущен этим, пока не понял, что так называемый "путь" - это путь относительный к файлу MyClass. class в файловой системе и а не файл MyClass. java. Моя IDE копирует ресурсы (например, xx.jpg, xx.xml) в каталог, локальный в MyClass.class. Например, внутри каталога pkg, называемого "target/classes/pkg". Расположение файла-класса может отличаться для разных IDE и в зависимости от структуры структуры для вашего приложения. Сначала вы должны изучить файловую систему и найти местоположение файл MyClass.class и скопированное местоположение связанного ресурса, который вы хотите извлечь. Затем определите путь относительно файла MyClass.class и напишите его как строковое значение с "точками" и "слэшами".

Например, вот как я делаю файл app1.fxml доступным для моего приложения javafx, где соответствующий "MyClass.class" неявно "Main.class". Файл Main.java содержит эту строку кода вызова ресурсов. В моем конкретном случае ресурсы копируются в место на том же уровне, что и вложенная папка пакета. То есть:/target/classes/pkg/Main.class и /target/classes/app 1.fxml. Поэтому перефразируя... относительная ссылка "../app1.fxml" "начинается с Main.class, поднимайтесь на один уровень каталога, теперь вы можете увидеть ресурс".

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

Обратите внимание, что в этой строке относительного пути "../app1.fxml" первые две точки ссылаются на каталог, охватывающий Main.class и единственный ".". указывает расширение файла. После того, как эти детали станут второй натурой, вы забудете, почему это сбивает с толку.