0

I'm working on a project in which there are 2 tabs. On first tab's user interface there is a text field and a button. In the text field user can write any number till 100 and when he will press button Next, my application will go to the next tab on which there is a Gridpane with three columns A, B and C.

enter image description here

enter image description here

So what I want is whatever number user will enter in the first tab's text field according to that number it should add same number of rows with Textfields, Checkboxes and Datepicker in second tab's Gridpane.

enter image description here

enter image description here

With SceneBuilder it's very easy to create fixed sized Gridpane and then add elements inside it and give them fx:id, but dynamically it's complicated because I've to assign fx:id to each text field, checkboxes and Datepicker so I can retrieve it's data and can send to db.

Should I use Gridpane or is there any other solution to achieve the goal. It would be great help if someone could guide me on what needs to be done.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Junaid
  • 664
  • 5
  • 18
  • 35
  • 1
    You don’t have to assign fx:id values to your fields. Just keep them in a List as you create and add them. – VGR May 05 '17 at 14:55

1 Answers1

0

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.

fabian
  • 80,457
  • 12
  • 86
  • 114
  • it resolved my issue thanks. Can you please give me a little example how to access data inside Gridpane's textboxes, checkboxes and datepicker, let say user entered data in specific textfields(not in all), checked specific checkboxes and choose some dates from datepickers. So how can I retrieve only that specif data and save it in to a file or db ? And can you please tell me which element should be better Gridpane or TableView ? – Junaid May 06 '17 at 13:55