Reputation: 664
I've recently decided to start using JavaFX but I seem to have run into an issue. My elements won't show when I run the application. I Googled around, but from what I found out, my code is either OK or people seem to create their elements programmatically, which I don't want to do. I just want to use the ScreenBuilder for design.
This is my main
:
package ParolaPM;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
primaryStage.setTitle("Parola PM");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This is my controller:
package ParolaPM;
import javafx.fxml.FXML;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
public class Controller {
@FXML
public AnchorPane ancPane;
@FXML
public ImageView imgLogo;
@FXML
public void initialize() {
}
}
And this is the fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="ancPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="327.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ParolaPM.Controller">
<children>
<ImageView fx:id="imgLogo" fitHeight="150.0" fitWidth="200.0" layoutX="21.0" layoutY="50.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../resources/lock.png" />
</image>
</ImageView>
</children>
</AnchorPane>
As you can see in the image below, on line 9 and 11 I have that little icon, which means that the controller detects the elements in the fxml
file and when I click them, it also directs me to those elements in that file.
I'm fairly new to this, so I really don't know what I've done wrong. In my current app, I only have an image, but when I run it, nothing shows, as seen in the image below.
Another interesting thing is that if my @FXML
elements in the Controller
are private
instead of public
, they're grayed out.
I've been struggling with this for days. I'd really appreciate any help!
EDIT:
Thanks to c0der, it works with links. I think I've identified the core of the problem.
If you select an image via the ScreenBuilder, it has a little @
sign, which goes into the code <Image url="@../../resources/lock.png" />
.
So, the correct URL, from my programming experience, should not have @
, BUT if you delete it, the program throws IllegalArgumentException
. Basically, if it's there, it doesn't show the image, if it's not, shows error.
I also tried to write it manually. With/without the <Image></Image>
. A bunch of different combinations of the last two with and without the @
and it doesn't work. At least links work, but it should not be like this. I think I'll submit this as a bug if I don't find what's wrong with it and why it's like this.
EDIT 2:
I seem to have been incorrect about the @
. According to the official documentation link I found in this thread, the @
is used to specify the relative to the fxml
file path. Therefor, it should be working. Interesting...
EDIT 3:
Max's solution in this thread seems to work as well. Selecting the "gear" next to the path in the SceneBuilder and choosing the "absolute path" option. In the fxml
file, the path will then look like <Image url="file:/home/user/IdeaProjects/App/resources/lock.png" />
. Unfortunately, the relative path solution in the same thread, does not seem to work.
The problem with this is, from my knowledge, if I use the absolute one, once I launch the app on another machine, it will not load the image.
EDIT 4:
Found a solution for relative path.
The image folder MUST be in the src/Application
folder. You can then select it from the SceneBuilder, leaving it with the relative path option selected, and the image will show in the Builder AND when the application is ran.
Structure:
SceneBuilder:
Then the FXML image code will automatically be written as: <Image url="@img/lock.png" />
Upvotes: 0
Views: 2199
Reputation: 18792
I removed fx:controller="ParolaPM.Controller
from fxml and tested with
<Image url="http://www.digitalphotoartistry.com/rose1.jpg" />
(It is always a good idea to test with a path that was tested before) - it worked fine.
You must be getting exceptions.
(It should work with the controller as well because it does not do anything)
Upvotes: 1