JavaFx: how to reference main Controller class instance from CustomComponentController class?

主宰稳场 提交于 2019-12-01 10:52:21

问题


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


回答1:


The problem can be solved if you comply the following conditions:

  1. Not only public, but obligatory static MainController mc should be.

  2. 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.

  3. Omit parameter fx:controller="main.CustomComponentController" in custom_component_controller.fxml as it results in "Controller value already specified" error (a conflict between main.fxml and custom_component_controller.fxml markup declared controllers).

  4. Put mc = this; in the beginning of MainController's initialize() method. Before using mc in CustomComponentController class, check if it's not null. It can be null when all components, including CustomComponentController, are instantiated at application startup, but there is no mc instance yet. MainController method initialize() where MainController is instantiated is called after components are loaded. Therefore better practice is to use approach in the next paragraph.

  5. In main.fxml create primary component of the same type that CustomComponentController and with the only fx:id parameter. Replace primary component with your CustomComponentController by creating reloadCustomComponents() method and calling it from CustomComponentController's initialize() method. Do it by adding the following to reloadCustomComponents() 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 in MainController class and can be reached through MainController mc reference. No duplicate creating of components in detail with parameters is needed.




回答2:


Your problem looks like the classic catalog-crud forms updating, I implemented an interface that I called Updatable with an update method so I could reference any catalog form with any crud form easy after passing Controller Main Class as the UserData Property of the Child Root Component's Form

Hope it Can Solve your problem



来源:https://stackoverflow.com/questions/17550578/javafx-how-to-reference-main-controller-class-instance-from-customcomponentcont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!