在 javafx 中将数据从一个控制器传递到另一个控制器。 java.lang.IllegalArgumentException

Passing data from one controller to another in javafx. java.lang.IllegalArgumentException

我正在创建一个报告应用程序,其中有 3 个场景和 3 个控制器 classes。我的目标是单击我的 MaintainanceBacklog_Controller Class 中的按钮(发送电子邮件),它使用来自同一控制器 class 的 3 个 ObservableList 和来自另一个控制器 class 的 1 个 ObservableList( BatchProcesses_Controller)。我需要将这个列表从 BatchProcesses_Controller 传递到我的 MaintainanceBacklog_Controller。我得到

Caused by: java.lang.IllegalArgumentException: Can not set reporting.controllers.BatchProcesses_Controller field reporting.controllers.MainScreen_Controller.batchProcesses_Controller to javafx.scene.layout.AnchorPane

我附上了这三个控制器的代码片段 classes + main Class + 所有三个 fxml 文件片段 + 错误堆栈跟踪.. 请帮忙。无法弄清楚这个问题。

MainScreen_Controller.java

package reporting.controllers;

import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import reporting.model.BatchProcess_OnlySuccessCount;
import reporting.controllers.BatchProcesses_Controller;
import reporting.controllers.MaintainanceBacklog_Controller;

public class MainScreen_Controller {
    @FXML private BatchProcesses_Controller batchProcesses_Controller;
    @FXML private MaintainanceBacklog_Controller maintainanceBacklog_Controller;
    public void initialize() {
        batchProcesses_Controller.init(this);
        maintainanceBacklog_Controller.init(this);
    }

    public ObservableList<BatchProcess_OnlySuccessCount> 
    getBatchProcessListData() {
        return batchProcesses_Controller.data_SuccessCount;
    }
}

BatchProcesses_Controller.java

.
.//other @FXML declarations
.
@FXML
private DatePicker datePck_To;

private MainScreen_Controller mainScreen;

@Override
public void initialize(URL location, ResourceBundle resources) {
    assert cmbBox_Product != null : "fx:id=\"cmbBox_Product\" was not 
injected: check your FXML file 'MaintainanceBacklog_BatchProcesses.fxml'.";
    dateCol.setCellValueFactory(new PropertyValueFactory<>("Date"));
    ...//other column setCellValues here
    showGraphCol.setCellValueFactory(new PropertyValueFactory<>
("showGraphBtn"));
}
//injecting main screen controller to this class
public void init(MainScreen_Controller mainScreen_Controller) {
    mainScreen = mainScreen_Controller;
}

MaintainanceBacklog_Controller.java

...//other imports
import reporting.util.Maint_ProcessesEnum;
import reporting.controllers.MainScreen_Controller;

public class MaintainanceBacklog_Controller implements Initializable {
    ...//other FXM`enter code here`L declarations
    private MainScreen_Controller main;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //other table column setCellValuesFactorys
    }

    public void onButtonClick_EmailReport() {
        EmailGenerator email = new EmailGenerator();
        email.setDataInTable(data_after, data_before,data_businessErr, 
    main.getBatchProcessListData());
    }//calling getBatchProcessListData to get the required list

Main.java

public class Main extends Application {private Parent rootNode;
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void init() throws Exception {
        FXMLLoader fxmlLoader = new 
    FXMLLoader(reporting.design.Test.class.getResource("MainScreen.fxml"));
        rootNode = fxmlLoader.load();
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("RSA Reporting");
        stage.setScene(new Scene(rootNode));
        stage.show();
    }

MainScreen.fxml

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

<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="833.0" prefWidth="750.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="reporting.controllers.MainScreen_Controller">
    <children>
        <TabPane prefHeight="791.0" prefWidth="1046.0">
            <tabs>
                <Tab text="BatchProcess">
                    <content>
                        <fx:include fx:id="batchProcesses_Controller" source="BatchProcesses.fxml" />
                    </content>
                </Tab>
                <Tab text="MaintainanceBacklog">
                    <content>
                        <fx:include fx:id="maintainanceBacklog_Controller" source="MaintainanceBacklog.fxml" />
                    </content>
                </Tab>
            </tabs>
        </TabPane>
    </children>
</AnchorPane>

BatchProcesses.fxml

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

<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="batchProcesses" prefHeight="791.0" prefWidth="1046.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="reporting.controllers.BatchProcesses_Controller">
    <children>
        <Label layoutX="194.0" layoutY="73.0" prefHeight="17.0" prefWidth="82.0" text="Select Process" />
        <ComboBox fx:id="cmbBox_Product" layoutX="288.0" layoutY="69.0" prefHeight="25.0" prefWidth="174.0" promptText="Select">
            <items>
                <FXCollections fx:factory="observableArrayList">
...

MaintainanceBacklog.fxml

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

<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="maintainanceBacklog" prefHeight="791.0" prefWidth="1046.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="reporting.controllers.MaintainanceBacklog_Controller">
    <children>
        <ComboBox fx:id="cmbBox_Product_MaintainanceBacklog" layoutX="151.0" layoutY="52.0" prefHeight="25.0" prefWidth="313.0" promptText="Select">
            <items>
                <FXCollections fx:factory="observableArrayList">
...

ErrorStackTrace

log4j:WARN No appenders could be found for logger (reporting.util.Util).
log4j:WARN Please initialize the log4j system properly.
Apr 20, 2018 3:37:16 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 8.0.141 by JavaFX runtime of version 8.0.122-ea
Apr 20, 2018 3:37:16 PM javafx.fxml.FXMLLoader$ValueElement processValue
WARNING: Loading FXML document with JavaFX API of version 8.0.141 by JavaFX runtime of version 8.0.122-ea
Exception in Application init method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application init method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:912)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication5(LauncherImpl.java:182)
    at java.lang.Thread.run(Unknown Source)
Caused by: javafx.fxml.LoadException: 
/C:/SyntBotsServices/ProductionReporting/bin/reporting/design/MainScreen.fxml:13

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at application.Main.init(Main.java:72)
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:841)
    ... 2 more
Caused by: java.lang.IllegalArgumentException: Can not set reporting.controllers.BatchProcesses_Controller field reporting.controllers.MainScreen_Controller.batchProcesses_Controller to javafx.scene.layout.AnchorPane
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
    at java.lang.reflect.Field.set(Unknown Source)
    at javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1163)
    at javafx.fxml.FXMLLoader.access00(FXMLLoader.java:103)
    at javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:857)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:751)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    ... 6 more
Exception running application application.Main

由于 BatchProcesses.fxml 的根元素是 <AnchorPane> 元素,因此为下一行创建了 AnchorPane

<fx:include fx:id="batchProcesses_Controller" source="BatchProcesses.fxml" />

你的控制器中对应fx:id属性值的字段是

@FXML private BatchProcesses_Controller batchProcesses_Controller;

FXMLLoader 无法将 AnchorPane 分配给类型 BatchProcesses_Controller 的字段,原因很明显。

如果需要将包含的fxml的controller分配给一个controller字段,需要使用append Controller to the fx:id of the <fx:include>:

@FXML private AnchorPane batchProcesses_Controller;
@FXML private BatchProcesses_Controller batchProcesses_ControllerController;