Add Java FX form data to ArrayList - java

In school i had the task to create a JavaFX form GUI in which I can write some Strings like name, eMail...
First I should make a class Person in which the data fields are located.
And there should be a class AdressDB in which I create a list about Person
In the class GUI I should create a form that can be used to add "Persons" to the list. For example with a button.
"Create a class AdressDB. This class keeps a list of Person. Person holds typical data fields such as:eMail, Name, .... In the GUI class you implement a form that you can use to add "Persons" to the list."
I have already completed the form. Now my question: How can I add the data from the form to the ArrayList ?
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.stage.Window;
import java.util.ArrayList;
import javafx.scene.text.Text;
import javafx.scene.text.*;
public class GUI extends Application {
private TextField fieldName, fieldActor;
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Registration Form JavaFX Application");
GridPane gridPane = createRegistrationFormPane();
addUIControls(gridPane);
Scene scene = new Scene(gridPane, 800, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
private GridPane createRegistrationFormPane() {
// Instantiate a new Grid Pane
GridPane gridPane = new GridPane();
// Position the pane at the center of the screen, both vertically and horizontally
gridPane.setAlignment(Pos.CENTER);
// Set a padding of 20px on each side
gridPane.setPadding(new Insets(40, 40, 40, 40));
// Set the horizontal gap between columns
gridPane.setHgap(10);
// Set the vertical gap between rows
gridPane.setVgap(10);
// Add Column Constraints
// columnOneConstraints will be applied to all the nodes placed in column one.
ColumnConstraints columnOneConstraints = new ColumnConstraints(100, 100, Double.MAX_VALUE);
columnOneConstraints.setHalignment(HPos.RIGHT);
// columnTwoConstraints will be applied to all the nodes placed in column two.
ColumnConstraints columnTwoConstrains = new ColumnConstraints(200,200, Double.MAX_VALUE);
columnTwoConstrains.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().addAll(columnOneConstraints, columnTwoConstrains);
return gridPane;
}
private void addUIControls(GridPane gridPane) {
Label headerLabel = new Label("Bitte geben sie Ihre Daten ein");
headerLabel.setFont(Font.font("Arial", FontWeight.BOLD, 24));
gridPane.add(headerLabel, 0,0,2,1);
GridPane.setHalignment(headerLabel, HPos.CENTER);
GridPane.setMargin(headerLabel, new Insets(20, 0,20,0));
// Add Name Label
Label nameLabel = new Label("Name : ");
gridPane.add(nameLabel, 0,1);
// Add Name Text Field
TextField name = new TextField();
name.setPrefHeight(40);
gridPane.add(name, 1,1);
// Add Email Label
Label emailLabel = new Label("E-Mail: ");
gridPane.add(emailLabel, 0, 2);
// Add Email Text Field
TextField email = new TextField();
email.setPrefHeight(40);
gridPane.add(email, 1, 2);
// Add Birthday Label
Label Geburtsdatum = new Label("Geburtsdatum : ");
gridPane.add(Geburtsdatum, 0, 3);
// Add Birhday Field
TextField geburtsdatum = new TextField();
geburtsdatum.setPrefHeight(40);
gridPane.add(geburtsdatum, 1, 3);
geburtsdatum.setText("Geburtsdatum");
// Add Submit Button
Button submitButton = new Button("Submit");
submitButton.setPrefHeight(40);
submitButton.setDefaultButton(true);
submitButton.setPrefWidth(100);
gridPane.add(submitButton, 0, 4, 2, 1);
GridPane.setHalignment(submitButton, HPos.CENTER);
GridPane.setMargin(submitButton, new Insets(20, 0,20,0));
submitButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
;
if(name.getText().isEmpty()) {
showAlert(Alert.AlertType.ERROR, gridPane.getScene().getWindow(), "Form Error!", "Please enter your name");
return;
}
if(email.getText().isEmpty()) {
showAlert(Alert.AlertType.ERROR, gridPane.getScene().getWindow(), "Form Error!", "Please enter your email id");
return;
}
if(geburtsdatum.getText().isEmpty()) {
showAlert(Alert.AlertType.ERROR, gridPane.getScene().getWindow(), "Form Error!", "Please enter a password");
return;
}
showAlert(Alert.AlertType.CONFIRMATION, gridPane.getScene().getWindow(), "Wir haben ihre Daten erhalten!", "Vielen dank für ihr Vertrauen " + name.getText());
}
});
}
private void showAlert(Alert.AlertType alertType, Window owner, String title, String message) {
Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.initOwner(owner);
alert.show();
}
public static void main(String[] args) {
launch(args);
}
}

In the handle method of submitButton.setOnAction you need to read the fields to create a new Person. This new Person than can be added to the ArrayList.
As long as you implement the buttons setOnAction Method in the same method, where you define the TextFields, this works well. But as soon as you move the buttons setOnAction implementation to another method, you need to define the TextFields as class "variables" (Fields!) to access them.

Related

How to block text field when user change database from drop down menu?

I have GUI app to connect with few databases and from every database I use different fields to connect. The main question is how I can disable fields depending on which database user will choose, for example like in the below picture when user chooses MySQL, fields like dbName and path to db are disabled.
But when user will choose other, for example SQLite, fields like localhost, port, username and password should be disabled. For now I disabled fields for MySQL but when I change to other databases the same fields are still disabled.
Below is my code:
private void choseFieldsWhichNeedToDb() {
String value = databaseChoiceBox.getValue();
if (value.equals("MySql")){
databaseNameTextField.setDisable(true);
databasePathTextField.setDisable(true);
}
}
private void fillChoiceBox() {
DatabaseType[] types = DatabaseType.values();
for (DatabaseType type : types) {
databaseChoiceBox.getItems().add(type.getType());
}
databaseChoiceBox.setValue("MySql");
}
Not a complete answer but hopefully enough to allow you to complete your app.
You need to create a ChangeListener that listens to changes in the ChoiceBox selected value and enable or disable the relevant TextFields according to the chosen value in the ChoiceBox.
The below code creates a GUI similar to that in your screen capture but only enables (or disables) the dbName and path text fields according to the selected database.
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class ChooseDb extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
GridPane root = new GridPane();
root.setHgap(10.0);
root.setVgap(10.0);
root.setPadding(new Insets(20, 20, 20, 20));
Label hostLabel = new Label("Host");
root.add(hostLabel, 0, 0);
TextField hostTextField = new TextField();
root.add(hostTextField, 1, 0);
Label portLabel = new Label("Port");
root.add(portLabel, 2, 0);
TextField portTextField = new TextField();
root.add(portTextField, 3, 0);
Label usernameLabel = new Label("Username");
root.add(usernameLabel, 0, 1);
TextField usernameTextField = new TextField();
root.add(usernameTextField, 1, 1);
Label passwordLabel = new Label("Password");
root.add(passwordLabel, 2, 1);
TextField passwordTextField = new TextField();
root.add(passwordTextField, 3, 1);
Label dbNameLabel = new Label("Database name");
root.add(dbNameLabel, 0, 2);
TextField dbNameTextField = new TextField();
dbNameTextField.setDisable(true);
root.add(dbNameTextField, 1, 2);
Label dbPathLabel = new Label("Path to database file");
root.add(dbPathLabel, 2, 2);
TextField dbPathTextField = new TextField();
dbPathTextField.setDisable(true);
root.add(dbPathTextField, 3, 2);
ChoiceBox<String> dbNames = new ChoiceBox<>(FXCollections.observableArrayList("MySQL", "SQLite"));
dbNames.setValue("MySQL");
dbNames.valueProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable,
String oldValue,
String newValue) {
switch (newValue) {
case "MySQL":
dbNameTextField.setDisable(true);
dbPathTextField.setDisable(true);
break;
case "SQLite":
dbNameTextField.setDisable(false);
dbPathTextField.setDisable(false);
break;
}
}
});
root.add(dbNames, 0, 3);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Cannot convert textfield into string

Hi I'm currenntly doing a coding exercise where I create an application with 2 views. Create in it an application with two views. The first view should have a text field that's used to ask for the user's name. The second view then shows the user a greeting text. The greeting should be of the form "Welcome name!" where the user's name is inserted in place of 'name'.
package application;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class GreeterApplication extends Application {
public static void main(String[] args) {
launch(GreeterApplication.class);
}
#Override
public void start(Stage window) throws Exception {
//1. Creating the view
//1.1 Creating components to be used
Label intro = new Label("Enter your name and start.");
Button start = new Button("start");
TextField input = new TextField();
//1.2 creating new layout
GridPane layout = new GridPane();
layout.add(intro, 0, 0);
layout.add(input, 0, 1);
layout.add(start, 0, 2);
// 1.3 Styling the layout
//1.4 creating view itself and setting it to use the layout
Scene first = new Scene(layout);
//2. Creating new view
StackPane welcome = new StackPane();
String name = input.getText();
Label welcomeText = new Label("Welcome " + input + "!"); //inpu
welcome.getChildren().add(welcomeText);
Scene welcomeView = new Scene(welcome);
//3. Adding event handler
start.setOnAction((event) -> {
if (!input.getText().isEmpty()) {
window.setScene(welcomeView);
}
});
window.setScene(first);
window.show();
}
}
I tried converting input into a string via input.getText() and input.toString() but I have had no success.
Kindly note the following edit.
Label welcomeText = new Label();
The text of the label should only be set after receiving the input from the user.
Hence, you can create a welcomeText Label and update its text value in the event handler using welcomeText.setText(input.getText()).

JavaFX GridPane Object Alignment

I am trying to use JavaFX to create a scene with the program's title positioned at the top-center, and buttons in a vertical line along the left side of the scene. However, both of these elements are displayed clustered up in the top-right of the scene, instead of where I want them to be.
How can I get these elements to be displayed where I want them to?
Here is how I try to set the program title's position:
grid.add(gameTitle, 0, 0);
GridPane.setHalignment(gameTitle, HPos.CENTER);
GridPane.setValignment(gameTitle, VPos.TOP);
I try to set the VBox object similarly:
grid.getChildren().add(buttonBox);
GridPane.setHalignment(buttonBox, HPos.LEFT);
GridPane.setValignment(buttonBox, VPos.CENTER);
This is what is displayed:
My entire MainMenu class. (This class is called in my Main class to construct the scene):
package scenes;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.application.Platform;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
public class MainMenu {
public Pane getMainMenuPane() {
// Create the scene grid
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
// Set the game title to the top center
Text gameTitle = new Text("Bandit King");
Font titleFont = new Font(75);
gameTitle.setFont(titleFont);
//
grid.add(gameTitle, 0, 0);
GridPane.setHalignment(gameTitle, HPos.CENTER);
GridPane.setValignment(gameTitle, VPos.TOP);
// Create Button objects and put in VBox
Button[] buttArr = makeButtons();
VBox buttonBox = new VBox();
buttonBox.getChildren().addAll(buttArr);
buttonBox.setSpacing(10);
// add Button VBox to GridPane
grid.getChildren().add(buttonBox);
GridPane.setHalignment(buttonBox, HPos.LEFT);
GridPane.setValignment(buttonBox, VPos.CENTER);
return (Pane) grid;
}
private Button[] makeButtons() {
// Create buttons
Button start = new Button("Start a New Game");
Button load = new Button("Load a Saved Game");
Button exit = new Button("Exit the Game");
// set Button actions
start.setOnAction( a -> {
System.out.println("WIP- start game.");
});
load.setOnAction( a -> {
System.out.println("WIP- load game");
});
exit.setOnAction( a -> {
Platform.exit();
System.exit(0);
});
// return Button[] array
Button[] buttArr = {start, load, exit};
return buttArr;
}
}
My Main class (Displays the scene):
package central;
import javafx.stage.Stage;
import scenes.*;
import controllers.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
public class Main extends Application {
// Get scene panes
private static Pane mainMenu = new MainMenu().getMainMenuPane();
// Create SceneController object.
private static Scene scene = new Scene(mainMenu, 1600, 900);
public static SceneController SceneControl = new SceneController(scene);
#Override
public void start(Stage stage) {
stage.setTitle("Bandit King");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The default cell you add the children of a GridPane to is (0, 0) which is what you do in this line:
grid.getChildren().add(buttonBox);
you need to change this to
grid.add(buttonBox, 0, 1);
to set the row index to 1. (There are alternatives to assigning the row index this way, but this is the most convenient option in this case.)
This won't result in the first column taking the full width of the GridPane though. If you also want the first column to take all the width available, you need to specify this by adding ColumnConstraints:
ColumnConstraints constraints = new ColumnConstraints();
constraints.setHgrow(Priority.ALWAYS);
grid.getColumnConstraints().add(constraints);
As far as what I noticed, you added all the nodes in a column and set there positions, but you did not specify how much the column needs to be stretched. GridPane column will not stretch automatically by itself unless specified.
You can debug your program, by enabling the gridLinesVisible of GridPane property to true.
grid.setGridLinesVisible(true);
You need to specify the columnConstraints, to let the GridPane column stretch to the available width.
ColumnConstraints constraint = new ColumnConstraints();
constraint.setHgrow(Priority.ALWAYS);
grid.getColumnConstraints().add(constraint);

Extracting text from dynamically created textfields inside various rows of gridpane

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.
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!
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 (in each row of the second/1th column) -> vboxgrid2 (along with vboxgrid1 above it for the radiobutton row in mainVBox) -> innerRowbox -> name (textfield)
If it's difficult to understand the nesting of all my nodes
Since you do seem to realize that your nesting is a bit confusing, it would be preferable to save the TextFields 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: since you use index 1 you access the second row, not the first one.
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();
}
In the demo app, I added a List<TextField> textFieldContainer = new ArrayList(); that stores the dynamically create TextFields.
The code below delete the appropriate TextFields if the numbers change and Enter is pressed.
textFieldContainer.removeIf(p -> p.getUserData().toString().startsWith("TextField_" + tempRow));
Full Code:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
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 {
List<TextField> textFieldContainer = new ArrayList();
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);
final Integer tempRow = i;
howManytxtB.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
vboxgrid2.getChildren().clear();
Integer howManyNum = Integer.valueOf(howManytxtB.getText());
//The next two lines clears TextFields if you change the amount and/or press enter
textFieldContainer.removeIf(p -> p.getUserData().toString().startsWith("TextField_" + tempRow));
for(int row=0;row<howManyNum;row++) {
//creating rows for entering the new entities
HBox innerRowbox = new HBox();
TextField name = new TextField();
final Integer innerRow = row;
name.setUserData("TextField_" + tempRow + "_" + innerRow);
System.out.println(name.getUserData().toString());
textFieldContainer.add(name);
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-> {
System.out.println("Saving these TextField's Text:");
for(TextField textField : textFieldContainer)
{
System.out.println(textField.getUserData() + ": " + textField.getText());
}
});
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);
}
}
Output:
Click save content to see the info currently in the TextFields.
Saving these TextField's Text:
TextField_0_0: one
TextField_1_0: two
TextField_1_1: three
TextField_2_0: four
TextField_3_0: seven
TextField_3_1: six
TextField_4_0: five

Java dynamically add items to a listview

Hey guys I have this small problem. I'm a newbie to Java and I just want to figure out "how to add another item at the end of the list view below in my code". This should happen dynamically while the program is running. I just wanna click that appropriate space at the bottom of the listview and just add an item. Could someone please help me on this concern. thanks!
Note: Run the application and everything will appear there. I just want to add functionalities to these buttons. When I click "Add" button, i should be able to add more items.
package layoutsizingaligning;
import java.util.Scanner;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.control.Control;
import javafx.scene.Scene;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.PasswordField;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
/**
* Sample application that shows how the sized of controls can be managed.
* Sample is for demonstration purposes only, most controls are inactive.
*/
public class LayoutSizingAligning extends Application {
// Define buttons here for access by multiple methods
private Button btnApply = new Button("Apply");
private Button btnContinue = new Button("Continue");
private Button btnExit = new Button("Exit");
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(LayoutSizingAligning.class, args);
}
//#Override
public void start(Stage primaryStage) {
// Make Exit button bigger by using larger font for label
//btnExit.setStyle("-fx-font-size: 12pt;");
// Use tab pane with one tab for sizing UI and one tab for alignment UI
TabPane tabs = new TabPane();
Tab tabSize = new Tab();
tabSize.setText("Sizing");
tabSize.setContent(sizingSample());
Tab tabAlign = new Tab();
tabAlign.setText("Alignment");
tabAlign.setContent(alignmentSample());
tabs.getTabs().addAll(tabSize, tabAlign);
Scene scene = new Scene(tabs, 300, 400); // Manage scene size
primaryStage.setTitle("Sizing and Aligning");
primaryStage.setScene(scene);
primaryStage.show();
}
/*
* Creates the UI for the sizing sample, which demonstrates ways to manage
* the size of controls when you don't want the default sizes.
*/
private Pane sizingSample() {
BorderPane border = new BorderPane();
border.setPadding(new Insets(20, 0, 20, 20));
ListView<String> lvList = new ListView<String>();
ObservableList<String> items = FXCollections.observableArrayList (
"Hot dog", "Hamburger", "French fries",
"Carrot sticks", "Chicken salad");
// Scanner scan = new Scanner(System.in);
// String s = scan.next();
// items.add(s);
lvList.setItems(items);
lvList.setMaxHeight(Control.USE_PREF_SIZE);
lvList.setPrefWidth(150.0);
border.setLeft(lvList);
border.setRight(createButtonColumn());
border.setBottom(createButtonRow()); // Uses a tile pane for sizing
// border.setBottom(createButtonBox()); // Uses an HBox, no sizing
return border;
}
/*
* Creates the UI for the alignment sample, which demonstrates ways to manage
* the alignment of controls when you don't want the default alignment.
*/
private Pane alignmentSample() {
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER); // Override default
grid.setHgap(10);
grid.setVgap(12);
// Use column constraints to set properties for columns in the grid
ColumnConstraints column1 = new ColumnConstraints();
column1.setHalignment(HPos.RIGHT); // Override default
grid.getColumnConstraints().add(column1);
ColumnConstraints column2 = new ColumnConstraints();
column2.setHalignment(HPos.LEFT); // Override default
grid.getColumnConstraints().add(column2);
HBox hbButtons = new HBox();
hbButtons.setSpacing(10.0);
hbButtons.setAlignment(Pos.CENTER); // Aligns HBox and controls in HBox
Button btnSubmit = new Button("Submit");
Button btnClear = new Button("Clear");
Button btnExit2 = new Button("Exit");
//btnSubmit.setStyle("-fx-font-size: 15pt;");
Label lblName = new Label("User name:");
TextField tfName = new TextField();
Label lblPwd = new Label("Password:");
PasswordField pfPwd = new PasswordField();
hbButtons.getChildren().addAll(btnSubmit, btnClear, btnExit2);
grid.add(lblName, 0, 0);
grid.add(tfName, 1, 0);
grid.add(lblPwd, 0, 1);
grid.add(pfPwd, 1, 1);
grid.add(hbButtons, 0, 2, 2, 1);
/* Uncomment the following statements to bottom-align the buttons */
// hbButtons.setAlignment(Pos.BOTTOM_CENTER);
// GridPane innergrid = new GridPane();
// innergrid.setAlignment(Pos.CENTER);
// innergrid.add(hbButtons, 0, 0);
// grid.add(innergrid, 0, 2, 2, 1);
return grid;
}
/*
* Creates a column of buttons and makes them all the same width as the
* largest button.
*/
private VBox createButtonColumn() {
Button btnAdd = new Button("Add");
Button btnDelete = new Button("Delete");
Button btnMoveUp = new Button("Move Up");
Button btnMoveDown = new Button("Move Down");
// Comment out the following statements to see the default button sizes
btnAdd.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnDelete.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnMoveUp.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnMoveDown.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnMoveDown.setMinWidth(Control.USE_PREF_SIZE);
btnAdd.setOnAction(new EventHandler<ActionEvent>() {
//#Override
public void handle(ActionEvent event) {
Scanner scan = new Scanner(System.in);
String s = scan.next();
}
});
VBox vbButtons = new VBox();
vbButtons.setSpacing(10);
vbButtons.setPadding(new Insets(0, 20, 10, 20));
vbButtons.getChildren().addAll(
btnAdd, btnDelete, btnMoveUp, btnMoveDown);
return vbButtons;
}
/*
* Creates a row of buttons and makes them all the same size.
*/
private TilePane createButtonRow() {
// Let buttons grow, otherwise they will be different sizes based
// on the length of the label
btnApply.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnContinue.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnExit.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
btnExit.setOnAction(new EventHandler<ActionEvent>() {
//#Override
public void handle(ActionEvent event) {
System.exit(0);
}
});
TilePane tileButtons = new TilePane(Orientation.HORIZONTAL);
tileButtons.setPadding(new Insets(20, 10, 20, 0));
tileButtons.setHgap(10.0);
tileButtons.setVgap(8.0); // In case window is reduced and buttons
// require another row
tileButtons.getChildren().addAll(btnApply, btnContinue, btnExit);
return tileButtons;
}
/*
* Creates a row of buttons with the default sizes.
*/
private HBox createButtonBox() {
HBox hbButtons = new HBox();
hbButtons.setSpacing(10);
hbButtons.setPadding(new Insets(20, 10, 20, 0));
hbButtons.getChildren().addAll(btnApply, btnContinue, btnExit);
return hbButtons;
}
}
First of all, you need to put your ListView in an accessible place, so that you can find the reference again later. Thus, do not declare it as a local variable, but as a field.
Then, to add an item, you simply do:
listview.getItems().add("some new element");

Categories

Resources