Hier mal ein kleines Beispiel, wie man mit JavaFX, in der FXML, Controller verschachtelt und worauf man achten muss.
Wenn man in einer FXML-Datei weitere FXML-Dateien verschachteln will, nutzt man den folgenden Tag. Im SceneBuilder findet man das unter File > Include > FXML…
<fx:include source="PersonEditor.fxml" fx:id="personEditor"/>Code-Sprache: HTML, XML (xml)
Um an den Controller und Container der „PersonEditor.fxml“ zu kommen, fügt man folgenden Code ein. ACHTUNG der Variablen-Name vom Container muss der selbe Name der fx:include ID sein, bei der Controller-Klasse gilt das selbe, aber da muss noch dein „Controller“ angefügt werden, wenn diese Konvention nicht eingehalten wird, sind die Variablen Null.
@FXML private GridPane personEditor;
@FXML private PersonEditorController personEditorController; Code-Sprache: CSS (css)
Hier nochmal den kompletten Code
MainController.java
package app.example.NestedController;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
public class MainController {
// ACHTUNG - der Name von der Controller-Variable muss die ID vom <fx:include /> sein, mit "Controller" hinten dran
// wenn der Name nicht stimmt, ist die Controller-Klasse null
@FXML private PersonEditorController personEditorController;
// ACHTUNG - der Name vom Container muss der Name von der <fx:include /> ID sein, andernfalls ist die Variable null
@FXML private GridPane personEditor;
@FXML private ListView<Person> personList ;
public void initialize() {
personList.getItems().addAll(
new Person("Hugo", "Lloris"),
new Person("Kyle", "Walker"),
new Person("Jan", "Verthongen"),
new Person("Younes", "Kaboul"),
new Person("Danny","Rose"),
new Person("Nacir", "Chadli"),
new Person("Etienne", "Capoue"),
new Person("Paulinho", "Maciel"),
new Person("Andros", "Townsend"),
new Person("Erik", "Lamela"),
new Person("Roberto", "Soldado")
);
personList.setCellFactory(new Callback<ListView<Person>, ListCell<Person>>() {
@Override
public ListCell<Person> call(ListView<Person> listView) {
return new ListCell<Person>() {
@Override
public void updateItem(Person person, boolean empty) {
super.updateItem(person, empty);
textProperty().unbind();
if (person != null) {
textProperty().bind(Bindings.format("%s %s", person.firstNameProperty(), person.lastNameProperty()));
}
}
};
}
});
personEditorController.personProperty().bind(personList.getSelectionModel().selectedItemProperty());
}
}Code-Sprache: PHP (php)
PersonViewer.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.Pane?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="app.example.NestedController.MainController">
<center>
<SplitPane>
<ListView fx:id="personList"/>
<Pane>
<fx:include source="PersonEditor.fxml" fx:id="personEditor"/>
</Pane>
</SplitPane>
</center>
</BorderPane>Code-Sprache: HTML, XML (xml)
PersonEditorController.java
package app.example.NestedController;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
public class PersonEditorController {
private final ObjectProperty<Person> person ;
@FXML
private TextField firstName ;
@FXML
private TextField lastName ;
public PersonEditorController() {
this.person = new SimpleObjectProperty<>(this, "person", null);
}
public void initialize() {
this.person.addListener(new ChangeListener<Person>() {
@Override
public void changed(ObservableValue<? extends Person> observable,
Person oldPerson, Person newPerson) {
if (oldPerson != null) {
firstName.textProperty().unbindBidirectional(oldPerson.firstNameProperty());
lastName.textProperty().unbindBidirectional(oldPerson.lastNameProperty());
}
if (newPerson != null) {
firstName.textProperty().bindBidirectional(newPerson.firstNameProperty());
lastName.textProperty().bindBidirectional(newPerson.lastNameProperty());
}
}
});
}
public final ObjectProperty<Person> personProperty() {
return person ;
}
public final Person getPerson() {
return person.get() ;
}
public final void setPerson(Person person) {
this.person.set(person);
}
}
Code-Sprache: PHP (php)
PersonViewer.java
package app.example.NestedController;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class PersonViewer extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
Scene scene = new Scene(FXMLLoader.<Parent>load(getClass().getResource("PersonViewer.fxml")), 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}Code-Sprache: JavaScript (javascript)
PersonEditor.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<GridPane xmlns:fx="http://javafx.com/fxml" fx:controller="app.example.NestedController.PersonEditorController">
<Label text="First Name:">
<GridPane.columnIndex>0</GridPane.columnIndex>
<GridPane.rowIndex>0</GridPane.rowIndex>
</Label>
<Label text="Last Name:">
<GridPane.columnIndex>0</GridPane.columnIndex>
<GridPane.rowIndex>1</GridPane.rowIndex>
</Label>
<TextField fx:id="firstName">
<GridPane.columnIndex>1</GridPane.columnIndex>
<GridPane.rowIndex>0</GridPane.rowIndex>
</TextField>
<TextField fx:id="lastName">
<GridPane.columnIndex>1</GridPane.columnIndex>
<GridPane.rowIndex>1</GridPane.rowIndex>
</TextField>
</GridPane>Code-Sprache: HTML, XML (xml)
Person.java
package app.example.NestedController;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Person {
private final StringProperty firstName ;
private final StringProperty lastName ;
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(this, "firstName", firstName);
this.lastName = new SimpleStringProperty(this, "lastName", lastName);
}
public final StringProperty firstNameProperty() {
return firstName ;
}
public final String getFirstName() {
return firstName.get() ;
}
public final void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public final StringProperty lastNameProperty() {
return lastName ;
}
public final String getLastName() {
return lastName.get();
}
public final void setLastName(String lastName) {
this.lastName.set(lastName);
}
@Override
public String toString() {
return getFirstName() + " " + getLastName() ;
}
}Code-Sprache: PHP (php)