If I have a JavaFX project that uses FXML, how would I structure it to adhere to the Model-View-Controller pattern? This is what I would assume the general structure to be like:
Model - Underlying program (what the GUI is representing).
View - FXML file.
Controller - FXML controller.
The issue with this representation is that the view cannot be notified of the model's changes, as it is simply an FXML file. Should the view be the FXML controller class, and then should I have a main controller class such that the FXML controller gets information from the model, and the main controller handles the action events? In this case, how would the main controller access the JavaFX nodes?
Also, in an MVC pattern, where should the main method be? Right now, It is in my JavaFX Application class, which then does nothing for the remainder of the program. Also, should the JavaFX Application class be part of the MVC pattern, or is it only necessary to initialize the GUI?
Summary of questions (please read the full post though):
- How do I structure my JavaFX project which uses FXML to adhere to the MVC pattern? Should the view be the FXML controller class, and then should I have a main controller class such that the FXML controller gets information from the model, and the main controller handles the action events?
- In an MVC pattern, where should the main method be?
- Should the JavaFX Application class be part of the MVC pattern, or is it only necessary to initialize the GUI?
In my opinion it is not very helpful if everybody who starts with JavaFX first tries to invent his own scheme of implementing one of the variants of MVC. Instead one should pick one of the many already existing application frameworks (for JavaFX), try to understand it and then strictly follow the guidelines of this framework to build an application. My personal favorite is mvvmFX but of course you could also use one of the others like AfterburnerFX. Studying and using such a framework would answer many of the constantly asked questions here on SO.
Both JavaFX and Swing push towards tight coupling between the View and the Controller, with the justification that making a generic Controller is difficult. However, MVC itself has a few interpretations so it's all a bit vague.
Given this justification on the tight coupling of the View and Controller, you have some options. I'll suggest two and maybe others can add or even disagree.
1) Accept that the View class is just a dummy for loading the FXML file, setting the
Scene
andStage
and so making theFXMLController
class observe the model and update the view.This limits the Controller to JavaFXML applications, meaning it can't easily be interchanged with Swing for instance. Although changing the View is quick and simple as long as it refers to the correct Controller and all onAction or equivalent Node attributes use the same reference.
2) Don't use the skeleton code provided. Instead make the View load the FXML file and access Nodes manually, additionally removing the
fx:controller
attribute from your FXML file andonAction
attributes from the relevant Nodes in the FXML file.You can then access any
Node
as needed from the FXML in the View, e.g.This gives you the advantage or specifying your own generic controller, and allows the View class to observe the model itself.
At the end of day, the most important thing is to seperate the Model from the View and Controller, since the Model is meat of the program. Smart Model, Thin Controller, Dumb View
Doesn't matter. However, a JavaFX application doesn't strictly need a
main
method if the JAR created is done so by the JavaFX Packager Tool, and it instead useslaunch
as the entry point. You could however use themain
method as an entry point in a separate class and callApplication.launch(MyJavaFXApplicationClass.class);
instead.Yes, as it is part of the View. See the two methods I mentioned above.