加载 FXML 文件时,它的关联控制器也会加载



我已经为ScreenController类(由每个屏幕的单个控制器类扩展的类(创建了一个解决方案,该类将处理应用程序中的基线屏幕层次结构。

在我的类中,我使用一个函数将另一个 FXML 文件的内容(加载(到当前控制器的当前锚窗格中。

我的问题是:

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 使用的类(或者更确切地说,特定控制器(是否也实例化/加载?

如果在 FXML 文件的根元素中有fx:controller属性,那么是的,将创建指定控制器类的新实例(默认情况下(。FXML 文件描述的所有对象也是如此。换句话说,每次加载 FXML 文件时,FXMLLoader都会返回根和控制器的新实例。可以通过在FXMLLoader上设置自定义controllerFactory来自定义控制器实例的创建方式。

如果没有fx:controller属性,则要么没有控制器实例,要么需要以编程方式指定一个控制器实例。在这种情况下,您可以手动提供控制器实例。

注:切勿在不同的 FXML 文件之间共享控制器类,也不要在不同负载之间共享控制器实例。这样做会引起各种混乱,并且不必要地复杂。也就是说,拥有一个共同的抽象类可能是合适的,只要它只具有每个子类共有的状态和行为。


2(这样做时,如果新的FXMl的类被实例化/加载,以前的FXML的类是从内存中释放的?还是仍在使用内存。

如本答案开头所述,FXMLLoader只是解释 FXML 文件并创建适当的对象图1。完成此操作后,创建的对象会发生什么取决于您。只要任何线程都可以强烈访问对象,它们就不会被垃圾回收。

如果您问重用FXMLLoader实例会发生什么,我不完全确定,因为我从未尝试过。可以说,我建议每次要加载 FXML 文件(或使用静态load(URL)方法(时创建一个新的FXMLLoader实例。


1. 创建对象图后,如果存在控制器,则FXMLLoader还将注入任何适当的字段并"链接"所有适当的方法。

这取决于您如何使用 FXMLLoader。有静态和非静态加载方法,也有可以提供控制器实例的方法。最好在 FXMLLoader 类文档中查看各种加载方法。

最新更新