Issue
I have been unsuccessfully trying to display my image in my JavaFX application using fxml. My code:
...
<ImageView fitHeight="24" fitWidth="24"
pickOnBounds="true" preserveRatio="true">
<Image url="@res/icon.png"/>
</ImageView>
...
My project directory structure:
There is no error, but my image is not displaying. I think the image was loaded, but not displayed.
Is this possible? How can I check? If it is, shouldn't there be an error for it?
Infact, even if I give an incorrect name, there is no runtime error. So maybe not loaded?
I have also tried loading different images and changing the dimensions, nothing works.
I have 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 (What I am using)"@/../res/icon.png"
-> Lint error + Runtime error #2"@../res/icon.png"
-> Lint error, no display
Runtime Error #1: Caused by: java.lang.IllegalArgumentException: Invalid URL: Invalid URL or resource not found
Runtime Error #2: Caused by: javafx.fxml.LoadException: Invalid resource: /res/icon.png not found on the classpath
(I know we shouldn't use .. or . in urls. I was just testing)
I have seen:
- Why does Image don't load in JavaFX which is exactly my configuration.
- How to show image using ImageView from where I got the proper way to link images in fxml. No error, but image not loading/displaying.
- ImageView does not work but I would like to do this in fxml only.
- Can't load JavaFX Image again fxml only.
- Cannot load Image in JavaFX again fxml only.
- Load Image to ImageView JavaFX again fxml only.
- JavaFX Image loading error I am not using CSS.
- JavaFX image loading in background and threads not what I'm interested in.
- How to determine correct path... very extensive, but what about fxml?
Edit: I recreated a duplicate of the original project and tried the troubleshooting following the comments.
The results (response to troubleshooting section):
Proper image name: The name was valid, and the image properly deployed to
out
folder. But it was not recognized by the IDE and resulted in error or no display.Proper paths
a) Absolute URLs
Interestingly, the getClass().getResource("/res/icon.png").getExternalForm()
method gives:
file:/C:/Users/Chander%20Shekhar/IdeaProjects/TestRes/out/production/TestRes/res/icon.png
and works. Not sure if the file:
should be there. 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 /
gave another error:
Caused by: java.lang.IllegalArgumentException: Invalid URL: unknown protocol: c
b) Relative URLs
So I actually made a marker class in my res
folder, and used ImageMarker.class.getResource("icon.png").toExternalForm()
which gave
file:/C:/Users/Chander%20Shekhar/IdeaProjects/TestRes/out/production/TestRes/res/icon.png
Same as the first example, and works!
- Classpath: I also made sure I had the relative address from project root, the
src
folder (which I believe is the classpath root. Wrong?)
But in the end, all of this is still irrelevant, since I am using fxml. God!
Solution
I suggest you to use a resources folder, and put both your FXML and images in that folder. So you'd have this file structure:
src/
|-- main/
| -- java/
| -- resources/
| -- fxml/screen.fxml
| -- img/image.png
Then on screen.fxml
you would do something like
<ImageView pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../img/image.png" />
</image>
</ImageView>
That's how I organize my projects and it works just fine. CSS files will live in resources too, hope that helps.
PS: You have a res/
folder, but Java won't recognize it as a resource folder unless you acknowledge it. If you're on IntelliJ, you can right click it and then choose "Mark as resources root". If you use maven there are ways to declare it as your resource folder. Anyways, if you just rename it to resources/
it will be automatically considered as your resource folder.
Answered By - Allan Juan