From 231cf31911250f2cb0ef2a8f4bfd03a18446ddd3 Mon Sep 17 00:00:00 2001 From: Harry Linrui XU <xulr0820@hotmail.com> Date: Thu, 23 Mar 2023 18:23:34 +0100 Subject: [PATCH] Attempted to make expense and income the same class. Made new dialog box for income. Made new enum to distinguish between incoem and expense --- .../demo/controller/AddExpenseController.java | 12 +- .../demo/controller/AddIncomeController.java | 124 ++++++++++++ .../demo/controller/ExpensesController.java | 184 ++++++++++++------ src/main/resources/view/AddIncome.fxml | 89 ++++----- 4 files changed, 301 insertions(+), 108 deletions(-) create mode 100644 src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java index 0a0edcfc..21d8bc4f 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java @@ -17,10 +17,18 @@ import javafx.scene.control.TextField; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Economics.Expense; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; +import no.ntnu.idatt1002.demo.data.Economics.Income; + public class AddExpenseController { Expense newExpense = null; //the expense that is chosen when editing or the expense that is created when adding Expense chosenExpense = null; //an expense that is meant to track the old state of an expense before editing, in case cancel bugtton is clicked + + Income newIncome = null; + + Income chosenIncome = null; + + private ItemMode itemMode; @FXML private Button cancelBtn; @@ -55,9 +63,6 @@ public class AddExpenseController { ObservableList<Boolean> recurring = FXCollections.observableArrayList(true, false); recurringBox.setItems(recurring); recurringBox.setValue(false); - - System.out.print("This is in initialize"); - System.out.println(descriptionField); } public ExpenseCategory getCategory() { @@ -79,7 +84,6 @@ public class AddExpenseController { amountField.textProperty().setValue(String.valueOf(expense.getAmount())); recurringBox.setValue(expense.isRecurring()); - //new SimpleStringProperty(datePicker.getValue().toString()).bindBidirectional(new SimpleStringProperty(expense.getDate().toString())); //Bind this expense's fields with the argument object's fields. If cancel is pressed - do nothing. If ok is pressed, bind the textfields with this expsense diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java new file mode 100644 index 00000000..dc677df6 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java @@ -0,0 +1,124 @@ +package no.ntnu.idatt1002.demo.controller; + +import java.text.NumberFormat; +import java.time.LocalDate; + +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.DatePicker; +import javafx.scene.control.TextField; +import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Economics.Expense; +import no.ntnu.idatt1002.demo.data.Economics.Income; +import no.ntnu.idatt1002.demo.data.Economics.IncomeCategory; + +public class AddIncomeController { + + Income newIncome = null; + + Income chosenIncome = null; + + private ItemMode itemMode; + @FXML + private Button cancelBtn; + + @FXML + private Button okBtn; + + @FXML + private TextField dateField; + + @FXML + private DatePicker datePicker; + + @FXML + private TextField descriptionField; + + @FXML + private TextField amountField; + + @FXML + private ComboBox<IncomeCategory> categoryBox; + + @FXML + private ComboBox<Boolean> recurringBox; + + @FXML + public void initialize() { + ObservableList<IncomeCategory> incomeCategories = FXCollections.observableArrayList( + IncomeCategory.values()); + categoryBox.setItems(incomeCategories); + categoryBox.setValue(IncomeCategory.GIFT); + + ObservableList<Boolean> recurring = FXCollections.observableArrayList(true, false); + recurringBox.setItems(recurring); + recurringBox.setValue(false); + } + + public IncomeCategory getCategory() { + return categoryBox.getValue(); + } + + public boolean isRecurring() { + return recurringBox.getValue();//.equals("Yes"); + } + + public void setIncome(Income income) { //TODO NEED CANCEL BUTTON TO REMOVE THE CHANGES IF CANCEL IS PRESSED + chosenIncome = new Income(income.getDescription(), income.getAmount(), income.isRecurring(), income.getCategory(), income.getDate()); + chosenIncome.descriptionProperty().bindBidirectional(income.descriptionProperty()); + chosenIncome.amountProperty().bindBidirectional(income.amountProperty()); + chosenIncome.recurringProperty().bindBidirectional(income.recurringProperty()); + //chosenExpense.().bindBidirectional(income.descriptionProperty()); + //chosenExpense.().bindBidirectional(income.descriptionProperty()); + descriptionField.textProperty().set(income.getDescription()); + amountField.textProperty().setValue(String.valueOf(income.getAmount())); + recurringBox.setValue(income.isRecurring()); + + //new SimpleStringProperty(datePicker.getValue().toString()).bindBidirectional(new SimpleStringProperty(income.getDate().toString())); + //Bind this income's fields with the argument object's fields. If cancel is pressed - do nothing. If ok is pressed, bind the textfields with this expsense + + /*amountField.textProperty().bindBidirectional(income.amountProperty(), NumberFormat.getNumberInstance()); //TODO AMOUNT IS STORED WITH COMMA, WHICH IS NOT ALLOWED + descriptionField.textProperty().bindBidirectional(income.descriptionProperty()); + //categoryBox.valueProperty().bindBidirectional(income.getCategory()); + recurringBox.valueProperty().bindBidirectional(income.recurringProperty());*/ + } + + @FXML + public void pressOkBtn(ActionEvent event) { + if (chosenIncome == null) { + LocalDate date = datePicker.getValue(); + double amount = Double.parseDouble(amountField.getText()); + String description = descriptionField.getText(); + IncomeCategory category = getCategory(); + boolean recurring = isRecurring(); + newIncome = new Income(description, amount, recurring, category, date); + } + if (chosenIncome != null) { + chosenIncome.setDescription((descriptionField.getText())); + chosenIncome.setAmount(Double.parseDouble(amountField.getText())); + chosenIncome.setRecurring(recurringBox.getValue()); + } + + final Node source = (Node) event.getSource(); + ((Stage) source.getScene().getWindow()).close(); + } + + @FXML + public void pressCancelBtn(ActionEvent event) { + final Node source = (Node) event.getSource(); + final Stage stage = (Stage) source.getScene().getWindow(); + + stage.close(); + } + + public Income getNewIncome() { + return this.chosenIncome; + } +} \ No newline at end of file diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java index 0c069860..10828491 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java @@ -1,10 +1,7 @@ package no.ntnu.idatt1002.demo.controller; -import java.io.File; import java.io.IOException; -import java.time.LocalDate; -import java.time.Month; import java.util.Optional; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -22,7 +19,6 @@ import javafx.scene.control.ComboBox; import javafx.scene.control.Dialog; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; -import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.stage.Modality; import javafx.stage.Stage; @@ -32,17 +28,25 @@ import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister; import no.ntnu.idatt1002.demo.data.Economics.FileHandling; import no.ntnu.idatt1002.demo.data.Economics.Income; import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; +import no.ntnu.idatt1002.demo.data.Economics.Item; +import no.ntnu.idatt1002.demo.data.Economics.ItemRegister; enum DialogMode { ADD, EDIT, DELETE } + +enum ItemMode { + INCOME, EXPENSE +} + public class ExpensesController { /** * The mode of the dialog. NEW if new contact, EDIT if edit existing contact. */ - private DialogMode mode; + private DialogMode dialogMode; + private ItemMode itemMode; @FXML private Button addBtn; @FXML @@ -81,47 +85,40 @@ public class ExpensesController { private TableView<Expense> expenseTableView; @FXML - private TableView<Expense> incomeTableView; + private TableView<Income> incomeTableView; ExpenseRegister expenseRegister; ObservableList<Expense> expenses; + ObservableList<String> filter; + + //ItemRegister itemRegister; IncomeRegister incomeRegister; ObservableList<Income> income; @FXML public void initialize() throws IOException { //TODO SAME REGISTER FOR BOTH, BUT LOAD DIFFERENT DATA DEPENDING ON WHICH IT IS - if (expenseTableView.getColumns() != null) { - ObservableList<String> filter = FXCollections.observableArrayList("All", "Food", "Clothes", "Books", "Other", "Fixed expense"); - show.setItems(filter); - show.setValue("All"); - - expenseRegister = loadDataFromFile("Expense"); - expenses = FXCollections.observableArrayList(expenseRegister.getItems()); - dateColumn.setCellValueFactory(new PropertyValueFactory<Expense, String>("date")); amountColumn.setCellValueFactory(new PropertyValueFactory<Expense, Double>("amount")); categoryColumn.setCellValueFactory(new PropertyValueFactory<Expense, ExpenseCategory>("category")); descriptionColumn.setCellValueFactory(new PropertyValueFactory<Expense, String>("description")); recurringColumn.setCellValueFactory(new PropertyValueFactory<Expense, Boolean>("recurring")); - expenseTableView.setItems(expenses); - } else { - ObservableList<String> filter = FXCollections.observableArrayList("All", "Salary", "Student loan", "Gift", "Fixed expense"); - show.setItems(filter); - show.setValue("All"); - - expenseRegister = loadDataFromFile("Income"); + if (expenseTableView != null) { + itemMode = ItemMode.EXPENSE; + filter = FXCollections.observableArrayList("All", "Food", "Clothes", "Books", "Other", "Fixed expense"); + expenseRegister = loadExpenseDataFromFile("Expense"); expenses = FXCollections.observableArrayList(expenseRegister.getItems()); - - dateColumn.setCellValueFactory(new PropertyValueFactory<Expense, String>("date")); - amountColumn.setCellValueFactory(new PropertyValueFactory<Expense, Double>("amount")); - categoryColumn.setCellValueFactory(new PropertyValueFactory<Expense, ExpenseCategory>("category")); - descriptionColumn.setCellValueFactory(new PropertyValueFactory<Expense, String>("description")); - recurringColumn.setCellValueFactory(new PropertyValueFactory<Expense, Boolean>("recurring")); - expenseTableView.setItems(expenses); + } else { + itemMode = ItemMode.INCOME; + filter = FXCollections.observableArrayList("All", "Salary", "Student loan", "Gift", "Fixed expense"); + incomeRegister = loadIncomeDataFromFile("Income"); + income = FXCollections.observableArrayList(incomeRegister.getItems()); + incomeTableView.setItems(income); } + show.setItems(filter); + show.setValue("All"); } @FXML @@ -130,10 +127,16 @@ public class ExpensesController { } @FXML protected void handleEditButton(ActionEvent event) { + FXMLLoader loader = new FXMLLoader(); + if (itemMode == ItemMode.EXPENSE) { + loader.setLocation(getClass().getResource("/view/AddExpense.fxml")); + } else { + loader.setLocation(getClass().getResource("/view/AddIncome.fxml")); + } Expense newExpense = null; + Income newIncome = null; String dialogTitle = ""; // Load the FXML file for your dialog box - FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/AddExpense.fxml")); Dialog<Expense> dialog = new Dialog<>(); dialog.initModality(Modality.APPLICATION_MODAL); @@ -146,51 +149,88 @@ public class ExpensesController { // Get the controller for the loaded FXML file AddExpenseController dialogController = loader.getController(); + AddIncomeController dialogController1 = loader.getController(); - if (event.getSource().equals(addBtn)) { - mode = DialogMode.ADD; - dialogTitle = "Add expense"; - + if (itemMode == ItemMode.EXPENSE) { + if (event.getSource().equals(addBtn)) { + dialogMode = DialogMode.ADD; + dialogTitle = "Add expense"; } else if (event.getSource().equals(editBtn) && expenseTableView.getSelectionModel().getSelectedItem() != null) { - mode = DialogMode.EDIT; - dialogTitle = "Edit expense"; - newExpense = expenseTableView.getSelectionModel().getSelectedItem(); - dialogController.setExpense(newExpense); + dialogMode = DialogMode.EDIT; + dialogTitle = "Edit expense"; + newExpense = expenseTableView.getSelectionModel().getSelectedItem(); + dialogController.setExpense(newExpense); + } else { + return; + } } else { - return; + if (event.getSource().equals(addBtn)) { + dialogMode = DialogMode.ADD; + dialogTitle = "Income"; + } else if (event.getSource().equals(editBtn) && incomeTableView.getSelectionModel().getSelectedItem() != null) { + dialogMode = DialogMode.EDIT; + dialogTitle = "Edit income"; + newIncome = incomeTableView.getSelectionModel().getSelectedItem(); + dialogController1.setIncome(newIncome); //TODO NEED TO FXI THIS TO INCOME + } else { + return; + } } dialog.setTitle(dialogTitle); // Show the Dialog and wait for the user to close it - dialog.showAndWait(); //Get the newly created expense from the dialog pane - newExpense = dialogController.getNewExpense(); - //Only add the expense to the tableview, if the expense is not null - if (newExpense != null && mode == DialogMode.ADD) { - expenseRegister.addItem(newExpense); - refreshObservableList(); + + if (itemMode == ItemMode.EXPENSE) { + newExpense = dialogController.getNewExpense(); + if (newExpense != null && dialogMode == DialogMode.ADD) { + expenseRegister.addItem(newExpense); + refreshObservableList(); + } } else { + newIncome = dialogController1.getNewIncome(); //TODO NEED TO FIX to newIncome + if (newIncome != null && dialogMode == DialogMode.ADD) { //TODO NEED TO FIX TO NEW INCOME + incomeRegister.addItem(newIncome); //TODO NEED TO FIX TO NEW INCOME + refreshObservableList(); + } + } + //Only add the expense to the tableview, if the expense is not null } @FXML public void handleDeleteBtn(ActionEvent event) { - Expense chosenExpense = expenseTableView.getSelectionModel().getSelectedItem(); - if (chosenExpense == null) { - return; - } - Optional<ButtonType> isConfirmed = showConfirmationDialog(); - if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { - expenseRegister.removeItem(chosenExpense); - refreshObservableList(); + if (itemMode == ItemMode.EXPENSE) { + Expense chosenExpense = expenseTableView.getSelectionModel().getSelectedItem(); + if (chosenExpense == null) { + return; + } + Optional<ButtonType> isConfirmed = showConfirmationDialog(); + if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { + expenseRegister.removeItem(chosenExpense); + refreshObservableList(); + } + } else { + Income chosenIncome = incomeTableView.getSelectionModel().getSelectedItem(); + if (chosenIncome == null) { + return; + } + Optional<ButtonType> isConfirmed = showConfirmationDialog(); + if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { + incomeRegister.removeItem(chosenIncome); + refreshObservableList(); + } } } protected void refreshObservableList() { - this.expenses.setAll(expenseRegister.getItems()); - + if (itemMode == ItemMode.EXPENSE) { + this.expenses.setAll(expenseRegister.getItems()); + } else { + this.income.setAll(incomeRegister.getItems()); + } } @@ -203,7 +243,8 @@ public class ExpensesController { return alert.showAndWait(); } - public ExpenseRegister loadDataFromFile(String fileName) throws IOException { + public ExpenseRegister loadExpenseDataFromFile(String fileName) throws IOException { + //ItemRegister<T extends Item> FileHandling fileHandling = new FileHandling(); if (fileHandling.isEmpty(fileName)) { expenseRegister = new ExpenseRegister(); @@ -217,14 +258,39 @@ public class ExpensesController { return expenseRegister; } + public IncomeRegister loadIncomeDataFromFile(String fileName) throws IOException { + FileHandling fileHandling = new FileHandling(); + if (fileHandling.isEmpty(fileName)) { + incomeRegister = new IncomeRegister(); + } else { + try { + incomeRegister = fileHandling.readIncomeRegisterFromFile(fileName); + } catch (IOException e) { + e.printStackTrace(); + } + } + return incomeRegister; + } + + + public void saveDataToFile(String fileName) throws IOException { FileHandling fileHandling = new FileHandling(); - fileHandling.writeItemRegisterToFile(expenseRegister, fileName); + if (itemMode == ItemMode.EXPENSE) { + fileHandling.writeItemRegisterToFile(expenseRegister, fileName); } + else { + fileHandling.writeItemRegisterToFile(incomeRegister, fileName); } } @FXML public void switchScene(ActionEvent event) throws IOException { - saveDataToFile("Expense"); + if (itemMode == ItemMode.EXPENSE) { + saveDataToFile("Expense"); + } + else { + saveDataToFile("Income"); + } + FXMLLoader loader = new FXMLLoader(); if (event.getSource() == incomeBtn) { loader.setLocation(SceneController.class.getResource("/view/Income.fxml")); @@ -233,10 +299,12 @@ public class ExpensesController { } else if (event.getSource() == returnBtn) { loader.setLocation(SceneController.class.getResource("/view/FirstMenu.fxml")); } + Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); + } } -} + diff --git a/src/main/resources/view/AddIncome.fxml b/src/main/resources/view/AddIncome.fxml index 097992b0..be30573f 100644 --- a/src/main/resources/view/AddIncome.fxml +++ b/src/main/resources/view/AddIncome.fxml @@ -3,55 +3,52 @@ <?import javafx.geometry.Insets?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.DatePicker?> +<?import javafx.scene.control.DialogPane?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.TextField?> <?import javafx.scene.layout.ColumnConstraints?> <?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.RowConstraints?> -<GridPane hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SceneController"> - <columnConstraints> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="10.0" prefWidth="11.0" /> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="189.0" minWidth="10.0" prefWidth="189.0" /> - </columnConstraints> - <rowConstraints> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - </rowConstraints> - <padding> - <Insets bottom="10.0" left="10.0" top="20.0" /> - </padding> - <children> - <Label text="Date:" /> - <Label text="Amount:" GridPane.rowIndex="1" /> - <Label text="Description:" GridPane.rowIndex="2" /> - <Label text="Category" GridPane.rowIndex="3"> - <GridPane.margin> - <Insets /> - </GridPane.margin> - </Label> - <TextField promptText="Date" GridPane.columnIndex="1" GridPane.columnSpan="2" /> - <TextField promptText="Amount" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="1" /> - <TextField promptText="Description (optional)" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="2" /> - <ComboBox prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="3"> - <GridPane.margin> - <Insets /> - </GridPane.margin> - </ComboBox> - <Button mnemonicParsing="false" onAction="#closeButton" text="Cancel" GridPane.columnIndex="3" GridPane.rowIndex="4"> - <GridPane.margin> - <Insets left="75.0" /> - </GridPane.margin> - </Button> - <Button mnemonicParsing="false" onAction="#closeButton" text="Button" GridPane.columnIndex="3" GridPane.rowIndex="4"> - <GridPane.margin> - <Insets left="130.0" /> - </GridPane.margin> - </Button> - </children> -</GridPane> +<DialogPane expanded="true" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.AddExpenseController"> + <content> + <GridPane> + <columnConstraints> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> + </columnConstraints> + <rowConstraints> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + </rowConstraints> + <children> + <Label text="Date:" /> + <Label text="Amount:" GridPane.rowIndex="1" /> + <Label text="Description:" GridPane.rowIndex="2" /> + <Label text="Category" GridPane.rowIndex="3" /> + <Label text="Recurring" GridPane.rowIndex="4" /> + <TextField fx:id="amountField" promptText="100" GridPane.columnIndex="1" GridPane.rowIndex="1" /> + <TextField fx:id="descriptionField" promptText="(optional)" GridPane.columnIndex="1" GridPane.rowIndex="2" /> + <ComboBox fx:id="categoryBox" prefWidth="150.0" promptText="Choose" GridPane.columnIndex="1" GridPane.rowIndex="3" /> + <ComboBox fx:id="recurringBox" prefWidth="150.0" promptText="No" GridPane.columnIndex="1" GridPane.rowIndex="4" /> + <HBox alignment="BOTTOM_RIGHT" prefHeight="100.0" prefWidth="200.0" spacing="10.0" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="5"> + <children> + <Button fx:id="cancelBtn" mnemonicParsing="false" onAction="#pressCancelBtn" prefHeight="25.0" prefWidth="60.0" text="Cancel" /> + <Button fx:id="okBtn" mnemonicParsing="false" onAction="#pressOkBtn" prefHeight="25.0" prefWidth="60.0" text="OK" /> + </children> + <GridPane.margin> + <Insets top="20.0" /> + </GridPane.margin> + </HBox> + <DatePicker fx:id="datePicker" GridPane.columnIndex="1" /> + </children> + </GridPane> + </content> +</DialogPane> -- GitLab