0

I've got a part of code, which contains all objects of controllers which I've been using in my program. The topButtonsController is the only one injected from FXML file (fx:include), the others are created by myself.

I recon that initialize() method is invoked after the constructor of MainController in created, so assuming that all the methods from the initialize() methods should have do their job firstly.

public class MainController {
   @FXML
   private TopButtonsController topButtonsController;

   private AddNewOrderController addNewOrderController = new AddNewOrderController();

   private OrdersController ordersController = new OrdersController();

   @FXML
   private BorderPane borderPane;

   @FXML
   public void initialize() {
       topButtonsController.setMainController(this);
       addNewOrderController.setMainController(this);
       ordersController.setMainController(this);
       System.out.println("Finished injection");    
   }
}

Here I've got a class of controller for another FXML file. After pressing the button the acceptButtonClicked method should invoked, but unfortunately the mainController is Null! Why it is so if I've already set him to a value in MainController initialize method, that should have been hit first.

public class AddNewOrderController {

   private MainController mainController;

   @FXML
   private TextField nameOfPizzaTextField;

   private ArrayList<Order> arrayList = new ArrayList<Order>();

   private ObservableList<Order> observableList = FXCollections.observableArrayList(arrayList);

   @FXML
   private Button acceptButton;
   @FXML
   void acceptButtonClicked(ActionEvent event) {
       if(mainController == null) {
           System.out.println("MainController is null!!"); //it is printed, why?
       }

       Order order = new Order(nameOfPizzaTextField.getText());
       arrayList.add(order);
       observableList.add(order);
       System.out.println("Dodano "+nameOfPizzaTextField.getText()+"do listy");
       System.out.println(observableList);
       mainController.getOrdersController().getListView().setItems(mainController.getAddNewOrderController().getObservableList()); // here occurs error

   @FXML
   public void initialize() {
   }

   public void setMainController(MainController mainController) {
       this.mainController= mainController;
   }
}
nickb
  • 59,313
  • 13
  • 108
  • 143
  • The `acceptButtonClicked` method looks like a handler method that is invoked on the controller for the FXML file. You are calling `setMainController` on an instance of `AddNewOrderController` that you create "by hand": that is not the controller. You need to call `setMainController` on the actual controller that is instantiated when the corresponding FXML file is loaded. – James_D Jul 17 '17 at 14:58
  • Okey I understand that i miss the idea of which controller i get. So how can I achive getting right controller. Is it by the FXMLLoader class? FXMLLoader loader = FXMLLoader(..); loader.getController() ? – MichaelKorf2 Jul 17 '17 at 15:32
  • You have to get the controller when you load (and display) the FXML file. (Call `getController()` *after* calling `load()`). – James_D Jul 17 '17 at 15:40
  • I still dont get it. If I do so I will let know other controller that there are others controller (because I need to create such field in other files) E.g I load all my fxml files in TopMenuButtonsController so I need to create there 3 additional fields with instance of controllers and than how to pass it to another files? I want only mainController to know that more controllers exist. Do you have any ready app or example which emphasise problem ? – MichaelKorf2 Jul 17 '17 at 16:14
  • I don't really understand how you are trying to organize the application. If your `TopMenuButtonsController` is loading the FXML files, it needs to do any necessary initialization on the corresponding controllers. The FXML file and controller work as a fairly tightly-coupled pair: if the `TopMenuButtonsController` is loading the FXML files, then it is really already implicitly creating the controllers too. – James_D Jul 17 '17 at 16:18
  • I usually avoid controllers communicating with each other entirely, and prefer a MVC approach, so you share a single model instance with all the controllers. E.g. https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx – James_D Jul 17 '17 at 16:20
  • Or perhaps, since `TopMenuButtonsController` has a reference to the main controller, you should move the code for loading and displaying the other FMXL files to the main controller (which might be a more natural place for it), and then just invoke methods on the main controller to load those FXML files from the `TopMenuController`. Again, there's not really enough information in your question to understand what you are trying to do. – James_D Jul 17 '17 at 16:25

0 Answers0