java - 加载 FXML 文件时,是否也加载了关联的控制器
问题描述
我为 ScreenController 类(由每个屏幕的各个控制器类扩展的类)创建了一个解决方案,它将处理我的应用程序中的基线屏幕层次结构。
在我的课程中,我使用一个函数将另一个 FXML 文件的内容添加(加载)到当前控制器的当前 AnchorPane 中。
我的问题是:
1)当新的 FXML 被加载时,FXML 使用的类(或者更确切地说,特定的控制器)是否也被实例化/加载?
2) 这样做时,如果新的 FXMl 的类被实例化/加载,之前的 FXML 的类是否从内存中释放?还是它仍在使用内存。
屏幕转换代码:
public void setScreen(String screen) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource(screen));
window.getChildren().setAll(root);
}
解决方案
理解这FXMLLoader
不是一个框架,尽管它可以用作框架的基础。没有容器可以管理控制器类的实例或加载的根。FXMLLoader
由应用程序代码确定的对象会发生什么。
FXML 文件只是描述对象图的 XML 格式的文本文件。FXMLLoader
简单地解释该文件并创建所述对象图1。当然,FXML 格式有一些特别添加的语法来处理 JavaFX 特定的功能(例如添加事件处理程序、绑定等)。
1)当新的 FXML 被加载时,FXML 使用的类(或者更确切地说,特定的控制器)是否也被实例化/加载?
如果您fx:controller
在 FXML 文件的根元素中有一个属性,那么是的,会创建一个指定控制器类的新实例(默认情况下)。FXML 文件描述的所有对象也是如此。换句话说,每次加载 FXML 文件时,FXMLLoader
都会返回根和控制器的新实例。控制器实例的创建方式可以通过controllerFactory
在FXMLLoader
.
如果您没有fx:controller
属性,那么要么没有控制器实例,要么您需要以编程方式指定一个。在这种情况下,您需要手动提供控制器实例。
注意:永远不要在不同的 FXML 文件之间共享一个控制器类,也不要在不同的负载之间共享一个控制器实例。这样做会引起各种混乱,而且不必要地复杂。也就是说,拥有一个公共抽象类可能是合适的,只要它只具有每个子类共有的状态和行为。
2) 这样做时,如果新的 FXMl 的类被实例化/加载,之前的 FXML 的类是否从内存中释放?还是它仍在使用内存。
如本答案开头所述, anFXMLLoader
只需解释 FXML 文件并创建适当的对象图1。一旦这样做,创建的对象会发生什么取决于您。只要对象可以被任何线程强烈访问,它们就不会被垃圾收集。
如果您问如果重用FXMLLoader
实例会发生什么,我不完全确定,因为我从未尝试过。可以这么说,我建议FXMLLoader
您每次要加载 FXML 文件(或使用静态load(URL)
方法)时都创建一个新实例。
1.创建对象图后,如果存在控制器,则FXMLLoader
还将注入任何适当的字段并“链接”所有适当的方法。
推荐阅读
- python - 函数调用和函数中的代码给出不同的结果
- ios - 如何显示带有大标题的UITabbar
- wso2esb - 发送消息时出现意外错误 - 错误 {org.apache.synapse.core.axis2.Axis2Sender}
- extjs - 使用 extjs 应用程序中的语言下拉更改标签
- jquery - 如何从循环表索引中传递值并显示到输入框中
- python - 使用 core.Token 将字符串参数作为数字传递
- postgresql - 如何将现有的 postgres 数据文件夹复制并使用到 docker postgres 容器中
- mmenu - 将带有递归搜索的搜索字段添加到子面板(类似于带有导航栏的固定搜索字段)
- amazon-web-services - AWS Route53 将请求转发到子域
- solidity - Require() 函数在下面的代码中无法正常工作