Java 为什么在加载fxml时会出现堆栈溢出?

Java 为什么在加载fxml时会出现堆栈溢出?,java,javafx,javafx-2,fxml,Java,Javafx,Javafx 2,Fxml,我已经调整了控制器构造函数和fxml,以便除了fxml构造和fxml加载之外,控制器的所有fxml设置都在fxml中。这是我的控制器: public class MainOverviewTab extends Tab { @FXML private AnchorPane content; public MainOverviewTab() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("main_over

我已经调整了控制器构造函数和fxml,以便除了fxml构造和fxml加载之外,控制器的所有fxml设置都在fxml中。这是我的控制器:

public class MainOverviewTab extends Tab {

@FXML private AnchorPane content;

public MainOverviewTab() {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("main_overview_tab.fxml"));
    // fxmlLoader.setRoot(content);
    // fxmlLoader.setController(this);      

    try {
        fxmlLoader.load();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
和我的fxml文件:

<AnchorPane id="AnchorPane" 
    fx:id="content" 
    fx:controller="dominion.application.controller.MainOverviewTab"
    ...other settings >

        <children>
            ....
        </children>
</AnchorPane>

....

调用fxmlLoader.load()并返回fxmlLoader fxmlLoader=new fxmlLoader(…),然后再次调用fxmlLoader.load()时,会发生堆栈溢出。。。为什么会发生这种情况?我如何保持我的控制器构造函数不变并加载相同的fxml?或者这是不可能的?

您不应该在构造函数中调用FXml加载程序。因为当您使用fxml加载程序加载fxml文件时,它会一次又一次递归地创建MainOverview选项卡。因此会导致堆栈溢出错误。如果您从构造函数中删除代码并从显式方法中调用,它将起作用

public static void mainTabLoader() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("main_overview_tab.fxml"));
    // fxmlLoader.setRoot(content);
    // fxmlLoader.setController(this);      

    try {
        fxmlLoader.load();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

如果在FXMLLoader实例上调用setController(…),则不应在FXML文件中指定控制器。从FXML文件中删除fx:controller属性,并取消对setRoot(…)和setController(…)调用的注释,它应该可以工作。

当控制器构造函数尝试使用fx:controller属性加载FXML并命名时,会发生这种情况,它会无限递归。我去过那里。。。巧妙地使用fxmlLoader.setControllerFactory(factoryObject)可以解决这个问题


有关在根元素中保留fx:controller属性的基于FXML的控件,请参见my,这可以适用于其他控制器的创建。

可能有帮助。在这种情况下,不需要setRoot和setController调用。但是,当我取消对setRoot和setController的注释并删除fxml中的这些属性时,它会起作用。如果fxml中没有fx:controller属性,FXMLLoader的load(…)方法将不会实例化控制器。所以删除属性会破坏无限递归。但是我在构造函数中注释掉的行是我想要删除的。我还希望将属性保留在FXML文件中,我希望所有这些都不会出现异常。在这种情况下,您应该将FXML的加载移出控制器类。通常,这将在应用程序子类的start(…)方法中完成,但如果您使用多个FXML,则可能在其他地方完成。load(…)方法解析FXML文件,查看fx:controller属性,实例化控制器,并调用其initialize()方法。如果在构造函数(或initialize()方法)中使用相同的FXML文件调用fxmlLoader.load(…),则最终会出现无限递归。