Jaideep Shekhar
Jaideep Shekhar

Reputation: 886

Display Image in JavaFX using fxml

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:
enter image description here

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:
  1. "/res/icon.png" -> Runtime error #1
  2. "res/icon.png" -> Lint error + Runtime error #1
  3. "/../res/icon.png" -> Lint error + Runtime error #1
  4. "../res/icon.png" -> Lint error + Runtime error #1
  5. "@/res/icon.png" -> Runtime error #2
  6. "@res/icon.png" -> Lint error (What I am using)
  7. "@/../res/icon.png" -> Lint error + Runtime error #2
  8. "@../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:
  1. Why does Image don't load in JavaFX which is exactly my configuration.
  2. 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.
  3. ImageView does not work but I would like to do this in fxml only.
  4. Can't load JavaFX Image again fxml only.
  5. Cannot load Image in JavaFX again fxml only.
  6. Load Image to ImageView JavaFX again fxml only.
  7. JavaFX Image loading error I am not using CSS.
  8. JavaFX image loading in background and threads not what I'm interested in.
  9. 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):

  1. 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.

  2. 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!

  1. 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!

Upvotes: 4

Views: 4196

Answers (1)

Allan Juan
Allan Juan

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

Related Questions