来自不同FXML文件的@ FXML-annotated组件导致NPE [英] @FXML-annotated components coming from different FXML files resulting in NPE

查看:97
本文介绍了来自不同FXML文件的@ FXML-annotated组件导致NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个FXML文件。第一个窗口描述了要显示的第一个窗格,其中包含选项卡窗格,菜单和菜单项,它应该在选项卡窗格中打开一个新选项卡并在其中绘制一组新的节点。
这是代码:

I have two FXML files. The first describes the first pane to show up, which contains a tab pane, a menu and a menu item, which is supposed to open a new tab in the tab pane and draw a new set of Nodes in it. This is the code:

public class Main extends Application {

private Pane mainRoot;
private Pane secondaryRoot;

@Override
public void start(Stage primaryStage) {
    try {
        mainRoot = (Pane) ResourceLoader
                .load("MainFXML.fxml");

        secondaryRoot = (Pane) ResourceLoader.load(("SecondaryFXML.fxml"));

        Scene scene = new Scene(mainRoot);

        primaryStage.setScene(scene);
        primaryStage.show();

        thisMain = this;

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    launch(args);
}

private static Main thisMain;

public static Main getMain() {
    return thisMain;
}
public Pane getSecondaryRootPane() {
    return secondaryRoot;
}

然后我有一个与两个FXML文件相关联的控制器。因此,它将选项卡窗格作为FXML注释字段。此外,它处理菜单项上的click事件,该事件是创建新选项卡的事件:

Then I have a single controller associated to both FXML files. So, it has the tab pane as a FXML-annotated field. Furthermore, it handles the click event on the menu item, which is the one creating the new tab:

public class GUIController {
@FXML
private TabPane tabPane;

public void newTabRequest(Event e) {
    // create the new tab
    Tab newTab = new Tab("New tab");

    // set the content of the tab to the previously loaded pane
    newTab.setContent(Main.getMain().getSecondaryRootPane());

    // add the new tab to the tab pane and focus on it
    tabPane.getTabs().add(newTab);
    tabPane.getSelectionModel().select(newTab);

    initializeComboBoxValues(); // HERE I HAVE A PROBLEM
}}

控制器的最后一行调用一个方法,其代码如下:

Last line of the controller invokes a method, whose code is as follow:

private void initializeComboBoxValues() {
    myComboBox.getItems().add(MyEnum.myEnumValue1);
    myComboBox.getItems().add(MyEnum.myEnumValue2);
}

我有一个字段@FXML ComboBox与相应的组件同名在FXML中声明并且我正在尝试填充值。
问题是myComboBox结果为null。我哪里错了?我在哪里设计错了?

and I have a field @FXML ComboBox having the same name as the corresponding component declared in the FXML and that I am trying to fill up with values. The issue is that myComboBox results null. Where am I wrong? Where am I designing it wrong?

如果它可以提供帮助,我想说明一点:我在新标签页面中创建并添加了一个测试按钮。与此按钮关联的事件将调用相同的initializeComboBoxValues方法。好吧,这是有效的(给定我从newTabRequest处理程序中删除它的调用,以避免NPE)。

If it can help, I want to make this point: I created and added a test button in the new tab. The event associated to this button invokes the same initializeComboBoxValues method. Well, that works (given I remove its invocation from the newTabRequest handler, so to avoid the NPE).

推荐答案

每次你使用 FXMLLoader ,您创建一个新的控制器。由于您没有做任何事情来连接两个控制器,因此每个控制器只有 @FXML 带注释的字段集,它们在它自己的窗格中当它被夸大时。

Every time you use FXMLLoader, you create a new controller. Since you don't do anything to connect both controllers, every controller has only the @FXML annotated fields set, that were in it's own Pane at the time it was inflated.

你必须在两个控制器之间建立某种通信才能使它工作。

You'll have to establish some kind of communication between both controllers to get it working.

如果您使用 FXMLLoader的实例 FXMLLoader 获取控制器$ c>和非静态加载函数,例如像这样(不要重复使用 FXMLLoader 来加载第二个fxml文件):

You can get the controller from the FXMLLoader, if you use a instance of the FXMLLoader and a non-static load function, e.g. like this (don't reuse a FXMLLoader to load a second fxml file):

FXMLLoader loader = new FXMLLoader();
// be sure to use a non-static load method, like load(InputStream)
secondaryRoot = loader.load(getClass().getResourceAsStream("SecondaryFXML.fxml"));
FXMLDocumentController secondaryController = loader.getController(); // Change type to your controller type here

然后,您可以向控制器添加一个方法,将另一个控制器传递给控制器​​。这样你就可以从另一个控制器访问这些字段了。

You can then add a method to your controller that allows you to pass the other controller to the controller. That way you can access the fields from the other controller.

我强烈建议你为两种布局创建不同的控制器类。否则只会增加混乱。

这篇关于来自不同FXML文件的@ FXML-annotated组件导致NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆