I am working in a JavaFX project. There I have fxml included in other fxml files. Now I need to send data from the outer controller to the inner controller. I've tried it, but the combobox looses its items as soon as the transferMethod finished.
Edit: As in the comment section advised, I switched to another import method. This import method fixes the bug with the comboBox, but causes problems with the import itself, at least in some cases. Therefore I update the MRE
Parts in use:
Import class:
package at.palberon.miniproqa.fxplayground;
import java.util.ArrayList;
public class Import {
ArrayList<String> list;
public Import() {
list = new ArrayList<>();
list.add("Hello");
list.add("World");
}
public ArrayList<String> getList() {
return list;
}
}
inner.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.palberon.miniproqa.fxplayground.InnerController">
<ComboBox fx:id="comboBox" prefWidth="150.0" />
</AnchorPane>
InnerController Class:
package at.palberon.miniproqa.fxplayground;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import java.util.ArrayList;
public class InnerController {
@FXML
ComboBox<String> comboBox;
ObservableList<String> observableList;
public void setComboBoxItems(ArrayList<String> items) {
observableList = FXCollections.observableArrayList(items);
comboBox.setItems(observableList);
}
}
outer.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<TabPane prefHeight="600.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="at.palberon.miniproqa.fxplayground.OuterController">
<tabs>
<Tab fx:id="efTab" closable="false" text="Einstieg">
<fx:include fx:id="innerController" source="inner.fxml"/>
</Tab>
</tabs>
</TabPane>
OuterController Class:
package at.palberon.miniproqa.fxplayground;
import javafx.fxml.FXML;
import java.util.ArrayList;
public class OuterController {
private ArrayList<String> items;
@FXML
private InnerController innerController;
public void initialize(){
if (innerController != null) {
System.out.println("Right");
}
Import importData = new Import();
items = importData.getList();
innerController.setComboBoxItems(items);
}
}
With this setup, I am unable to start the program, and get an Exception.
Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at javafx.graphics@22-ea/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics@22-ea/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1147)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics@22-ea/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
at javafx.graphics@22-ea/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:1570)
Caused by: javafx.fxml.LoadException:
/C:/Users/Pascal/IdeaProjects/fxplayground/target/classes/at/palberon/miniproqa/fxplayground/outer.fxml:11
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2727)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2705)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2568)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2536)
at at.palberon.miniproqa.fxplayground/at.palberon.miniproqa.fxplayground.HelloApplication.start(HelloApplication.java:14)
at javafx.graphics@22-ea/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at javafx.graphics@22-ea/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at javafx.graphics@22-ea/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at javafx.graphics@22-ea/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at javafx.graphics@22-ea/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at javafx.graphics@22-ea/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics@22-ea/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
... 1 more
Caused by: java.lang.IllegalArgumentException: Can not set at.palberon.miniproqa.fxplayground.InnerController field at.palberon.miniproqa.fxplayground.OuterController.innerController to javafx.scene.layout.AnchorPane
at java.base/jdk.internal.reflect.FieldAccessorImpl.throwSetIllegalArgumentException(FieldAccessorImpl.java:228)
at java.base/jdk.internal.reflect.FieldAccessorImpl.throwSetIllegalArgumentException(FieldAccessorImpl.java:232)
at java.base/jdk.internal.reflect.MethodHandleObjectFieldAccessorImpl.set(MethodHandleObjectFieldAccessorImpl.java:115)
at java.base/java.lang.reflect.Field.set(Field.java:836)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.injectFields(FXMLLoader.java:1180)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:870)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:764)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2858)
at javafx.fxml@22-ea/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2654)
... 12 more
Exception running application at.palberon.miniproqa.fxplayground.HelloApplication
Process finished with exit code 1
I have an inner module, I call it a module (fxml file plus the Controller) which is included in the outer module. In the FXML of the outer module, I include the FXML of the inner. In the outer Controller I try to make me the inner Controller accessible.
<fx:include source="inner.fxml"/>
to this<fx:include fx:id="inner" source="inner.fxml"/>
and leave only these lines on the initialize() method from OuterControllerImport importData = new Import(); items = importData.getList(); innerController.setComboBoxItems(items);
and add@FXML
to thisprivate InnerController innerController;
<fx:include fx:id="innerController" source="inner.fxml"/>
change the name tofx:id="inner"
the reason is because in the controller class you haveinnerController
if you want to keep thefx:id="innerController"
then the you need to change the name of the field inOuterController
toinnerControllerController