You cannot use loop logig in a fxml file. However you could implement some logic to add a specified number of rows. A <fx:root>
element can be used to create a fxml file for the individual rows:
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.Text?>
<GridPane fx:id="root" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml.grid.MainController">
<children>
<Text text="A"/>
<Text text="B" GridPane.columnIndex="1"/>
<Text text="C" GridPane.columnIndex="2"/>
</children>
</GridPane>
sub.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.DatePicker?>
<fx:root type="javafx.scene.layout.GridPane" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml.grid.SubController">
<children>
<TextField fx:id="text" GridPane.columnIndex="0" GridPane.rowIndex="$rowIndex" />
<CheckBox fx:id="checkBox" GridPane.columnIndex="1" GridPane.rowIndex="$rowIndex" />
<DatePicker fx:id="datePicker" GridPane.columnIndex="2" GridPane.rowIndex="$rowIndex" />
</children>
</fx:root>
MainController
public class MainController {
@FXML
private GridPane root;
private final List<SubController> subControllers = new ArrayList<>();
public void setRowNumber(int rows) throws IOException {
if (rows < subControllers.size()) {
// for simplicity only allow the number of rows to grow
throw new IllegalArgumentException();
}
for (int i = subControllers.size(); i < rows; i++) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("sub.fxml"));
// add rowIndex to be used from fxml using $rowIndex
loader.getNamespace().put("rowIndex", subControllers.size() + 1);
loader.setRoot(root);
loader.load();
subControllers.add(loader.getController());
}
}
}
SubController
public class SubController {
@FXML
private TextField text;
@FXML
private CheckBox checkBox;
@FXML
private DatePicker datePicker;
}
Use
int num = 6;
FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
Parent parent = loader.load();
loader.<MainController>getController().setRowNumber(num);
It shouldn't be too hard to add methods to the controllers to access individual elements.
Note that TableView
may also be worth a look.