从 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
,它基本上具有此功能,外加更多的基础设施。
我正在尝试根据用户输入创建一个具有动态行数的网格窗格。一旦行数已知,每行将有 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
,它基本上具有此功能,外加更多的基础设施。