Java dynamically add items to a listview - java

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");

Related

Why are my JavaFX buttons unevenly spaced?

I'm new to JavaFX, trying to build a GUI program that displays a bill for a table at a restaurant when you click on that table. The spacing is off between the table buttons and I'm not sure why.
The GUI class for my program:
package restaurantBillingProgram;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
public class BillingGUI extends Application {
#Override
public void start(Stage primaryStage) {
// Create grid pane
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setHgap(5);
pane.setVgap(5);
// Label
pane.add(new Label("Generate bill"), 1, 0);
// Buttons
Button btT1 = new Button("Table 1");
pane.add(btT1, 0, 1);
btT1.setOnAction(e - > Billing.generateT1());
Button btT2 = new Button("Table 2");
pane.add(btT2, 1, 1);
btT2.setOnAction(e - > Billing.generateT2());
Button btT3 = new Button("Table 3");
pane.add(btT3, 2, 1);
btT3.setOnAction(e - > Billing.generateT3());
// Create scene and place in stage
Scene scene = new Scene(pane, 250, 250);
primaryStage.setTitle("Restaurant Billing Program");
primaryStage.setScene(scene);
primaryStage.show();
}
// Main method
public static void main(String[] args) {
launch(args);
}
}
From the Javadoc:
Row/Column Sizing
By default, rows and columns will be sized to fit their content; a column will be wide enough to accommodate the widest child, ...
The label in row 0 column 1 forces that column to be wider.
You probably want the label to be centered and span all 3 columns.
While doing you layout, use pane.setGridLinesVisible(true). This should only be used during debugging. It can be very useful for situations like your current situation. As #Jim Garrison pointed out, your Label is causing the issue:
Issue:
One way to fix this is to let the Label span all columns and center the Label's text.
Fix:
Key Code:
label.setMaxWidth(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
pane.add(label, 0, 0, 3, 1);// Look at the following link to see how this add method works. https://openjfx.io/javadoc/11/javafx.graphics/javafx/scene/layout/GridPane.html#add(javafx.scene.Node,int,int,int,int)
Full Code:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
public class BillingGUI extends Application {
#Override
public void start(Stage primaryStage) {
// Create grid pane
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setHgap(5);
pane.setVgap(5);
pane.setGridLinesVisible(true);//Use for debugging only!!!!
// Label
Label label = new Label("Generate bill");
label.setMaxWidth(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
pane.add(label, 0, 0, 3, 1);
// Buttons
Button btT1 = new Button("Table 1");
pane.add(btT1, 0, 1);
Button btT2 = new Button("Table 2");
pane.add(btT2, 1, 1);
Button btT3 = new Button("Table 3");
pane.add(btT3, 2, 1);
// Create scene and place in stage
Scene scene = new Scene(pane, 250, 250);
primaryStage.setTitle("Restaurant Billing Program");
primaryStage.setScene(scene);
primaryStage.show();
}
// Main method
public static void main(String[] args) {
launch(args);
}
}

Animate adding components to a pane

I want to implement some kind of notification system in my application but I have trouble with the calculation of the actual position of my notification. All notifications should appear in a separate stage and each notification should be aligned among themselves and each notification is a simple VBox with two labels (title and message).
I created a little standalone application with the issue I have.
As soon as you press the button on the main stage, a VBox will be created and added to a second notification stage. As soon as a seconds notification needs to be added, this second notification should be below the first notification and so on. Therefore I need to find the height of the first notification in order to position the second notification underneath.
I know I could use a VBox instead, but in my application the notification should make a smooth animation and push the other notifications further down. I removed the whole animation and removing part of notifications so the example stays as small as possible.
The problem is that all notification boxes have the same height - but they don't (if you modify the text and make it longer / smaller).
package whatever;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class NotificationTest {
private Stage notificationStage;
private Pane contentPane;
private static final Integer NOTIFICATION_WIDTH = 250;
private Double notificationOffset = 0.0;
private static final Integer SPACING_BETWEEN_NOTIFICATIONS = 20;
public void start() {
Stage mainStage = new Stage();
TextField textField = new TextField("Some long text for testing purpose with even more letters in oder to create at least one linebreak...");
Button button = new Button("Add Notification");
button.setOnAction(actionEvent -> {
addNotification(textField.getText());
});
VBox vBox = new VBox(10);
vBox.getChildren().addAll(textField, button);
mainStage.setScene(new Scene(vBox, 300, 300));
mainStage.show();
}
private void addNotification(String text) {
if(notificationStage == null) {
notificationStage = new Stage();
notificationStage.setWidth(NOTIFICATION_WIDTH);
notificationStage.setHeight(Screen.getPrimary().getVisualBounds().getHeight() - 50);
notificationStage.setX(Screen.getPrimary().getVisualBounds().getWidth() - 260);
notificationStage.setY(50);
contentPane = new Pane();
contentPane.setStyle("-fx-background-color: transparent");
notificationStage.setScene(new Scene(contentPane));
notificationStage.initStyle(StageStyle.TRANSPARENT);
notificationStage.getScene().setFill(Color.TRANSPARENT);
notificationStage.show();
}
VBox notificationBox = new VBox(10);
notificationBox.setMaxWidth(NOTIFICATION_WIDTH);
notificationBox.setMinWidth(NOTIFICATION_WIDTH);
notificationBox.setStyle("-fx-background-radius: 10; -fx-background-color: red");
notificationBox.getChildren().add(new Label("Title of Notification"));
Label message = new Label(text);
message.setWrapText(true);
notificationBox.getChildren().add(message);
notificationBox.setLayoutY(notificationOffset);
contentPane.getChildren().add(notificationBox);
// Needs to be done - otherwise the height would be 0
contentPane.layout();
System.out.println(notificationBox.getHeight());
notificationOffset += notificationBox.getHeight() + SPACING_BETWEEN_NOTIFICATIONS;
}
}
I used the ScenicView Tool to verify the height and it says that the height is 79, but the System.out tells me the height is 10.4. The 79 value seems to be correct, but how can I get this value in my application?
The short answer is use applyCss():
contentPane.applyCss();
contentPane.layout();
From the documentation:
If required, apply styles to this Node and its children, if any. This
method does not normally need to be invoked directly but may be used
in conjunction with Parent.layout() to size a Node before the next
pulse
The long and better answer is to use a VBox or a ListView.
To add layout animation use LayoutAnimator.java. You can find more details here.
Edit: an mre of using LayoutAnimator to animate newly added notifications:
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class NotificationTest extends Application {
private Stage notificationStage;
private Pane contentPane;
private static final int NOTIFICATION_WIDTH = 250, SPACING_BETWEEN_NOTIFICATIONS = 20;
private static final String LONG_TEXT = "Some long text for testing purpose with even more letters in oder to create "
+ "at least one linebreak...";
private int counter = 0;
#Override
public void start(Stage mainStage) throws Exception {
mainStage = new Stage();
TextField textField = new TextField(LONG_TEXT);
Button button = new Button("Add Notification");
button.setOnAction(actionEvent -> {
addNotification(textField.getText());
});
VBox vBox = new VBox(10, textField, button);
mainStage.setScene(new Scene(vBox, 300, 300));
mainStage.show();
}
private void addNotification(String text) {
if(notificationStage == null) {
notificationStage = new Stage();
notificationStage.setWidth(NOTIFICATION_WIDTH);
notificationStage.setX(Screen.getPrimary().getVisualBounds().getWidth() - 260);
notificationStage.setY(50);
contentPane = new VBox(SPACING_BETWEEN_NOTIFICATIONS);
contentPane.setStyle("-fx-background-color: transparent");
notificationStage.setScene(new Scene(contentPane));
notificationStage.initStyle(StageStyle.TRANSPARENT);
//animate using LayoutAnimator https://gist.github.com/jewelsea/5683558
LayoutAnimator ly = new LayoutAnimator();
ly.observe(contentPane.getChildren());
notificationStage.show();
}
VBox notificationBox = new VBox(10);
notificationBox.setMaxWidth(NOTIFICATION_WIDTH);
notificationBox.setMinWidth(NOTIFICATION_WIDTH);
notificationBox.setStyle("-fx-border-color: black");
notificationBox.getChildren().add(new Label("Title of Notification"));
Label message = new Label(counter++ + ": " +text);
message.setWrapText(true);
notificationBox.getChildren().add(message);
contentPane.getChildren().add(0, notificationBox);
}
public static void main(String[] args) {
launch(null);
}
}

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);
}
}

Add Java FX form data to ArrayList

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.

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);

Categories

Resources