Use fxml to display images in JavaFX
I’ve been trying to display my images in my JavaFX application using fxml without success.
My code:
...
<ImageView fitHeight="24" fitWidth="24"
pickOnBounds="true" preserveRatio="true">
<Image url="@res/icon.png"/>
</ImageView>
...
My project directory structure:
No error, but my image is not showing up. I think the image is loaded, but not displayed.
Is this possible? How do I check? If so, shouldn’t an error be reported?
In fact, even if I give the wrong name, there is no runtime error. So maybe not loading?
I also tried loading different images and changing the size, but nothing worked.
I tried:
"/res/icon.png"
-> Runtime Error #1"res/icon.png"
-> lint error + runtime error #1"/.. /res/icon.png"
-> lint error + runtime error #1".. /res/icon.png"
-> lint error + runtime error #1"@/res/icon.png"
-> Runtime Error #2"@res/icon.png"
– > lint error (which I’m using)."@/.. /res/icon.png"
-> lint error + runtime error #2"@.. /res/icon.png"
-> lint error, no display
Runtime Error #1: Reason: java.lang.IllegalArgumentException: Invalid URL: Invalid URL or resource not found
Runtime Error #2: Caused: javafx.fxml.LoadException: Invalid resource: /res/icon .png not found in classpath
(I know we shouldn’t use … or . in URLs.) I’m just testing)
I’ve seen:
- Why does Image don’t load in JavaFX This is exactly my configuration.
- How to show image using ImageViewFrom there I got the right way to link images in fxml. There are no errors, but the image is not loading/displaying.
- ImageView does not work, but I want to do it in fxml Only do this.
- Can’t load JavaFX Image again fxml.
- Cannot load Image in JavaFX again only fxml.
- Load Image to ImageView JavaFX again only fxml.
- JavaFX Image loading errorI am not using CSS.
- JavaFX image loading in Background and threads are not what I’m interested in.
- How to determine correct path… Very broad, but what about fxml?
EDIT: I recreated a copy of the original project and tried to troubleshoot by following the comments.
Results (response to the troubleshooting section):
- Correct image name
: The name is valid and the image is correctly deployed to
the out
folder. However, the IDE does not recognize it, resulting in an error or no display.Correct path
a) Absolute URL
Interestingly, the getClass().getResource("/res/icon.png").getExternalForm()
method gives:
file:/C:/Users/Chander%20Shekhar/IdeaProjects/TestRes/out/production/TestRes/res/icon.png
And it works. Not sure if file:
should exist. The getPath()
method gives:
/C:/Users/Chander%20Shekhar/IdeaProjects/TestRes/out/production/TestRes/res/icon.png
And doesn’t work (runtime error #1). Removing the first /
gives another error :
Caused by: java.lang.IllegalArgumentException: Invalid URL: unknown protocol: c
b) Relative URL
So I actually created a markup class in my res
folder and gave it using ImageMarker.class.getResource("icon.png").toExternalForm().
file:/C:/Users/Chander%20Shekhar/IdeaProjects/TestRes/out/production/TestRes/res/icon.png
Same as the first example, and valid!
- Classpath: I also make sure I have the relative address of the project root,
the src
folder (I believe it’s the classpath root. Wrong ? )
But in the end, all of this is still irrelevant because I’m using fxml. Oh my God!
Solution
I recommend that you use the Resources folder and put both your FXML and images in that folder. So you will have this file structure:
src/
|-- main/
| --.java/
| -- resources/
| -- fxml/screen.fxml
| -- img/image.png
Then on screen.fxml
you would do something similar
<pre class=”lang-xml prettyprint-override”><ImageView pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@.. /img/image.png" />
</image>
</ImageView>
That’s how I organized my project, and it worked well. The CSS file will also be present in the resource, I hope it helps.
PS: You have a res/
folder, but Java doesn’t recognize it as a resource folder unless you confirm. If you are using IntelliJ, you can right-click it and select Mark as Resource Root. If you use Maven, you can declare it as a resource folder in several ways. Anyway, if you just rename it to resources/, it will automatically be considered your resources
folder.