2

I am attempting to make a simple menu in JavaFX. When I attempt to load an image using a relative path I receive the following exception:

Caused by: java.lang.IllegalArgumentException: Invalid URL or resource not found
  at javafx.scene.image.Image.validateUrl(Image.java:1110)

I am using eclipse, although this problem appears not be eclipse specific, since I have received the same exception when running in terminal. Also, for some reason it works when the file is in inside the package or in the src folder (given path is changed appropriately).

My Current active class Menu.java is in the package test.dsp, which is located in the project as:

project/src/test/dsp/Menu.java

The file I am attempting to access:

project/assets/graphics/test/dsp/sslogo.png

I am attempting to access the file under the assumption that this path is relative to the current Menu class in Menu.java and due to the physical directories being project/src/test/dsp/Menu.java, I am implementing ../ thrice in my relative path to get to the project directory. Then I simply put the path to the image as seen below.

Image ssLogo = new Image("../../../assets/graphics/test/dsp/sslogo.png",
            2000, 2000, true, true);

I am basing my knowledge off of the constructor described in the JavaFX API:

public Image(java.lang.String url,
     double requestedWidth,
     double requestedHeight,
     boolean preserveRatio,
     boolean smooth)

url - the string representing the URL to use in fetching the pixel data

I have searched through a plethora of questions but their answers do not provide a solution to making my current case work. I've tried getResource, getResourceAsStream, and external resource. I checked the URL that is returned by these means and none worked with my provided path as seen above. I also tried different numbers of ../, still to no avail. Admittedly, I may have implemented them wrong, which led to no success.

  • Why does this method of file access via relative path not work and how can I make this work with my current directory set up?

  • What is the proper way to access a file via a relative path in java in general? And specifically when the file is outside of the package, such as this case?

    • is there a way to include the file into the file path via code in the java class?
  • Is it more efficient to have the file inside the package, or does it not matter (clearly depending on the means of accessing the file outside of package)?

    • is there a more effective means of file access through java?
fabian
  • 80,457
  • 12
  • 86
  • 114
prijatelj
  • 865
  • 2
  • 12
  • 27

1 Answers1

4

A relative path in java starts at the root of your project (in your case the "project" directory) and not at the class where the url is called. So the relative path to your png file would be "assets/graphics/test/dsp/sslogo.png".

Generally packages do not have influence on relative path.

The more efficient way is to keep your images and other static files, as you did, in a different directory. "src" folder is reserved for .java files.


Update:

As said in that post : https://stackoverflow.com/a/16122215/6629388

If you don't use a protocole like http: or file: at the start of the URL the resource will be searched in the (default) package. So in your case the good way to get your file is to use the following line :

Image ssLogo = new Image("file:assets/graphics/test/dsp/sslogo.png", 2000, 2000, true, true);
Community
  • 1
  • 1
  • I have already tried this with no success. Any reason why this would not work? Perhaps I am missing something incredibly simple, but I have tested this and it does not work. Any thoughts why, would be helpful. code below: Image ssLogo = new Image("assets/graphics/test/dsp/sslogo.png", 2000, 2000, true, true); – prijatelj Jul 24 '16 at 02:28
  • Of course my question turns out to be a duplicate. I wonder why I didn't find that question... >_< Using: "file:assets/graphics/test/dsp/sslogo.png" works and has solved the problem. But I still do not understand and would like some clarification/confirmation: So by using the "file:" at the beginning of my URL string, the path will be relative to the project root directory, in this case "project", Correct? If the URL string is w/o file: or http:, then it searches in the "default" package? Even though I am not using the default package? or do you mean the package of the class? – prijatelj Jul 24 '16 at 14:06
  • 1
    When you use the _file:_ protocol the path is local to your computer it can be relative or absolute (ex:"file:c:/users/Quentin/Desktop/myImage.png" or "file:resources/images/myImage.png"). In the case of a relative path it will be relative to the project root directory. With the _http:_ protocol you can get an image on the web but i think other protocols can be used. If you don't use protocol (ex:"resources/images/myImage.png") the path will be relative to the default package. In your case without protocol the image is searched at "project/src/assets/graphics/test/dsp/sslogo.png" – Quentin Seiwert Jul 24 '16 at 17:14
  • Excellent explanation Quentin. :D Thank you. 1 more question, is accessing a file one way better in efficiency or time than the other? [EDIT] nevermind. Project is not the default package. I believe in this case that would be src. And since assets is not a part of src, then it cannot be reached via your other method. I think I understand now. – prijatelj Jul 24 '16 at 20:38