1

I have a spring javafx app which uses Spring JPA and MySQL. The method changeScene in ViewUtils class should swap from Login form to Admin, but after I introduced the username & password, I got this error: Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Location is not set.

For both fxml files I am using BorderPane and I specified the controller used for each one

admin-view.fxml => AdminController.java

login-view.fxml => LoginController.java

public class ViewUtils {
    public void changeScene(ActionEvent event, String fxml) {
    
        Parent root = null;
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(ViewUtils.class.getResource(fxml));
            root = fxmlLoader.load();
            Scene scene = new Scene(root);
    
            Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
            stage.setScene(scene);
            scene.setFill(Color.TRANSPARENT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        stage.setScene(new Scene(root, 800, 600));
        stage.show();
    }
}

I am using this method changeScene in LoginController:

@Controller 
public class LoginController {
    @FXML private Label wrongLoginLabel;
    @FXML private TextField usernameTextField;
    @FXML private PasswordField passwordPasswordField;
    @FXML private Button loginButton;
    
    private AdminController adminController;
    private Scene adminScene;
    String username, password;

    @FXML
    public void userLogin(ActionEvent actionEvent) throws IOException {
        username = usernameTextField.getText();
        password = passwordPasswordField.getText();
    
        ViewUtils viewUtils = new ViewUtils();
    
        if(isValidCredentials(username, password)) {
            loginButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent actionEvent) {
                    viewUtils.changeScene(actionEvent, "admin-view.fxml");
                }
            });
        } else if(username.isEmpty() && password.isEmpty()) {
                wrongLoginLabel.setText("Please enter your data.");
        } else {
            clearFields();
            wrongLoginLabel.setText("Wrong username or password!");
        }
    }
}

login-view.fxml looks like that:

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #4fadb0; -fx-border-color: #ffc900;" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.app.demo.controller.LoginController"> <left> <AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER"> <children> <ImageView fitHeight="412.0" fitWidth="210.0" layoutX="57.0" layoutY="59.0" pickOnBounds="true" preserveRatio="true"> <image> <Image url="@../img/image1.png" /> </image> </ImageView> </children> </AnchorPane> </left> <center> <AnchorPane prefHeight="400.0" prefWidth="335.0" BorderPane.alignment="CENTER"> <children> <ImageView fitHeight="60.0" fitWidth="92.0" layoutX="137.0" layoutY="39.0" pickOnBounds="true" preserveRatio="true"> <image> <Image url="@../img/image2.png" /> </image> </ImageView> <Label layoutX="32.0" layoutY="155.0" text="Username" textFill="#ffc900"> <font> <Font name="System Bold" size="20.0" /> </font> </Label> <Label layoutX="35.0" layoutY="211.0" text="Password" textFill="#ffc900"> <font> <Font name="System Bold" size="20.0" /> </font> </Label> <TextField fx:id="usernameTextField" layoutX="146.0" layoutY="158.0" promptText="Username" /> <PasswordField fx:id="passwordPasswordField" layoutX="146.0" layoutY="214.0" promptText="Password" /> <Button fx:id="loginButton" layoutX="130.0" layoutY="298.0" mnemonicParsing="false" onAction="#userLogin" prefHeight="33.0" prefWidth="74.0" style="-fx-background-color: #ffc900;" text="Login" /> <Label fx:id="wrongLoginLabel" layoutX="146.0" layoutY="250.0" textFill="#ff622e"/> </children> </AnchorPane> </center> </BorderPane>

AdminController and admin-view.fxml are similar to above files.

SpringApplication class:

@SpringBootApplication public class SpringJavaFXApplication extends Application {
    
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/app/demo/login-view.fxml"));
    
            Parent root = fxmlLoader.load();
            Scene scene = new Scene(root);
            scene.setFill(Color.TRANSPARENT);
    
            primaryStage.initStyle(StageStyle.TRANSPARENT);
            primaryStage.setScene(scene);
            primaryStage.setTitle("Login");
            primaryStage.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

I found out that FXWeaver is used for spring JavaFX app, so I tried to follow this tutorial for FXWeaver: https://rgielen.net/posts/2019/creating-a-spring-boot-javafx-application-with-fxweaver/ but for some reason FXWeaver object is not recognized in java classes and neither the @FXMLView annotation for controllers. The dependency from pom.xml looks fine. I do not know if this could be a solution for my problem, but I will continue to read more about fxweaver in the meantime.

Also, I tried the solution from here: https://stackoverflow.com/questions/51128560/java-lang-illegalstateexception-location-is-not-set but it did not work.

Can anyone help me with this error? Thanks in advance!

  • 3
    There are quite a lot of issues here. Resource loading, is documented in: [How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?](https://stackoverflow.com/questions/61531317/how-do-i-determine-the-correct-path-for-fxml-files-css-files-images-and-other), the [Eden resource guide](https://edencoding.com/where-to-put-resource-files-in-javafx/) and [How to reference javafx fxml files in resource folder?](https://stackoverflow.com/questions/19602727/how-to-reference-javafx-fxml-files-in-resource-folder) – jewelsea Jul 18 '23 at 17:55
  • I think the resources are correctly https://github.com/madaOprea/petcomplet – Mădălina Oprea Jul 18 '23 at 21:22

1 Answers1

0

+1 for what @jewelsea mentioned in the comment. Please do follow the links in the comment.

But on a quick glance of your code and the git repo you provided, I think the below reason could be one of the issue.

In the SpringJavaFXApplication class you loaded the FXML file by providing the full path of the file, which is working fine when you started the application.

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/app/demo/login-view.fxml"));

But when you need to change the scenes, you just provided only the file name and expecting the ViewUtils to pick the file from getResource() method. Technically it will try to fetch the fxml in com/app/petcomplet/utils folder in the resources. And this is not how you defined and thus getting the Location is not set error.

As a starting point, I would rather try to provide a correct resource from controller to the ViewUtils class something like below:

In LoginController:

loginButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
        viewUtils.changeScene(actionEvent,"/com/app/petcomplet/admin-view.fxml");
    }
});

Also I didn't get why you loaded the Stage twice in the ViewUtils -> changeScene method

Sai Dandem
  • 8,229
  • 11
  • 26
  • I tried your solution but it did not work. I still have the same issue loginButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent actionEvent) { viewUtils.changeScene(actionEvent, String.valueOf(getClass().getResource("/com/app/petcomplet/admin-view.fxml"))); } }); – Mădălina Oprea Jul 19 '23 at 05:53
  • Sorry my bad... there is typo issue. I updated it. Use the string.. not with getClass().getResource() – Sai Dandem Jul 19 '23 at 06:33
  • After I updated and removed the target folder I get this error every time: javafx.fxml.LoadException:/Users/myuser/.../target/classes/com/app/petcomplet/admin-view.fxml:12 javafx.fxml@20/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2722)...Caused by: java.lang.NoSuchMethodException: com.app.petcomplet.controller.AdminController.() at java.base/java.lang.Class.getConstructor0(Class.java:3685) at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2854) javafx.fxml@20/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:941) – Mădălina Oprea Jul 19 '23 at 11:44