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

橙三吉。 提交于 2021-02-08 12:04:50

问题


I am creating a reporting application in which I have 3 scenes with 3 controller classes. My aim is to click on a button (Send Email) from my MaintainanceBacklog_Controller Class, which uses 3 ObservableList from the same controller class and 1 ObservableList from another controller class(BatchProcesses_Controller). I need to pass this one List from BatchProcesses_Controller to my MaintainanceBacklog_Controller. I am getting

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

I am attaching my code snippets for these three Controller classes + main Class + all three fxml files snippets + Error Stack trace.. Please help. Not able to figure out the issue.

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$launchApplication$155(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.access$1600(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

回答1:


Since the root element of BatchProcesses.fxml is a <AnchorPane> element, an AnchorPane is created for the following line.

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

The field in your controller corresponding to the value of the fx:id attribute is

@FXML private BatchProcesses_Controller batchProcesses_Controller;

FXMLLoader fails to assign a AnchorPane to a field of type BatchProcesses_Controller for obvious reasons.

If you need the controller of the included fxml to be assigned to a controller field, you need to use append Controller to the fx:id of the <fx:include>:

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


来源:https://stackoverflow.com/questions/49945101/passing-data-from-one-controller-to-another-in-javafx-java-lang-illegalargument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!