20

I would like to know what the JavaFX Image constructor's relative path resolution algorithm is for:

  1. Stand-alone apps.
  2. Browser deployed apps.
  3. Webstart deployed apps.

If the algorithm may look in multiple locations, I'd like to know what they are for each of the above deployment scenarios.

If the behaviour for stand-alone apps is different when the app is placed in a jar, I'd like to know that too.

jewelsea
  • 150,031
  • 14
  • 366
  • 406

3 Answers3

15

Then user provides relative path to new Image(String url) it will be relative against workdir of the app aka System.getProperty("user.dir")

  1. For stand-alone app it's a folder you started an application from
  2. For web-start app being run from command line (javaws myfxapp.jnlp) it works the same way as with standalone app
  3. For plugin start or webstart app loaded from browser you can't reliably be sure about workdir location. It depends on browser and even on installed plugins for that browser.

So general direction is: for standalone apps use url same way as you'll use it in new File(String url). For jnlp/plugin use full url with protocol or Class.getResource() approach.

Update: Please, note, this behavior is going to be clarified and changed in 2.2. See http://javafx-jira.kenai.com/browse/RT-18291

The following comment is from RT-18291 and outlines the intended changes for 2.2:

Martin Sladecek added a comment - May, 15 2012 10:53 AM After discussion with Richard Bair, we decided to change the current (undocumented) behavior for paths. Currently, they are treated as user.dir relative. All path, with or without leading slash will be now resolved as relative to classpath, which will be consistent with CSS and more corresponds to what might users expect. For user.dir relative paths, "file:" URL can be still used.

Sergey Grinev
  • 34,078
  • 10
  • 128
  • 141
  • Sorry, just noticed your update of a question. I'll look into that later on. – Sergey Grinev May 14 '12 at 11:09
  • Thanks Sergey. Sorry the original wording was not clear about all the scenarios I'd like to understand. – jewelsea May 14 '12 at 15:56
  • 1
    Thanks for the detailed update Sergey. I raised a [jira](http://javafx-jira.kenai.com/browse/RT-21515) to get the documentation for the API improved and included your answer in the Jira comments. – jewelsea May 14 '12 at 20:46
  • 1
    I tried EVERYTHING but was unable to locate the file. Do they really think that, while *every other application on planet earth* looks in `user.dir` (or $PWD), this new behavior "corresponds to what users expect"? In any case, thanks a lot for clearing this up. Had no idea that using the latest javafx introduced some breaking changes. – Luc Oct 10 '14 at 22:13
  • It's actually less error-prone the new way. This way you can include your assets in your project and specify the path mostly as you would specify a package (except with slashes instead of dots). Previously, you had to somehow unpack your assets to your user's directory as or before the user first runs it, which made it, if not impossible, then at least very difficult to deploy your stuff as one single JAR (you needed automatic extraction, and if you couldn't auto-extract there was no way). [To be continued.] – Egor Hans Sep 02 '17 at 14:22
  • So, if auto-extraction wasn't a thing, or you couldn't get the hang of it, your user had to put your bunch of pictures into some place they possibly didn't even hear of, otherwise your JAR wouldn't even start cleanly. Also, this is not only how CSS handles it, but also how any other Java code handles it. All file resources are in the JAR, including the very common `*.properties` files. – Egor Hans Sep 02 '17 at 14:29
  • I, for instance, have an `assets` folder in my project resource root, where I put all pictures and sounds and other media stuff. Almost everyone does it like that. It would be a real pain in the ass having to navigate from the launch directory into the JAR every single time you need to access something, considering that, by using the command line, the user could launch your JAR from literally anywhere. – Egor Hans Sep 02 '17 at 14:34
  • Forget about the "directory they possibly didn't even hear of", I later on noticed I misread something. But still, deploying as a ZIP where a JAR and a bunch of resources are stuffed in is more tedious than just deploying as a JAR. You get an unneccessary load of subfolders to keep the assets separate, which you can still very frequently observe with EXE-based ZIP applications. I'm happy that at least for Java, the trend goes to just putting one single executable file with no extras that contains everything it needs. – Egor Hans Sep 02 '17 at 14:43
2

The answer is "/" if case you are using getClass().getResourceAsStream(), i.e. the root of your jar file (inside it). Not user.dir nor where the package is hosted

assylias
  • 321,522
  • 82
  • 660
  • 783
Bruno Vieira
  • 3,884
  • 1
  • 23
  • 35
  • Sorry, but no. Run next code: `System.setProperty("user.dir", "c:"); root.getChildren().add(new ImageView(new Image("brd.jpg")));` and you will have next exception: `java.io.FileNotFoundException: c:\brd.jpg` – Sergey Grinev May 14 '12 at 16:01
  • Yes, that's right, my mistake. I'm used to use getClass().getResourceAsStream() which would search the package instead of user.dir as you stated – Bruno Vieira May 14 '12 at 16:31
  • 1
    please, update your answer to state it's `getClass().getResourceAsStream()` case to avoid confusing readers. – Sergey Grinev May 14 '12 at 17:27
0
  1. search directory where class files( name of class getClass().getName().toString() ) related to your .java file are present, copy and paste your image there
  2. Image image=new Image(getClass().getResourceAsStream("yourImageName.jpg")); is must.

In NetBeans the directory where classes are present NetBeansProjects/JavaFXProjectName/build/classes/packageName/

Sukhraj
  • 41
  • 5