Javafx 为什么我不能在控制器中使用FXML和fxid?

Javafx 为什么我不能在控制器中使用FXML和fxid?,javafx,Javafx,我找到了我需要的。我需要从一个控制器访问另一个控制器 但我有一个问题。为什么使用FXML注释时会出现异常 我想做些什么 public class MainController { @FXML Tab1Controller tab1Controller; @FXML Tab2Controller tab2Controller; @FXML Tab tab1; //THIS @FXML Tab tab2; // And this call exception

我找到了我需要的。我需要从一个控制器访问另一个控制器

但我有一个问题。为什么使用FXML注释时会出现异常

我想做些什么

public class MainController {
    @FXML Tab1Controller tab1Controller;
    @FXML Tab2Controller tab2Controller;

    @FXML Tab tab1;   //THIS
    @FXML Tab tab2;   // And this call exception. But if i comment both fields is evertying OK.


    @FXML public void initialize() {
        System.out.println("Application started");
        tab1Controller.init(this);
        tab2Controller.init(this);
    }

    public String loadLblTextFromTab1() {
        return tab1Controller.lbl1.getText();
    }

    public void setTab2LabelText(String text) {
        tab2Controller.lbl2.setText(text);
    }
}
另外,在我有fx:id的地方添加XML文件

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="299.0" prefWidth="309.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
   <children>
      <TabPane prefHeight="299.0" prefWidth="309.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <tabs>
          <Tab closable="false" text="Tab 1">
               <content>
                  <fx:include fx:id="tab1" source="tab/Tab1.fxml" />
               </content></Tab>
          <Tab closable="false" text="Tab 2">
               <content>
                  <fx:include fx:id="tab2" source="tab/Tab2.fxml" />
               </content></Tab>
        </tabs>
      </TabPane>
   </children>
</AnchorPane>
异常看起来像

Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566)
    ... 17 more
Caused by: java.lang.NullPointerException
    at controller.MainController.initialize(MainController.java:15)
    ... 27 more
所以,现在我不明白为什么我会得到这个例外?无论如何,我从fxml文件本身生成了我的
选项卡。

错误消息:

原因:java.lang.IllegalArgumentException:
无法将javafx.scene.control.Tab字段controller.MainController.tab1设置为javafx.scene.layout.ancorpane
解释问题所在。
生成一个
AnchorPane
(可能是
Tab1.fxml
的根元素),您试图使用类型为
Tab
的字段来引用它

如果您只需要访问选项卡的内容,只需相应地更改字段的类型:

public class MainController {
    @FXML Tab1Controller tab1Controller;
    @FXML Tab2Controller tab2Controller;

    @FXML AnchorPane tab1;   
    @FXML AnchorPane tab2;   


    @FXML public void initialize() {
        System.out.println("Application started");
        tab1Controller.init(this);
        tab2Controller.init(this);
    }

    public String loadLblTextFromTab1() {
        return tab1Controller.lbl1.getText();
    }

    public void setTab2LabelText(String text) {
        tab2Controller.lbl2.setText(text);
    }
}
如果您特别需要访问选项卡本身,则需要在
选项卡上设置
fx:id
s。与前面一样,要获取控制器的引用,需要在
上设置
fx:id
。因此,如果您希望实际引用
选项卡以及控制器,则
选项卡和
上都需要(不同的)
fx:id
s:



发布(至少)FXML文件和完整的堆栈跟踪。确定代码中哪一行引发异常。在我的问题中,我为所有文件提供了链接。无论如何,这里有一个异常
,原因是:java.lang.IllegalArgumentException:无法将javafx.scene.control.Tab字段controller.MainController.tab1设置为javafx.scene.layout.AnchorPane
您应该在问题中发布完整的堆栈跟踪(将其格式化为代码)。无论如何这是不言自明的,不是吗?<代码> <代码>生成<代码>锚文本< /代码>,并试图将其分配给<代码> Tab < /C>。考虑使用FX:root构造。它导致了更干净的代码,IMHO。在第二个版本中,
tab1Controller
将不会初始化,因为
tab1
fx:id
未应用于
。你为什么不像我在回答中那样尝试呢?为什么我要将我的对象更改为“@FXML AnchorPane tab1;”?我在“AnchorPane”里面有“Tab”,但在“Tab”里面没有“AnchorPane”。目前还不清楚me@Dred
fx:id
属性是在
元素上定义的,该元素创建了一个
锚烷
,而不是
选项卡
@Dred,因为
创建了一个
锚烷
,实际上,在每个
选项卡中都有一个
锚烷
@FXML选项卡tab2时间?我在
tab2Controller.init(这个)上有NPEtab2ContentController==null
但是
tab1ContentController
是filled@Dred我不明白那个评论。
public class MainController {
    @FXML Tab1Controller tab1Controller;
    @FXML Tab2Controller tab2Controller;

    @FXML AnchorPane tab1;   
    @FXML AnchorPane tab2;   


    @FXML public void initialize() {
        System.out.println("Application started");
        tab1Controller.init(this);
        tab2Controller.init(this);
    }

    public String loadLblTextFromTab1() {
        return tab1Controller.lbl1.getText();
    }

    public void setTab2LabelText(String text) {
        tab2Controller.lbl2.setText(text);
    }
}
public class MainController {
    @FXML Tab1Controller tab1ContentController;
    @FXML Tab2Controller tab2ContentController;

    @FXML Tab tab1;   
    @FXML Tab tab2;   


    @FXML public void initialize() {
        System.out.println("Application started");
        tab1Controller.init(this);
        tab2Controller.init(this);
    }

    public String loadLblTextFromTab1() {
        return tab1ContentController.lbl1.getText();
    }

    public void setTab2LabelText(String text) {
        tab2ContentController.lbl2.setText(text);
    }
}