Reputation: 886
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.
"/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 displayRuntime 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)
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!
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!
Upvotes: 4
Views: 4196
Reputation: 2554
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.
Upvotes: 6