WHAT I HAVE is a standard JavaFX application: Main.java, MainController.java & main.fxml
. To add custom component, I created CustomComponentController.java
and custom_component_controller.fxml
.
PROBLEM is that in CustomComponentController
methods I need to reference other methods and standard components from MenuController
. I add public static MainController mc;
to MainController
class body, so that it can be seen from CustomComponentController
(MainController.mc.neededMethod()
). Then I try to pass everything to it in MainController.initialize()
method (mc = this;
) - when debugging this breakpoint, I see this
full of components instances, but mc
remains with null components afterwards.
QUESTION is how to reference the running instance of MainController
to use its components and methods in other classes and to crossreference different custom components from each other? How to clean MainController
code from event handlers and assistance methods of components by moving it all to component's own class?
I tried the following approaches, but found no way to make them work without errors:
Accessing FXML controller class
How can I access a Controller class in JavaFx 2.0?
JavaFX 2.0 + FXML. Updating scene values from a different Task
JavaFX 2.2 -fx:include - how to access parent controller from child controller
The problem can be solved if you comply the following conditions:
Not only public, but obligatory static
MainController mc
should be.Do not forget id in fxml for CustomComponentController:
<CustomComponentController fx:id="cc"/>
, where cc is the name of the "@FXML imported" CustomComponentController in your MainController class.Omit parameter
fx:controller="main.CustomComponentController"
incustom_component_controller.fxml
as it results in "Controller value already specified" error (a conflict betweenmain.fxml
andcustom_component_controller.fxml
markup declared controllers).Put
mc = this;
in the beginning ofMainController
'sinitialize()
method. Before usingmc
in CustomComponentController class, check if it's not null. It can be null when all components, includingCustomComponentController
, are instantiated at application startup, but there is no mc instance yet. MainController methodinitialize()
where MainController is instantiated is called after components are loaded. Therefore better practice is to use approach in the next paragraph.In
main.fxml
create primary component of the same type thatCustomComponentController
and with the onlyfx:id
parameter. Replace primary component with yourCustomComponentController
by creatingreloadCustomComponents()
method and calling it fromCustomComponentController
'sinitialize()
method. Do it by adding the following toreloadCustomComponents()
method:customComponentAnchorPane.getChildren().remove(customComponent);
customComponent = new customComponent();
customComponentAnchorPane.getChildren().add(customComponent);
Thus all components can be placed outside
CustomComponentController
with all their methods and reloaded at the startup of the apllication. All component declarations stay inMainController
class and can be reached throughMainController mc
reference. No duplicate creating of components in detail with parameters is needed.Your problem looks like the classic catalog-crud forms updating, I implemented an interface that I called
Updatable
with anupdate method
so I could reference any catalog form with any crud form easy after passingController Main Class
as theUserData Property
of the Child Root Component's FormHope it Can Solve your problem