Search code examples
javaeclipsejavafxfxmlscene

How do I load an FXML file from another project using JavaFX in eclipse?


I have two projects: "Game" and "Game Library" - Game has a build path to the Game Library project. In Game Library, I have a method that switches the scene when Game requests it.

The scene switch method in Game Library project:

package gamelibrary;

public class SceneSwitcher{

    public Stage window;
    public Parent root;

    public void switchSceneFXML(String FXMLLocation) throws Exception{

        try{

            window = (Stage) node.getScene().getWindow();

        }catch(Exception e){

            e.printStackTrace();

        }

        root = FXMLLoader.load(getClass().getResource(FXMLLocation));

        window.setScene(new Scene(root));
        window.show();

    }
}

I call this method in Game project:

package game;

import gamelibrary.sceneSwitcher;

public class firstWindowController{

    public void buttonHandler(ActionEvent event){

        SceneSwitcher scene = new SceneSwitcher();

        if(event.getSource().equals(playButton){

            scene.switchScene("/game/SecondWindow.fxml");

        }

    }

}

So when I click the playButton in the FirstWindow.fxml, FirstWindowController in Game project will call the switchSceneFXML method in Game Library project.

I get this error:

java.lang.NullPointerException: Location is required.

at

root = FXMLLoader.load(getClass().getResource(FXMLLocation));

at

scene.switchSceneFXML("/game/SecondWindow.fxml");

Is there something i'm missing? How can I make switchSceneFXML method know to look for the package and file in Game project and not Game Library project?

I am trying to make switchSceneFXML method reusable with other FXML files so that I dont have to copy and paste code alot and would prefer a way that will allow me to write once and reuse.

I have looked around alot for an answer but I havent been able to fully grasp the concept in other peoples situations. Thanks for the help!


Solution

  • I am trying to make the switchSceneFXML method reusable for more than just on FXML. Is there a way I can get the name of the class automatically? – Chris

    Then you should have the various classes load their FXML themselves. You could Do this by using the JVMs ServiceLoader

    in gane lib:

    interface FxmlController{
      boolean isPrividingScene(String nextSceneIdOrName);
      String getFXMLLocation();
    }
    
    
    public class SceneSwitcher{
        public Stage window;
        public Parent root;
       private static ServiceLoader<FxmlController> sceneControllers
         = ServiceLoader.load(FxmlController.class);
        public void switchSceneFXML(String nextSceneIdOrName) throws Exception{
            try{
                window = (Stage) node.getScene().getWindow();
                for(FxmlController controller : sceneControllers){
                   if(controller.isPrividingScene(nextSceneIdOrName)){ // however you want to select the next scene...
                     FXMLLoader fxmlLoader = new FXMLLoader();
                     fxmlLoader.setController(controller);
                     root = fxmlLoader.load(controller.getClass().getResource(controller.getFXMLLocation()));
                     window.setScene(new Scene(root));
                     window.show();
                   }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    

    This way each FxmlController can (but does not need to) live in its own jar file having its own relative path to the FXML file.