来自资源文件夹的JavaFX图像 [英] JavaFX Image from resources folder
问题描述
由于某种原因,我一直在gradle javafx项目中获得NPE.
我的文件夹结构非常基本.我在main/java
文件夹中有一个带有Java文件的程序包.我的资源也位于main/resources
文件夹中.当我尝试加载image.png
时,它会给我NPE.
public static Image createImage(Object context, String url) {
Image m = null;
InputStream str = null;
URL _url = context.getClass().getResource(url);
try {
m = new Image(_url.getPath());
} catch (NullPointerException e) {
e.printStackTrace();
}
return m;
}
这是一个帮助程序类.
在Scene
中,我称:Image image = Helper.createImage(this, "image.png");
图像的绝对路径为main/resources/images/image.png
.
我检查了互联网上的每个教程,但找不到任何解决方案.我还尝试使用图像的路径作为参数,并使用InputStream
进行了尝试,但从未成功.
资源
并且您正在使用 另一个问题是您对 但是 由于 那么您至少有两个选择: 将绝对资源名称(即 将资源移到与 当然,如 那应该可行.但是,请注意:使用模块时,只有在包含资源的软件包为 For some reason I keep getting an NPE in a gradle javafx project. My folder structure is very basic. I have a package with my java files in the This is a helper class. From the I checked every tutorial on the internet but I couldn't find any solution for this. I also tried it with the path to the image as parameter and also with an The In a typical Maven/Gradle project structure, the From your question I gather your project structure looks something like: And you're calling your method with an The other problem is your use of But the result of This causes a problem due to the way All URLs supported by Notice the second sentence. If the passed URL does not have a scheme then it's interpreted as a resource name and the If you're going to use the Then you have at least two options: Pass the absolute resource name (i.e. Move the resource to the same package as the class of the passed in Of course, as noted by the documentation of And that should work. A note of caution, however: When using modules the above will only work if the resource-containing package is 这篇关于来自资源文件夹的JavaFX图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!<project-dir>
|--src/
|--main/
|--java/
|--resources/
|--images/
|--image.png
Object
和资源名称image.png
调用您的方法.这里的问题是,由于要传递相对名称,因此资源相对于传递的Object
的Class
(即context
)位于.我怀疑您的类是否位于名为images
的程序包中,这意味着将找不到相对于所述类的资源.您需要传递一个绝对名称:/images/image.png
.URL#getPath()
的使用.如果要找到资源,则从Class#getResource(String)
获得的URL
将看起来像这样:
file:/path/to/gradle/project/build/resources/main/images/image.png
URL#getPath()
的结果将给您:
/path/to/gradle/project/build/resources/main/images/image.png
Image
的工作方式,这会导致问题.来自文档:
public static Image createImage(Object context, String resourceName) {
URL _url = context.getClass().getResource(resourceName);
return new Image(_url.toExternalForm());
}
"/images/image.png"
)传递给您的#createImage(Object,String)
方法,因为image.png
资源与所传递的Object
(即context
)不在同一个包中.Object
中传递的类(即context
)相同的包中.例如,如果上下文对象的类为com.foo.MyObject
,则将资源放在src/main/resources/com/foo
下,它将与MyObject
放在同一包中.这将允许您继续传递相对资源名称.Image
的文档所述,您可以传递无方案的URL,并将其解释为资源名称.换句话说,您可以执行以下操作:
Image image = new Image("images/image.png");
opens
无条件或模块本身为open
的情况下,以上方法才有效.main/java
folder. I also have my resources in the main/resources
folder. When I try to load image.png
it gives me an NPE.public static Image createImage(Object context, String url) {
Image m = null;
InputStream str = null;
URL _url = context.getClass().getResource(url);
try {
m = new Image(_url.getPath());
} catch (NullPointerException e) {
e.printStackTrace();
}
return m;
}
Scene
I call: Image image = Helper.createImage(this, "image.png");
The absolute path to the image would be main/resources/images/image.png
. InputStream
but it never worked.Resources
Class#getResource(String)
and related API are used for locating resources relative to the class path and/or module path. When using Class
to get a resource you can pass an absolute name or a relative name. An absolute name will locate the resource relative to the root of the class path/module path; an absolute name starts with a /
. A relative name will locate the resource relative to the location of the Class
; a relative name does not start with a leading /
.src/main/java
and src/main/resources
are roots of the class path/module path. This means all resource names are relative to those directories. It's slightly more complicated than that because the files under those directories are moved to the target/build directory and it's that location that's put on the class path/module path, but for all intents and purposes consider the source directories as the root. There's a reason a get-resource API exists in the first place, to provide an application-location-independent way of obtaining resources.
Issues in Your Code
<project-dir>
|--src/
|--main/
|--java/
|--resources/
|--images/
|--image.png
Object
and a resource name of image.png
. The problem here is that, since you're passing a relative name, the resource is located relative to the Class
of the passed Object
(i.e. context
). I doubt your class is located in a package named images
which means the resource will not be found relative to said class. You need to pass an absolute name: /images/image.png
.URL#getPath()
. The URL
you obtain from Class#getResource(String)
will, if the resource were to be found, look something like this:file:/path/to/gradle/project/build/resources/main/images/image.png
URL#getPath()
will give you:/path/to/gradle/project/build/resources/main/images/image.png
Image
works. From the documentation:
URL
can be passed to the constructor. If the passed string is not a valid URL, but a path instead, the Image is searched on the classpath in that case. Image
will locate the image file relative to the classpath. In other words, since you're passing the value of URL#getPath()
to the Image
constructor it searches for the resource image.png
in the package path.to.gradle.project.build.resources.main.images
. That package does not exist. You should be passing the URL as-is to the Image
constructor via URL#toString()
or URL#toExternalForm()
.
Solution
URL
returned by Class#getResource(String)
to load the Image
then no matter what you need to use URL#toString()
or URL#toExternalForm()
instead of URL#getPath()
.public static Image createImage(Object context, String resourceName) {
URL _url = context.getClass().getResource(resourceName);
return new Image(_url.toExternalForm());
}
"/images/image.png"
) to your #createImage(Object,String)
method since the image.png
resource is not in the same package as the passed Object
(i.e. context
).Object
(i.e. context
). For instance, if the context object's class is com.foo.MyObject
then place the resource under src/main/resources/com/foo
and it will be in the same package as MyObject
. This will allow you to continue passing the relative resource name.Image
you can pass a scheme-less URL and it's interpreted as a resource name. In other words, you could do:Image image = new Image("images/image.png");
opens
unconditionally or if the module itself is open
.