Closed HossamMohsen7 closed 7 years ago
To load resources within your application manually you should use the ResourceLookup
helper.
To get a resource from your classpath, in the same package as the current component:
val myFxmlFile = resources.url("resourcename.fxml")
Alternatively, from any given location on the classpath:
val myFxmlFile = resources.url("/my/package/resourcename.fxml")
But why are you loading FXML files manually? You should make a View
that represents the FXML file and inject the root of the View from FXML instead:
class MyView : View() {
override val root: HBox by fxml()
This will look for MyView.fxml
in the same package as the View class. Alternatively, give any location as a parameter to the fxml
delegate:
class MyView : View() {
override val root: HBox by fxml("/views/myview.fxml")
Remember also that Maven doesn't put fxml-files in your source-folder on the build path, so you should make sure to put them in src/main/resources
and the corresponding package.
If this doesn't solve your problem, please post some code :)
Thanks for the help but I'm sorry I don't recognize this code I'm just using pure java and javaFX to make a desktop game and I'm loading FXML files for the menu and login screens and that things.
I have my .FXML files already in my src/main/resources folder and It works great in eclipse when I use CLASSNAME.class.getResoure("/RESOURCENAME.fxml")
.
What I do is I have a class named SceneChanger that loads all the .fxml files at startup and just changes the Stage parent. EDIT: This is how I load my .fxml files:
SceneChanger.class.getResource("Menu.fxml")
I hope you understood me.
Sorry, I thought you were using TornadoFX for some reason :) I've included an example of loading an FXML file in the FX Launcher Demo Project. This is how I load the FXML file there:
FXMLLoader.load(getClass().getResource("/views/MyView.fxml"))
Can you try using getClass().getResource()
like I do there?
Here is the complete method:
https://github.com/edvin/fxldemo/blob/master/src/main/java/no/tornado/FxlDemo.java#L58-L69
If this doesn't solve your issue, can you link to your code?
Sorry it's still giving me the exception. Here's some code:
start method in Main.java:
@Override
public void start(Stage primaryStage) {
System.out.println("Main.start()");
try {
primaryStage.setAlwaysOnTop(true);
primaryStage.setAlwaysOnTop(false);
primaryStage.getIcons().addAll(
new Image("/icons/icon_256.png"),
new Image("/icons/icon_128.png"),
new Image("/icons/icon_64.png"),
new Image("/icons/icon_32.png"),
new Image("/icons/icon_16.png"),
new Image("/icons/icon_8.png"));
SceneChanger.loginRoot = FXMLLoader.load(getClass().getResource("/Login.fxml"));
SceneChanger.scene = new Scene(SceneChanger.loginRoot);
primaryStage.setScene(SceneChanger.scene);
primaryStage.show();
primaryStage.sizeToScene();
primaryStage.setMaximized(true);
Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
primaryStage.setX((primScreenBounds.getWidth() - primaryStage.getWidth()) / 2);
primaryStage.setY((primScreenBounds.getHeight() - primaryStage.getHeight()) / 2);
Main.primaryStage = primaryStage;
new SceneChanger().load();
} catch(Exception e) {
e.printStackTrace();
}
}
Here's SceneChanger().load():
public void load() {
System.out.println("Loading scenes");
if (menuRoot == null)
try {
menuRoot = FXMLLoader.load(getClass().getResource("/Menu.fxml"));
} catch (Exception e) {
e.printStackTrace();
}
if (settingsRoot == null)
try {
settingsRoot = FXMLLoader.load(getClass().getResource("/Settings.fxml"));
} catch (Exception e) {
e.printStackTrace();
}
if (lobbyRoot == null)
try {
lobbyRoot = FXMLLoader.load(getClass().getResource("/Lobby.fxml"));
} catch (Exception e) {
e.printStackTrace();
}
if (gameRoot == null)
try {
gameRoot = FXMLLoader.load(getClass().getResource("/Game.fxml"));
} catch (Exception e) {
e.printStackTrace();
}
if (resultsRoot == null)
try {
resultsRoot = FXMLLoader.load(getClass().getResource("/Results.fxml"));
} catch (Exception e) {
e.printStackTrace();
}
}
And I change the view by calling SceneChanger.change
which takes a javafx.scene.Parent
Here it is:
public static void change(Parent root) { scene.setRoot(root); currentRoot = root; }
Also every field and method in SceneChanger.java is static except the load() method.
This code works fine in eclipse but it doesn't work with FXLauncher
Also the .FXML files are not in any package or subpackage
Can you send me the jar of your application or point me to a public repo?
Sorry but the application is private for now I can't give it to you
I'm going to try to put the fxml files into a subpackage to see if it works
Didn't work, but its weird that there is a "!" in the exception:
javafx.fxml.LoadException:file:/C:/Users/USERNAME/AppData/Local/HosCraft/Words/Words.jar!/views/Login.fxml
Is that normal?
That's completely normal, it just shows you that it's looking for the file inside Words.jar
. If you can't share the app, please make a new app with the absolute minimum content needed to show the behavior.
Ok I will do it right now
Ok it seems like github doesn't like .zip files so I uploaded the files to dropbox: https://www.dropbox.com/s/gy6uvwrkm2v2h38/TestProjectSourcesAndJar.zip?dl=0
The archive containes the source code and a test jar. It works fine with the jar but the problem is when I try to run it with FXLauncher it doesn't work. If you want I'll try to make a launcher using fxlauncher with that file.
OK so I've tried to make a launcher for this app and it worked just fine with no problems. But why doesn't it work with the original app?
You're doing something different in your app. I would take a copy of your original app, reduce features until it looks like the sample that does work, and that should tell you where the problem lies. Hard to help when I can't see the code :)
Ok finally I've got the problem. So what I think FXLauncher does is it loads the start() method from the main class and just skips the main method. What I was doing is I was setting up some initial stuff in the main method but FXLauncher skips them so they are always null Then in my LoginController I have an initialize method that uses some stuff that I have initialized in the main method but in this case it finds them as null so it doesn't work
What can I do or is this a fxlauncher problem?
Oh and if you asked how did I found out this, I just removed some stuff from the initalize method in my LoginController and it worked fine
This is not an FXLauncher problem at all, but you need to realize that when you run with FXLauncher, you start your JavaFX application class, not a main class. The main class is not needed for JavaFX anymore either, allthough it's possible to launch it from there. In the early days of JavaFX you actually had to have a main method, but that's not the case anymore.
The correct way to deal with initialization tasks is to override the init
method of your Application
class. It is run once the Application class is loaded, and even before the JavaFX Application Thread is created.
Now I get it, Thank you :) But if it doesn't have to have a main method, how am I going to test run the app in eclipse or any IDE?
The IDE and the JVM for that matter knows how to run a JavaFX application even without a main method :) There is of course no harm in having it there, but move your initialization code to the init method and you're golden no matter how to start the app.
Let me know how it goes, I'm pretty sure even Eclipse supports to run a JavaFX App without a main method these days :)
Thanks you every thing is working great now! :) Thanks for the help and thanks for your time :D
Great! Thanks for bringing this up, I'm sure this will be an interesting read for others as well :)
I had a similar issue, and I found the fix by explicitly setting the class loader using the setClassLoader() method of FXMLLoader class. I was debugging the load() method and found out that the it was returning null when the method to get the class loader was called.
Hello again :)
So I've tried to load my .FXML files from the class path using
CLASSNAME.class.getResoure("/RESOURCENSME.fxml")
but it doesn't work and it gives me ajavafx.fxml.LoadException
when starting the launcher. I've tried to useFXMLLoader.getDefaultClassLoader().getResource("RESOURCENAME.fxml")
(without the slash) but it still doesn't work and gives mejavafx.fxml.LoadException: file:/JAR_FILE_LOCATION!/RESOURCENSME.fxml
EDIT: The "!" mark is actually there and not written by me.Thanks