从 gridPane (JavaFX) 中的多个动态生成的 TextField 中提取值

Extracting values from multiple dynamically generated TextFields in a gridPane (JavaFX)

我正在尝试根据用户输入创建一个具有动态行数的网格窗格。一旦行数已知,每行将有 8 个对象,它们是 TextFields 和 DatePicker 的混合体。我可以创建它们,但现在我很难尝试提取用户将在其中输入的任何数据。我可能希望将一行的每个 textField 数据保存在一个单独的数组中,并且总共有 8 个数组供进一步使用。我知道有 getText(),但它不适用于动态添加的文本字段。我在这里做错了什么?

以下是我的控制器class:

private void addEntityTextFields() {
    int numOfOpenTextFieldRows = Integer.parseInt(numOfEntities);
    this.numOfOpenTextFieldRows = numOfOpenTextFieldRows;       
    EntityRowStructure();

    for (int rowNum=0; rowNum<numOfOpenTextFieldRows; rowNum++) {

        TextField entityNameTextBox = new TextField();
        entityOverview_GridPane.add(entityNameTextBox, 0 , rowNum+1);

        TextField EntityLegalTypeTextBox = new TextField();
        entityOverview_GridPane.add(EntityLegalTypeTextBox, 1, rowNum+1);

        TextField EntityTypeTextBox = new TextField();
        entityOverview_GridPane.add(EntityTypeTextBox, 2, rowNum+1);

        DatePicker AcquisitionDateTextBox = new DatePicker();
        entityOverview_GridPane.add(AcquisitionDateTextBox, 3, rowNum+1);

        DatePicker DivestitureDateTextBox = new DatePicker();
        entityOverview_GridPane.add(DivestitureDateTextBox, 4, rowNum+1);

        TextField EINTextBox = new TextField();
        entityOverview_GridPane.add(EINTextBox, 5, rowNum+1);

        DatePicker taxableStartDateTextBox = new DatePicker();
        entityOverview_GridPane.add(taxableStartDateTextBox, 6, rowNum+1);

        DatePicker taxableEndDateTextBox = new DatePicker();
        entityOverview_GridPane.add(taxableEndDateTextBox, 7, rowNum+1);

    }   
}

创建一个模型 class,其中包含 JavaFX properties 表示行中的文本字段和日期选择器正在编辑的数据,并创建该 class 的实例列表.

然后每次需要添加一行时,创建模型的新实例,添加一行,并将模型中的属性绑定到行中控件中的值。然后要读取值,您只需遍历列表并从每个对象中获取值。

这里有一个比您描述的更简单的版本,它使用两个文本字段和一个日期选择器,代表一个人的名字、姓氏和出生日期。首先是模型 class:

import java.time.LocalDate;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {
    private final StringProperty firstName = new SimpleStringProperty();
    private final StringProperty lastName = new SimpleStringProperty();
    private final ObjectProperty<LocalDate> dateOfBirth = new SimpleObjectProperty<>();
    public final StringProperty firstNameProperty() {
        return this.firstName;
    }

    public final String getFirstName() {
        return this.firstNameProperty().get();
    }

    public final void setFirstName(final String firstName) {
        this.firstNameProperty().set(firstName);
    }

    public final StringProperty lastNameProperty() {
        return this.lastName;
    }

    public final String getLastName() {
        return this.lastNameProperty().get();
    }

    public final void setLastName(final String lastName) {
        this.lastNameProperty().set(lastName);
    }

    public final ObjectProperty<LocalDate> dateOfBirthProperty() {
        return this.dateOfBirth;
    }

    public final LocalDate getDateOfBirth() {
        return this.dateOfBirthProperty().get();
    }

    public final void setDateOfBirth(final LocalDate dateOfBirth) {
        this.dateOfBirthProperty().set(dateOfBirth);
    }

}

然后是示例应用程序

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class DynamicGridPaneExample extends Application {

    private final List<Person> personList = new ArrayList<>();
    private  GridPane grid ;

    private final DateTimeFormatter format = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) ;


    private void addNewRow() {

        // create a new person, and add to list:
        Person person = new Person();
        personList.add(person);

        // create controls:
        TextField firstNameTextField = new TextField();
        TextField lastNameTextField = new TextField();
        DatePicker dateOfBirthPicker = new DatePicker();

        // bind controls to person:
        firstNameTextField.textProperty().bindBidirectional(person.firstNameProperty());
        lastNameTextField.textProperty().bindBidirectional(person.lastNameProperty());
        dateOfBirthPicker.valueProperty().bindBidirectional(person.dateOfBirthProperty());

        // add controls to grid:
        grid.addRow(personList.size(), firstNameTextField, lastNameTextField, dateOfBirthPicker);
    }

    @Override
    public void start(Stage primaryStage) {
        grid = new GridPane();
        grid.setHgap(2);
        grid.setVgap(2);

        grid.addRow(0, new Label("First Name"), new Label("Last Name"), new Label("Date of Birth"));

        Button add = new Button("Add");
        add.setOnAction(e -> addNewRow());

        // just as a demo of getting the values:
        Button process = new Button("Process data");
        process.setOnAction(e -> {
            for (Person person : personList) {

                String firstName = person.getFirstName();
                String lastName = person.getLastName();
                LocalDate dateOfBirth = person.getDateOfBirth();
                Object formattedDOB = dateOfBirth == null ? "" : format.format(dateOfBirth);
                System.out.printf("%s %s %s %n", firstName, lastName, formattedDOB);
            }
        });

        BorderPane root = new BorderPane(grid);
        HBox buttons = new HBox(5, add, process);
        buttons.setPadding(new Insets(5));
        buttons.setAlignment(Pos.CENTER);
        root.setBottom(buttons);

        Scene scene = new Scene(root, 800, 800);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

您还应该考虑使用 TableView,它基本上具有此功能,外加更多的基础设施。