问题描述
我正在尝试在每行上创建一个带有文本框的网格,用户可以在其中输入一个数字,并添加相应数量的新行。这很有效,如下面的屏幕截图所示。
I'm trying to create a grid with a textbox on each row where user can enter a number, and corresponding number of new rows are added. This works well, as shown below in the screenshot.
现在我正在尝试从基于有多少问题创建的文本字段中提取文本?因为它们嵌套在各种节点元素中,所以我很难找到正确的方法。任何人都可以告诉我我做错了什么?我尝试使用保存按钮测试它,但我总是进入其他
语句Vboxgrid2为空!
在我的控制台上。我不知道为什么它说我的VBoxgrid2是空的!
Now I'm trying to extract the text from those textfields created based on the question "how many?" and since they are nested within various node elements, I'm having a hard time identifying the right way.Can anyone tell me what I'm doing wrong? I tried testing it using the save button, but I always go into the else
statement of "Vboxgrid2 is empty!"
on my console. I don't know why it says that my VBoxgrid2 is empty!
以下是我重新创建的一个Minimal,Complete和Verifiable示例:
Following is a Minimal, Complete, and Verifiable example I've recreated:
package testing;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ExtractThatText extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("GridPane Experiment");
GridPane gridPane = new GridPane();
for(int i=0;i<5;i++) {
VBox mainVBox = new VBox();
VBox vboxgrid1 = new VBox();
VBox vboxgrid2 = new VBox();
HBox hboxgrid = new HBox();
hboxgrid.setPadding(new Insets(5,5,5,5));
RadioButton rbYes = new RadioButton("Yes");
RadioButton rbNo = new RadioButton("No");
Label howmanyLabel = new Label(" How many? ");
TextField howManytxtB = new TextField();
hboxgrid.getChildren().add(rbYes);
hboxgrid.getChildren().add(rbNo);
hboxgrid.getChildren().add(howmanyLabel);
hboxgrid.getChildren().add(howManytxtB);
vboxgrid1.getChildren().add(hboxgrid);
howManytxtB.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
vboxgrid2.getChildren().clear();
Integer howManyNum = Integer.valueOf(howManytxtB.getText());
for(int row=0;row<howManyNum;row++) {
//creating rows for entering the new entities
HBox innerRowbox = new HBox();
TextField name = new TextField();
ComboBox cb = new ComboBox(); //empty cb for now
name.setPromptText("Enter name of the new Entity");
name.setMinWidth(200);
innerRowbox.getChildren().add(name);
innerRowbox.getChildren().add(cb);
vboxgrid2.getChildren().add(innerRowbox);
}
}
});
mainVBox.getChildren().add(vboxgrid1);
mainVBox.getChildren().add(vboxgrid2);
gridPane.add(mainVBox,1, i);
}
for(int i=0;i<5;i++) {
gridPane.add(new Label("row"+i), 0 , i);
}
Button saveButton = new Button("save content");
saveButton.setOnAction(e-> {
Node mainVBox = gridPane.getChildren().get(1); //get just the first row's 1th column which contains mainVBox
if(mainVBox instanceof VBox) {
Node vboxgrid2 = ((VBox) mainVBox).getChildren().get(1);
if(vboxgrid2 instanceof VBox) {
if(!((VBox) vboxgrid2).getChildren().isEmpty()) {
Node innerRowBox = ((VBox) vboxgrid2).getChildren().get(0);
if(innerRowBox instanceof HBox) {
for(Node howmanyTB:((HBox)innerRowBox).getChildren()) {
if(howmanyTB instanceof TextField) {
System.out.println(((TextField) howmanyTB).getText()); //content to save, extracted from the dnamic textfields created.
}
else System.out.println("howmanyTB not an instance of TextField error!");
}
}
else System.out.println("innerRowBox not an instance of HBox error!");
}
else System.out.println("Vboxgrid2 is empty!");
}
else System.out.println("vboxgrid2 not an instance of VBox error!");
}
else System.out.println("mainVbox not an instance of VBox error!");
});
gridPane.add(saveButton, 1, 5);
gridPane.setHgap(10);
gridPane.setVgap(10);
Scene scene = new Scene(gridPane, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
**如果很难理解所有的嵌套我的节点,这是一个摘要:
** If it's difficult to understand the nesting of all my nodes, here is a summary:
gridPane
- > mainVBox
(在第二/第1列的每一行中) - > vboxgrid2
(以及<$ c)对于 mainVBox
中的radiobutton行,$ c> vboxgrid1 - > innerRowbox
- > name
(textfield)
gridPane
-> mainVBox
(in each row of the second/1th column) -> vboxgrid2
(along with vboxgrid1
above it for the radiobutton row in mainVBox
) -> innerRowbox
-> name
(textfield)
推荐答案
既然你似乎意识到你的嵌套有点令人困惑,最好将 TextField
保存在比场景层次结构更容易访问的数据结构中。在这种情况下,由于项目数量在创建之前是已知的,因此可以使用 TextField [] []
数组,但您也可以使用列表< List< TextField>>
,允许您动态添加(内部)行。
Since you do seem to realize that your nesting is a bit confusing, it would be preferable to save the TextField
s in a data structure that is easier to access than your scene hierarchy. In this case since the number of items is known before they are created, a TextField[][]
array could be used, but you could also go for a List<List<TextField>>
to allow you to dynamically add (inner) rows.
BTW:因为您使用索引 1
您访问第二行,而不是第一行。
BTW: since you use index 1
you access the second row, not the first one.
还使用 VBox
只是为了包含你的 HBox
似乎没必要。你可以直接使用 HBox
,因为 VBox
没有其他孩子。
Also using a VBox
just to contain your HBox
seems unnecessary. You could simply use the HBox
directly, since the VBox
has no other children.
Label howmanyLabel = new Label(" How many? ");
最好使用此间距而非空格的保证金。
Better use a margin for this spacing instead of spaces.
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("GridPane Experiment");
GridPane gridPane = new GridPane();
final int rowCount = 5;
TextField[][] textFields = new TextField[rowCount][0];
final Insets hboxPadding = new Insets(5);
final Insets labelMargin = new Insets(0, 15, 0, 15);
for (int i = 0; i < rowCount; i++) {
VBox vboxgrid2 = new VBox();
RadioButton rbYes = new RadioButton("Yes");
RadioButton rbNo = new RadioButton("No");
Label howmanyLabel = new Label("How many?");
HBox.setMargin(howmanyLabel, labelMargin);
TextField howManytxtB = new TextField();
HBox hboxgrid = new HBox(rbYes, rbNo, howmanyLabel, howManytxtB);
hboxgrid.setPadding(hboxPadding);
final int rowIndex = i;
howManytxtB.setOnAction(event -> {
vboxgrid2.getChildren().clear();
int howManyNum = Math.max(0, Integer.parseInt(howManytxtB.getText()));
TextField[] fields = new TextField[howManyNum];
for (int row = 0; row < howManyNum; row++) {
//creating rows for entering the new entities
TextField name = new TextField();
ComboBox cb = new ComboBox(); //empty cb for now
name.setPromptText("Enter name of the new Entity");
name.setMinWidth(200);
HBox innerRowbox = new HBox(name, cb);
vboxgrid2.getChildren().add(innerRowbox);
fields[row] = name;
}
textFields[rowIndex] = fields;
});
VBox mainVBox = new VBox(hboxgrid, vboxgrid2);
gridPane.addRow(i, new Label("row" + i), mainVBox);
}
Button saveButton = new Button("save content");
saveButton.setOnAction(e -> {
TextField[] secondRowFields = textFields[1];
if (secondRowFields.length == 0) {
System.out.println("no TextFields in row1");
} else {
for (TextField textField : secondRowFields) {
System.out.println(textField.getText());
}
}
});
gridPane.add(saveButton, 1, rowCount);
gridPane.setHgap(10);
gridPane.setVgap(10);
Scene scene = new Scene(gridPane, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
这篇关于从网格窗格的各行内的动态创建的文本字段中提取文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!