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