Следует помнить, что ресурсы - это не то же самое, что файлы, несмотря на то, что они выглядят довольно схожими, особенно перед упаковкой приложения.После упаковки приложения эти файлы ресурсов становятся записями в JAR-файле, к которым, хотя их можно рассматривать как файлы, нельзя получить такой же доступ, как и к файлам.В частности, API java.io.File
не понимает, как читать эти записи.Однако вы можете получить доступ к этим записям через URL
, возвращаемое Class#getResource(String)
или InputStream
, возвращаемое Class#getResourceAsStream(String)
.Обратите внимание, что последний в основном просто находит URL
и, если он существует, вызывает URL#openStream()
.Причина, по которой вы можете получить доступ к записям JAR (т. Е. К ресурсам) с помощью URL
, связана с JarURLConnection
и связанными классами;Я не буду вдаваться в подробности о том, как URL обрабатываются Java, поскольку это выходит за рамки этого ответа.
Теперь, так как вы пытаетесь отобразить изображение в JavaFX, я предполагаю, что вы используете Image
класс.Есть в основном три способа сообщить Image
, где находится ресурс изображения.
Использовать Image#<init>(String)
, где в аргументе URL отсутствует схема.В этом случае класс будет обрабатывать URL как путь относительно корня пути к классу и пытаться получить к нему доступ соответствующим образом.По сути, аргумент - это тот же аргумент, который вы бы указали Class#getResource(String)
, за исключением того, что путь должен быть абсолютным (т. Е. Не относиться ни к какому классу).Это поведение задокументировано классом Image
:
Все URL, поддерживаемые URL
, могут быть переданы в конструктор.Если переданная строка не является допустимым URL-адресом, а вместо этого указывается путь, в этом случае выполняется поиск образа на пути к классам.
Примечание. Если вы используете модули, то Инкапсуляция ресурсов вступает в игру при использовании этой опции.См. GitHub Issue # 441 .
Используйте тот же конструктор, что и выше, но передайте действительный URL (т. Е. У него есть схема).При использовании ресурса вы можете просто преобразовать URL
, возвращаемый Class#getResource(Sring)
в String
, используя URL#toExternalForm()
.
Image image = new Image(getClass().getResource(...).toExternalForm());
Примечание: вы можететакже используйте URL#toString()
, который возвращает то же значение.
Используйте Image#<init>(InputStream)
.Здесь вы можете использовать Class#getResourceAsStream(String)
.Не забудьте закрыть InputStream
, когда закончите с ним.
try (InputStream is = getClass().getResourceAsStream(...)) {
Image image = new Image(is);
}
Все это предполагает, что ресурсы были правильно упакованы в ваш файл JAR при его создании.Если это не так, сначала следуйте советам, данным Хосе Переда в комментариях к вопросу.
Обратите внимание, что можно получить доступ к записям файла ZIP / JAR с помощью API java.util.zip.*
java.util.jar.*
API или Java NIO ZipFileSystemProvider
.Каждый из них, особенно последний вариант, позволяет получить доступ к записям файла ZIP / JAR, аналогичным фактическим файлам, поскольку они специально предназначены для этого.Однако при использовании ресурсов в приложении вы должны придерживаться Class#getResource(String)
и связанных с ним методов.