Хотя ваш вопрос не дает четкого представления о конечной цели, некоторые другие пользователи предложили использовать цикл в вашем коде Java для создания TextFields
.
Я согласен, так как то, что вы описываете, вероятно, не лучше всего подходит для FXML, так как это гораздо проще сделать с помощью кода Java.
В приведенном ниже примере используется объект пользовательской модели данных с именем TextInput
, который содержит как TextField
, так и связанный с ним Label
.
Сам код также прокомментирован с дополнительным пониманием.
КОД
Main.java - Просто используется для запуска приложения и отображения сцены:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
loader.setController(new Controller());
primaryStage.setScene(new Scene(loader.load()));
primaryStage.setTitle("Dynamic TextFields Example");
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Layout.fxml - простой макет графического интерфейса, содержащий GridPane
, используемый для отображения данных TextInput
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.*?>
<VBox alignment="TOP_CENTER" prefHeight="400.0" prefWidth="300.0" spacing="10.0" xmlns="http://javafx.com/javafx/9.0.1"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" VBox.vgrow="ALWAYS">
<content>
<GridPane fx:id="gridPane" hgap="10.0" vgap="5.0">
<columnConstraints>
<ColumnConstraints hgrow="NEVER" minWidth="-Infinity"/>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="-Infinity" prefHeight="30.0" vgrow="NEVER"/>
</rowConstraints>
</GridPane>
</content>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</ScrollPane>
<Button fx:id="btnGetInputText" mnemonicParsing="false" text="Get Input 4 Text"/>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</VBox>
Controller.java - контроллер для макета FXML
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import java.util.ArrayList;
import java.util.List;
public class Controller {
@FXML
private GridPane gridPane;
@FXML
private Button btnGetInputText;
// List of new TextInput objects
List<TextInput> textInputs = new ArrayList<>();
@FXML
private void initialize() {
// Here we will generate 40 new TextInput objects.
for (int i = 0; i < 40; i++) {
TextInput input = new TextInput(
"Input " + i,
new Label("Input " + i + ":"),
new TextField()
);
// Now, add the new TextInput Label and TextField to the GridPane
gridPane.add(input.getLabel(), 0, i);
gridPane.add(input.getTextField(), 1, i);
// Finally, add the input to the list so they can be retrieved later using the input's Name
textInputs.add(input);
}
// Use the button to print out the text from Input #4
btnGetInputText.setOnAction(e -> {
System.out.println("Input #4: " + getInputTextByName("Input 4"));
});
}
/**
* Helper method to get the value of a specific TextField
*/
private String getInputTextByName(String name) {
// Loop through the list of TextInput objects and get the one with the desired name
for (TextInput input :
textInputs) {
if (input.getName().equalsIgnoreCase(name)) {
return input.getTextField().getText();
}
}
// If not found, return null (or empty String, if desired)
return null;
}
}
/**
* Custom data structure to hold both the Label and TextFields for your inputs. There is also a Name field that can
* be any type you wish, but provides a way of locating the right TextField when you need to. This could just as
* easily be done with an ID or searching label.getText(), but I'm using a separate field in this sample for simplicity.
*/
class TextInput {
private final String name;
private final Label label;
private final TextField textField;
public TextInput(String name, Label label, TextField textField) {
this.name = name;
this.label = label;
this.textField = textField;
}
public String getName() {
return name;
}
public Label getLabel() {
return label;
}
public TextField getTextField() {
return textField;
}
}