Scenario
I am creating a GUI where multiple views reference the same model object.
What I am Accustom to
In Swing, if i want all the views to reference the same model i would pass the model into the constructor.
What I am Currently Doing
In JavaFX, I am passing the model around by having a setter method in the views/controllers (menubars, split panes, tabs, ...), after each view/controller has been loaded. I find this very tacky and cumbersome. Additionally, I find it won't work because in certain situations i need the model to already exist in a controller before some of the controller widgets are initialized.
Lackluster Alternatives
(Note: I am referencing these stackoverflow questions:
- Javafx 2.0 How-to Application.getParameters() in a Controller.java file
- Passing Parameters JavaFX FXML
- Multiple FXML with Controllers, share object
Dependency Injection
- I've looked at this website, http://www.zenjava.com/2011/10/23/javafx-2-0-fxml-and-spring/, and i have looked a little into google Guice, but I don't see a way of simplistically giving each JavaFX view/controller the same model object. It seemed like the injection would inject a different model for each view/controller.
Saving the model object as a public static variable
- This is an option but at the moment I don't like the idea of having a public static model so open and available. Obviously, I can make it a private static variable and have getters and setters, but i don't like this idea much either.
Passing Parameters from Caller to Controller
I want each controller to load itself in its constructor, and I want each custom controller to be automatically injected into its parent controller. For example, the card overview tab loads itself like this:
public CardOverviewTab() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("card_overview_tab.fxml")); fxmlLoader.setRoot(content); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (Exception e) { e.printStackTrace(); } }
And the SingleGameSetup controller has the card overview tab automatically injected into a variable:
public class SingleGameSetupController extends AnchorPane { @FXML private CardOverviewTab cardOverviewTab; // Rest of the class }
And the part of the fxml containing the card overview tab looks like this:
<CardOverviewTab fx:id="cardOverviewTab" />
This way I do not need to worry about manually loading a controller, but I still have the problem of setting the model.
Setting a Controller on the FXMLLoader
- This option is similar to what I am accustom to, passing the model as a parameter into the constructor, but it still has the problem of loading controllers manually with the FXMLLoader.
Event Bus
- I haven't read too much into this, but from what I have read the event bus seems to be inactive and outdated.
Singleton
- This is similar to having a public static reference to the model object that controllers can retrieve, but again I am looking for a better solution. Plus, I do not want a singleton model.
What I am Looking for
Is there a way to pass the model object around in a less cumbersome way? I am looking for a way that is as simple as passing the model to a constructor, but I do not want to deal with manually loading controllers via the FXMLLoader, or setting the model after the controllers are loaded. Maybe having a class to retrieve the model is the best option, but I am asking just in case there is a better way.