0

I'm working on Java project with JavaFX using IntelliJ. My idea is separate .java file in differents folders for model-view-controller arq. To get in context, this is my project structure:

enter image description here

And each class (I've omit imports and redundant content for my issue):

  • Main.java

    public class Main extends Application {
        @Override
        public void start(Stage stage) throws IOException {
            Parent parent = FXMLLoader.load(Main.class.getResource("main-view.fxml"));
            Scene scene = new Scene(parent, 900, 500);
            stage.setTitle("Tennis Tournament!");
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch();
        }
    }
    
  • Views.java

    public class Views extends Controller implements Initializable{
    
        public Views() {
        }
    
        @Override
        public void initialize(URL arg0, ResourceBundle arg1) {
    
        }
    
        public void startTournament(ActionEvent event) throws IOException {
            this.parent = FXMLLoader.load(getClass().getResource("tournament-view.fxml"));
            //this.parent = FXMLLoader.load(getClass().getResource("tournament-view.fxml"));
            this.stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
            this.scene = new Scene(this.parent);
            this.stage.setScene(this.scene);
            this.stage.show();
        }
    
        public void salir(ActionEvent event){ System.exit(0);}
    }
    
  • TournamentController.java

    public class TournamentController extends Controller implements Initializable {
    
        @FXML
        private ChoiceBox choiceNumSets;
        private Tournament tournament;
        private Integer[] sets = {3, 5};
    
        public TournamentController(){
            tournament = new Tournament();
        }
    
        @Override
        public void initialize(URL url, ResourceBundle resourceBundle) {
            choiceNumSets.getItems().addAll(sets);
            choiceNumSets.setOnAction(this::setNumSets);
        }
    
        private void setNumSets(Event event) {
            tournament.setNum_sets((Integer) choiceNumSets.getValue());
            System.out.println(tournament.getNum_sets());
        }
    
        public void startMatch(ActionEvent event) throws IOException {
            this.parent = FXMLLoader.load(getClass().getResource("match-view.fxml"));
            this.stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
            this.scene = new Scene(this.parent);
            this.stage.setScene(this.scene);
            this.stage.show();
        }
    
        public void salir(ActionEvent event){ System.exit(0);}
    
    
    }
    
  • MatchController.java

    public class MatchController extends Controller implements Initializable {
        private Match match;
        public MatchController(){
            match = new Match();
        }
        @Override
        public void initialize(URL url, ResourceBundle resourceBundle) {
            match.setCurrentSets(1);
            System.out.println(match.getCurrentSets());
        }
        public void salir(ActionEvent event){ System.exit(0);}
    }
    
  • model-info.java

    module dux.tennis_tournament {
        requires javafx.controls;
        requires javafx.fxml;
    
        opens dux.tennis_tournament.controllers to javafx.fxml;
        exports dux.tennis_tournament.controllers;
    
        opens dux.tennis_tournament to javafx.fxml;
        exports dux.tennis_tournament;
    
    }
    
  • main-view.fxml -->

    fx:controller="dux.tennis_tournament.Views
    
  • tournament-view.fxml

    fx:controller="dux.tennis_tournament.controllers.TournamentController">
    
  • match-view.fxml

    fx:controller="dux.tennis_tournament.controllers.MatchController">
    

So as you can see, everything seems to be fine. But the problem comes when I try to open match-view.fxml from TournamentController.java. I get these errors:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
...
Caused by: java.lang.NullPointerException: Location is required.
...
at javafx.fxml@19-ea/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3196)
at dux.tennis_tournament/dux.tennis_tournament.controllers.TournamentController.startMatch(TournamentController.java:47)

where this last error is referenced to this line, in TournamentController.java

this.parent = FXMLLoader.load(getClass().getResource("match-view.fxml"));

I tried to delete "to javafx.fxml" in model-info.java, I called match-view.fxml from Main.java and everything woks fine, I also tried other similars ways to generate de Parent and even move Main.java into controllers folder, but nothing fix my problem...

I'm sure the problem is where I place the controllers, because in dux.tennis_tournament folder EVERYTHING works fine BUT if I move controllers to controllers folder, I don't get the spected results. I read it could be some module-info.java but I don't know how to figure this out. The easy solution is create ALL controllers in dux.tennis_tournament folder but this project is important to me so I want to do this in "the right way".

Gino
  • 31
  • 1
  • 1
    You're using a relative path with `getResource`, which for you will stop working when the FXML file and the controller class are no longer in the same package. The duplicate goes into more detail about this. Using an absolute path should work for you: `getResource("/dux/tennis_tournament/match-view.fxml")`. Unfortunately, since your FXML files end up in a "parent package", you can't use a relative path as the resource-lookup API does not support anything like `..`, so you're stuck with the absolute path. – Slaw Nov 20 '22 at 01:29
  • man I'm so glad. I have broked my head thinking that was something related to the project structure. Your answer works. Thank you so much BOOOOOOOOOCAA – Gino Nov 20 '22 at 02:34
  • unrelated: stick to java naming conventions (no underscores) – kleopatra Nov 20 '22 at 11:53

0 Answers0