diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..bee94ecc1da78ef1f1d6715889db951cf3067a3e --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +############################## +## Java +############################## +.mtj.tmp/ +*.class +*.jar +*.war +*.ear +*.nar + +############################## +## Maven +############################## +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +pom.xml.bak +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +############################## +## IntelliJ +############################## +out/ +.idea/* +*.iml +*.ipr +*.iws + +############################## +## Database +############################## +*.db +*.DS_Store diff --git a/pom.xml b/pom.xml index 5b73b10d1d3636fb9946e19ceed23210fe7f877f..abfdbb4c11119f996caad1c42a8029720b53ce54 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <junit.version>5.9.2</junit.version> + <junit.version>5.8.1</junit.version> <javafx.version>19.0.2.1</javafx.version> </properties> 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 378929b027298692df0589fd7271c2608b732ab1..b4a6ce145c8384a8ecfd3f9b908b4c004f52c319 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java @@ -12,14 +12,18 @@ 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.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 oldExpense = null; //an expense that is meant to track the old state of an expense before editing, in case cancel bugtton is clicked + Expense chosenExpense = null; //an expense that is meant to track the old state of an expense before editing, in case cancel bugtton is clicked + @FXML private Button cancelBtn; @@ -29,6 +33,9 @@ public class AddExpenseController { @FXML private TextField dateField; + @FXML + private DatePicker datePicker; + @FXML private TextField descriptionField; @@ -52,8 +59,7 @@ public class AddExpenseController { recurringBox.setItems(recurring); recurringBox.setValue(false); - System.out.print("This is in initialize"); - System.out.println(descriptionField); + datePicker.setValue(LocalDate.now()); } public ExpenseCategory getCategory() { @@ -65,22 +71,37 @@ public class AddExpenseController { } public void setExpense(Expense expense) { //TODO NEED CANCEL BUTTON TO REMOVE THE CHANGES IF CANCEL IS PRESSED - dateField.textProperty().bindBidirectional(new SimpleStringProperty(expense.getDate().toString())); - amountField.textProperty().bindBidirectional(expense.amountProperty(), NumberFormat.getNumberInstance()); //TODO AMOUNT IS STORED WITH COMMA, WHICH IS NOT ALLOWED - descriptionField.textProperty().bindBidirectional(expense.descriptionProperty()); - //categoryBox.valueProperty().bindBidirectional(expense.getCategory()); - recurringBox.valueProperty().bindBidirectional(expense.recurringProperty()); + chosenExpense = new Expense(expense.getDescription(), expense.getAmount(), expense.isRecurring(), expense.getCategory(), expense.getDate()); + chosenExpense.descriptionProperty().bindBidirectional(expense.descriptionProperty()); + chosenExpense.amountProperty().bindBidirectional(expense.amountProperty()); + chosenExpense.recurringProperty().bindBidirectional(expense.recurringProperty()); + chosenExpense.expenseCategoryObjectProperty().bindBidirectional(expense.expenseCategoryObjectProperty()); + chosenExpense.dateProperty().bindBidirectional(expense.dateProperty()); + + descriptionField.textProperty().set(expense.getDescription()); + amountField.textProperty().setValue(String.valueOf(expense.getAmount())); + recurringBox.setValue(expense.isRecurring()); + datePicker.setValue(expense.getDate()); + categoryBox.setValue(expense.getCategory()); } @FXML public void pressOkBtn(ActionEvent event) { - LocalDate date = LocalDate.parse(dateField.getText()); - double amount = Double.parseDouble(amountField.getText()); - String description = descriptionField.getText(); - ExpenseCategory category = getCategory(); - boolean recurring = isRecurring(); - newExpense = new Expense(description, amount, recurring, category, date); - System.out.println(date + " " + amount + " " + description + " " + category + " " + recurring); + if (newExpense == null) { + LocalDate date = datePicker.getValue(); + double amount = Double.parseDouble(amountField.getText()); + String description = descriptionField.getText(); + ExpenseCategory category = getCategory(); + boolean recurring = isRecurring(); + newExpense = new Expense(description, amount, recurring, category, date); + } + if (chosenExpense != null) { + chosenExpense.setDescription((descriptionField.getText())); + chosenExpense.setAmount(Double.parseDouble(amountField.getText())); + chosenExpense.setRecurring(recurringBox.getValue()); + chosenExpense.setCategory(categoryBox.getValue()); + chosenExpense.setDate(datePicker.getValue()); + } final Node source = (Node) event.getSource(); ((Stage) source.getScene().getWindow()).close(); 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 0000000000000000000000000000000000000000..d59604546b8dffc0e021ad82a5dc195d90a0b3db --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java @@ -0,0 +1,121 @@ +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; + @FXML + private Button cancelBtn; + + @FXML + private Button okBtn; + + @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); + + datePicker.setValue(LocalDate.now()); + } + + 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()); + chosenIncome.incomeCategoryObjectProperty().bindBidirectional(income.incomeCategoryObjectProperty()); + chosenIncome.dateProperty().bindBidirectional(income.dateProperty()); + descriptionField.textProperty().set(income.getDescription()); + amountField.textProperty().setValue(String.valueOf(income.getAmount())); + recurringBox.setValue(income.isRecurring()); + + descriptionField.textProperty().set(income.getDescription()); + amountField.textProperty().setValue(String.valueOf(income.getAmount())); + recurringBox.setValue(income.isRecurring()); + datePicker.setValue(income.getDate()); + categoryBox.setValue(income.getCategory()); + } + + @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()); + chosenIncome.setCategory(categoryBox.getValue()); + chosenIncome.setDate(datePicker.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.newIncome; + } +} \ No newline at end of file diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java new file mode 100644 index 0000000000000000000000000000000000000000..22215ac760f1d12f6d08ed1c5e4dab30e6ebbfd2 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java @@ -0,0 +1,210 @@ +package no.ntnu.idatt1002.demo.controller; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.text.Text; +import javafx.stage.Modality; +import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Budget.BudgetItem; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget; +import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; + + +import java.io.IOException; +import java.util.Optional; + +public class BudgetController { + + private GeneralBudget general; + + @FXML + private Button addBudget; + + @FXML + private Button editBudget; + + @FXML + private Button expenseBtn; + + @FXML + private Button incomeBtn; + + @FXML + private Button returnBtn; + + @FXML + private Button nextBtn; + + @FXML + private TableColumn<BudgetItem, Double> amountColumn; + + @FXML + private TableView<BudgetItem> budgetTableView = new TableView<>(); + + @FXML + private TableColumn<BudgetItem, ExpenseCategory> categoryColumn; + + @FXML + private TableColumn<BudgetItem, String> descriptionColumn; + + @FXML + private Text sum; + + @FXML + private TableColumn<BudgetItem, Double> percentageColumn; + + @FXML + private ObservableList<BudgetItem> budgetList; + + + + public void initialize() throws IOException { + categoryColumn.setCellValueFactory(new PropertyValueFactory<BudgetItem, ExpenseCategory>("budgetCategory")); + amountColumn.setCellValueFactory(new PropertyValueFactory<BudgetItem, Double>("budgetAmount")); + descriptionColumn.setCellValueFactory(new PropertyValueFactory<BudgetItem, String>("budgetDescription")); + + general = loadIncomeDataFromFile("Budget"); + budgetList = FXCollections.observableArrayList(general.getBudgetItems()); + budgetTableView.setItems(budgetList); + + sum.setText(String.valueOf(general.totalSum())); + } + @FXML + public void switchAddBudget(javafx.event.ActionEvent event) throws IOException { + BudgetItem item = null; + String dialogTitle = ""; + FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/AddBudget.fxml")); + Dialog<BudgetItem> dialog = new Dialog<>(); + dialog.initModality(Modality.APPLICATION_MODAL); + + try{ + dialog.getDialogPane().setContent(loader.load()); + } catch(IOException e) { + e.printStackTrace(); + } + + AddBudgetController budgetController = loader.getController(); + + DialogMode dialogMode; + if(event.getSource().equals(addBudget)){ + dialogMode = DialogMode.ADD; + dialogTitle = "New Budget"; + + } + else if (event.getSource().equals(editBudget) && budgetTableView.getSelectionModel().getSelectedItem() != null) { + dialogMode = DialogMode.EDIT; + dialogTitle = "Edit expense"; + item = budgetTableView.getSelectionModel().getSelectedItem(); + budgetController.setBudget(item); + } else { + return; + } + + dialog.setTitle(dialogTitle); + dialog.showAndWait(); + + item = budgetController.getNewBudgetItem(); + if(item != null && dialogMode == DialogMode.ADD){ + try { + general.addToBudgetBudgetItem(item); + } catch(IllegalArgumentException e) { + showIllegalBudgetItemDialog(); + } + } + refreshTableView(); + } + + @FXML + public void closeButton(javafx.event.ActionEvent actionEvent) { + final Node source = (Node) actionEvent.getSource(); + final Stage stage = (Stage) source.getScene().getWindow(); + stage.close(); + } + + @FXML + public void deleteButton(ActionEvent event) { + BudgetItem item = budgetTableView.getSelectionModel().getSelectedItem(); + if (item == null) { + return; + } + Optional<ButtonType> isConfirmed = showConfirmationDialog(); + if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { + general.deleteItemFromBudget(item.getBudgetCategory()); + refreshTableView(); + } + } + + private Optional<ButtonType> showConfirmationDialog() { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Confirm Delete"); + alert.setHeaderText("Delete Confirmation"); + alert.setContentText("Are you sure you would like to delete the selected entry?"); + + return alert.showAndWait(); + } + + private Optional<ButtonType> showIllegalBudgetItemDialog() { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Budget amount exceeded"); + alert.setHeaderText("Your budget exceeds the max limit"); + alert.setContentText("The total budget sum must be below " + general.getMaxAmount()); + + return alert.showAndWait(); + } + + + public GeneralBudget loadIncomeDataFromFile(String fileName) throws IOException { + FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); + if (fileHandlingBudget.isEmpty(fileName)) { + general = new GeneralBudget(31, 1000); + } else { + try { + general = fileHandlingBudget.readGeneralBudgetFromFile(fileName); + } catch (IOException e) { + e.printStackTrace(); + } + } + return general; + } + + public void saveDataToFile(String fileName) throws IOException { + FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); + fileHandlingBudget.writeGeneralBudgetToFile(fileName, general); + } + + + protected void refreshTableView(){ + this.budgetList.setAll(general.getBudgetItems()); + this.sum.setText(String.valueOf(general.totalSum())); + } + + @FXML + public void switchScene(ActionEvent event) throws IOException { + saveDataToFile("Budget"); + FXMLLoader loader = new FXMLLoader(); + if (event.getSource() == expenseBtn) { + loader.setLocation(SceneController.class.getResource("/view/Expenses.fxml")); + } else if (event.getSource() == returnBtn) { + loader.setLocation(SceneController.class.getResource("/view/FirstMenu.fxml")); + } else if (event.getSource() == incomeBtn) { + loader.setLocation(SceneController.class.getResource("/view/Income.fxml")); + } else if (event.getSource() == nextBtn) { + loader.setLocation(SceneController.class.getResource("/view/MainMenu.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/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java new file mode 100644 index 0000000000000000000000000000000000000000..34b0c179e2ed78299250a6723a84e1599efbe074 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java @@ -0,0 +1,231 @@ +package no.ntnu.idatt1002.demo.controller; + +import java.io.IOException; + +import java.util.Optional; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Dialog; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.text.Text; +import javafx.stage.Modality; +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.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 +} + +public class ExpensesController { + + @FXML + private Button addBtn; + @FXML + private Button editBtn; + + @FXML + private Button deleteBtn; + + @FXML + private ComboBox<String> show; + + @FXML + private Button incomeBtn; + + @FXML + private Text sum; + + @FXML + private Button budgetBtn; + + @FXML + private Button returnBtn; + + + @FXML + private TableColumn<Expense, Double> amountColumn; + + @FXML + private TableColumn<Expense, ExpenseCategory> categoryColumn; + + @FXML + private TableColumn<Expense, String> dateColumn; + + @FXML + private TableColumn<Expense, String> descriptionColumn; + + @FXML + private TableColumn<Expense, Boolean> recurringColumn; + + @FXML + private TableView<Expense> expenseTableView; + + @FXML + ExpenseRegister expenseRegister; + ObservableList<Expense> expenses; + + ObservableList<String> filter; + + @FXML + public void initialize() throws IOException { + 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")); + + filter = FXCollections.observableArrayList("All", "Food", "Clothes", "Books", "Other", + "Fixed expense"); + show.setItems(filter); + show.setValue("All"); + + expenseRegister = loadExpenseDataFromFile("Expense"); + expenses = FXCollections.observableArrayList(expenseRegister.getItems()); + expenseTableView.setItems(expenses); + + sum.setText(String.valueOf(expenseRegister.getTotalSum())); + } + + @FXML + protected void handleAddButton(ActionEvent event) { + handleEditButton(event); + } + + @FXML + protected void handleEditButton(ActionEvent event) { + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(getClass().getResource("/view/AddExpense.fxml")); + Expense newExpense = null; + String dialogTitle = ""; + // Load the FXML file for your dialog box + Dialog<Expense> dialog = new Dialog<>(); + dialog.initModality(Modality.APPLICATION_MODAL); + + try { + // Set the Dialog's content to the loaded FXML file + dialog.getDialogPane().setContent(loader.load()); + } catch (IOException e) { + e.printStackTrace(); + } + + // Get the controller for the loaded FXML file + AddExpenseController dialogController = loader.getController(); + + /** + * The mode of the dialog. NEW if new contact, EDIT if edit existing contact. + */ + DialogMode dialogMode; + if (event.getSource().equals(addBtn)) { + dialogMode = DialogMode.ADD; + dialogTitle = "Add expense"; + + + } else if (event.getSource().equals(editBtn) + && expenseTableView.getSelectionModel().getSelectedItem() != null) { + dialogMode = DialogMode.EDIT; + dialogTitle = "Edit expense"; + newExpense = expenseTableView.getSelectionModel().getSelectedItem(); + dialogController.setExpense(newExpense); + } else { + return; + } + dialog.setTitle(dialogTitle); + dialog.showAndWait(); + + // Show the Dialog and wait for the user to close it + //Get the newly created expense from the dialog pane + newExpense = dialogController.getNewExpense(); + + if (newExpense != null && dialogMode == DialogMode.ADD) { + expenseRegister.addItem(newExpense); + } + refreshTableView(); + } + //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); + refreshTableView(); + } + } + + protected void refreshTableView() { + this.expenses.setAll(expenseRegister.getItems()); + this.sum.setText(String.valueOf(expenseRegister.getTotalSum())); + + } + + private Optional<ButtonType> showConfirmationDialog() { + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("Confirm Delete"); + alert.setHeaderText("Delete Confirmation"); + alert.setContentText("Are you sure you would like to delete the selected entry?"); + + return alert.showAndWait(); + } + + public ExpenseRegister loadExpenseDataFromFile(String fileName) throws IOException { + //ItemRegister<T extends Item> + FileHandling fileHandling = new FileHandling(); + if (fileHandling.isEmpty(fileName)) { + expenseRegister = new ExpenseRegister(); + } else { + try { + expenseRegister = fileHandling.readExpenseRegisterFromFile(fileName); + } catch (IOException e) { + e.printStackTrace(); + } + } + return expenseRegister; + } + + public void saveDataToFile(String fileName) throws IOException { + FileHandling fileHandling = new FileHandling(); + fileHandling.writeItemRegisterToFile(expenseRegister, fileName); + } + + @FXML + public void switchScene(ActionEvent event) throws IOException { + saveDataToFile("Expense"); + FXMLLoader loader = new FXMLLoader(); + if (event.getSource() == incomeBtn) { + loader.setLocation(SceneController.class.getResource("/view/Income.fxml")); + } else if (event.getSource() == returnBtn) { + loader.setLocation(SceneController.class.getResource("/view/FirstMenu.fxml")); + } else if (event.getSource() == budgetBtn) { + loader.setLocation(SceneController.class.getResource("/view/BudgetNew.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/java/no/ntnu/idatt1002/demo/controller/IncomeController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeController.java new file mode 100644 index 0000000000000000000000000000000000000000..489d98dba005251700af594b22a7870ecf52d110 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeController.java @@ -0,0 +1,221 @@ +package no.ntnu.idatt1002.demo.controller; + +import java.io.IOException; + +import java.util.Optional; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Dialog; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.text.Text; +import javafx.stage.Modality; +import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Economics.Income; +import no.ntnu.idatt1002.demo.data.Economics.IncomeCategory; +import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; +import no.ntnu.idatt1002.demo.data.Economics.FileHandling; + +public class IncomeController { + + /** + * The mode of the dialog. NEW if new contact, EDIT if edit existing contact. + */ + private DialogMode dialogMode; + @FXML + private Button addBtn; + @FXML + private Button editBtn; + + @FXML + private Button deleteBtn; + + @FXML + private ComboBox<String> show; + + @FXML + private Button expenseBtn; + + @FXML + private Button overviewBtn; + + @FXML + private Button budgetBtn; + @FXML + private Button returnBtn; + + @FXML + private Text sum; + @FXML + private TableColumn<Income, Double> amountColumn; + + @FXML + private TableColumn<Income, IncomeCategory> categoryColumn; + + @FXML + private TableColumn<Income, String> dateColumn; + + @FXML + private TableColumn<Income, String> descriptionColumn; + + @FXML + private TableColumn<Income, Boolean> recurringColumn; + + @FXML + private TableView<Income> incomeTableView; + + IncomeRegister incomeRegister; + ObservableList<Income> income; + + ObservableList<String> filter; + + @FXML + public void initialize() throws IOException { + dateColumn.setCellValueFactory(new PropertyValueFactory<Income, String>("date")); + amountColumn.setCellValueFactory(new PropertyValueFactory<Income, Double>("amount")); + categoryColumn.setCellValueFactory(new PropertyValueFactory<Income, IncomeCategory>("category")); + descriptionColumn.setCellValueFactory(new PropertyValueFactory<Income, String>("description")); + recurringColumn.setCellValueFactory(new PropertyValueFactory<Income, Boolean>("recurring")); + + filter = FXCollections.observableArrayList("All", "Gift", "Salary", "Student loan", "Fixed income"); + show.setItems(filter); + show.setValue("All"); + + incomeRegister = loadIncomeDataFromFile("Income"); + income = FXCollections.observableArrayList(incomeRegister.getItems()); + incomeTableView.setItems(income); + + sum.setText(String.valueOf(incomeRegister.getTotalSum())); + //if budget.register isEmpty -> disable expense + } + + @FXML + protected void handleAddButton(ActionEvent event) { + handleEditButton(event); + } + + @FXML + protected void handleEditButton(ActionEvent event) { + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(getClass().getResource("/view/AddIncome.fxml")); + Income newIncome = null; + String dialogTitle = ""; + // Load the FXML file for your dialog box + Dialog<Income> dialog = new Dialog<>(); + dialog.initModality(Modality.APPLICATION_MODAL); + + try { + // Set the Dialog's content to the loaded FXML file + dialog.getDialogPane().setContent(loader.load()); + } catch (IOException e) { + e.printStackTrace(); + } + + // Get the controller for the loaded FXML file + AddIncomeController dialogController = loader.getController(); + + if (event.getSource().equals(addBtn)) { + dialogMode = DialogMode.ADD; + dialogTitle = "Add income"; + } else if (event.getSource().equals(editBtn) + && incomeTableView.getSelectionModel().getSelectedItem() != null) { + dialogMode = DialogMode.EDIT; + dialogTitle = "Edit income"; + newIncome = incomeTableView.getSelectionModel().getSelectedItem(); + dialogController.setIncome(newIncome); + } else { + return; + } + + dialog.setTitle(dialogTitle); + // Show the Dialog and wait for the user to close it + dialog.showAndWait(); + //Get the newly created income from the dialog pane + newIncome = dialogController.getNewIncome(); + + if (newIncome != null && dialogMode == DialogMode.ADD) { + incomeRegister.addItem(newIncome); + } + refreshTableView(); + } + //Only add the income to the tableview, if the income is not null + + @FXML + public void handleDeleteBtn(ActionEvent event) { + Income chosenIncome = incomeTableView.getSelectionModel().getSelectedItem(); + if (chosenIncome == null) { + return; + } + Optional<ButtonType> isConfirmed = showConfirmationDialog(); + if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { + incomeRegister.removeItem(chosenIncome); + refreshTableView(); + } + } + + protected void refreshTableView() { + this.income.setAll(incomeRegister.getItems()); + this.sum.setText(String.valueOf(incomeRegister.getTotalSum())); + } + + private Optional<ButtonType> showConfirmationDialog() { + Alert alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("Confirm Delete"); + alert.setHeaderText("Delete Confirmation"); + alert.setContentText("Are you sure you would like to delete the selected entry?"); + + return alert.showAndWait(); + } + + public IncomeRegister loadIncomeDataFromFile(String fileName) throws IOException { + FileHandling fileHandling = new FileHandling(); + if (fileHandling.isEmpty(fileName)) { + incomeRegister = new IncomeRegister(); + System.out.println("hey"); + } 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(incomeRegister, fileName); + } + + @FXML + public void switchScene(ActionEvent event) throws IOException { + saveDataToFile("Income"); + FXMLLoader loader = new FXMLLoader(); + if (event.getSource() == expenseBtn) { + loader.setLocation(SceneController.class.getResource("/view/Expenses.fxml")); + } else if (event.getSource() == overviewBtn) { + loader.setLocation(SceneController.class.getResource("/view/Overview.fxml")); + } else if (event.getSource() == returnBtn) { + loader.setLocation(SceneController.class.getResource("/view/FirstMenu.fxml")); + } else if (event.getSource() == budgetBtn) { + loader.setLocation(SceneController.class.getResource("/view/BudgetNew.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/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java index 556801954739fd49b84564d1f4c6b1de3806f968..f59aedc77d55dec90953454bd5f59e139b8cf3ed 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java @@ -1,5 +1,6 @@ package no.ntnu.idatt1002.demo.controller; import java.io.IOException; +import java.time.LocalDate; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; @@ -11,18 +12,23 @@ import javafx.scene.control.DatePicker; import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; import javafx.scene.image.ImageView; +import javafx.scene.paint.Color; +import javafx.scene.text.Text; import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister; +import no.ntnu.idatt1002.demo.data.Economics.FileHandling; +import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; public class MainMenuController { @FXML - private Button addExpenseButton; + private Button addExpenseBtn; @FXML private Button foodButton; @FXML - private Button overviewButton; + private Button overviewBtn; @FXML private ProgressBar progressbar; @@ -36,35 +42,55 @@ public class MainMenuController { @FXML private Label today; + @FXML + private Text budgetMonth; - //ExpenseRepository expenseRepository; @FXML - public void initialize() { - progressbar.setProgress(0.5); - //progressbar.setProgress((ExpenseRepository.getSum())/5000); - System.out.println(progressbar.getProgress()); - progressMarker.setTranslateX(-275 + progressbar.getProgress()); - today.setTranslateX(-275 + progressbar.getProgress()); - } + private Label balanceLbl; + @FXML - public void switchExpenses(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Expenses.fxml")); - Parent root = loader.load(); - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); + public void initialize() throws IOException { + IncomeController incomeController = new IncomeController(); + IncomeRegister incomeRegister = incomeController.loadIncomeDataFromFile("Income"); + + ExpensesController expensesController = new ExpensesController(); + ExpenseRegister expenseRegister = expensesController.loadExpenseDataFromFile("Expense"); + + double incomeSum = incomeRegister.getTotalSum(); + double expenseSum = expenseRegister.getTotalSum(); + + progressbar.setProgress(expenseSum/incomeSum); + progressMarker.setTranslateX(-275 + progressbar.getProgress()); + + budgetMonth.setText("BUDGET " + (LocalDate.EPOCH.getMonth())); + double balance = incomeSum - expenseSum; + balanceLbl.setText("Balance: " + (balance)); + + today.setText("Used " + expenseSum + " out of " + incomeSum + " this month"); + + if (balance < 0) { + balanceLbl.setTextFill(Color.RED); + } + + date.setValue(LocalDate.now()); + //date.restrict } @FXML - public void switchOverview(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Overview.fxml")); + public void switchScene(ActionEvent event) throws IOException { + //saveDataToFile("Income"); + FXMLLoader loader = new FXMLLoader(); + if (event.getSource() == addExpenseBtn) { + loader.setLocation(SceneController.class.getResource("/view/Expenses.fxml")); + } else if (event.getSource() == overviewBtn) { + loader.setLocation(SceneController.class.getResource("/view/Budget.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/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudget.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudget.java index 1d0826230f350682487f1ed9d8ef774d634fad55..c39321868e3685847d9eb0a920828f81937778e4 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudget.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudget.java @@ -36,6 +36,23 @@ public class FileHandlingBudget { } } + /** + * Method for checking if a .register file is empty. + * + * @param fileTitle the name of the file you want to check + * @return true or false depending on if file is empty. + * @throws IOException if an input or output exception occurred. + */ + public boolean isEmpty(String fileTitle) throws IOException { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + if (br.readLine() == null) { + return true; + } else { + return false; + } + } + } + /** * Method for reading (getting) a Budget from a file. * @@ -74,10 +91,9 @@ public class FileHandlingBudget { } else if (line.startsWith(FileHandlingBudget.budgetDescription)) { budgetDescription = line.replace(FileHandlingBudget.budgetDescription,""); } - if ((line.isEmpty() || (nextLine == null)) && (expenseCategory!=null)) { + if (line.isEmpty() || (nextLine == null)) { if(generalBudget == null){ generalBudget = new GeneralBudget(budgetPeriod,maxAmount); - generalBudget.addToBudget(budgetAmount,budgetDescription,expenseCategory); } else{ generalBudget.addToBudget(budgetAmount,budgetDescription,expenseCategory); } diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Expense.java b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Expense.java index 11848b02acc76fa0c1959fef8e75342055e1ee65..de47509b32c5ee29e911f21e4007236a16cbeae0 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Expense.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Expense.java @@ -45,6 +45,9 @@ public class Expense extends Item{ this.category = new SimpleObjectProperty<>(category); } + public ObjectProperty<ExpenseCategory> expenseCategoryObjectProperty() { + return this.category; + } /** * The method returns the category to which the Expense belongs as a value of the ExpenseCategory enum class. * @return The category the Expense belongs to as a value of the ExpenseCategory enum class. diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/FileHandling.java b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/FileHandling.java index ce4e00ed260290b4e79207556604b7956c5b2344..e678543fe5e25634aba1d67c029114c1b5633350 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/FileHandling.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/FileHandling.java @@ -92,8 +92,7 @@ public class FileHandling{ case "STUDENT_LOAN" -> IncomeCategory.STUDENT_LOAN; default -> IncomeCategory.SALARY; }; - } - if(line.isEmpty() || (nextLine == null)) { + } if(line.isEmpty() || (nextLine == null)) { if(description.equals("")){ incomeRegister.addItem(new Income(amount, reoccuring, incomeCategory, date)); } else{ diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Income.java b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Income.java index 904ab935c2c23da4ef0f859c5a89aafe454a4997..4b8eaae921444b441cc45821ec7a0209fa69d360 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Income.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Income.java @@ -53,6 +53,9 @@ public class Income extends Item{ } + public ObjectProperty<IncomeCategory> incomeCategoryObjectProperty() { + return this.category; + } /** * The method returns the category to which the Income belongs as a value of the IncomeCategory enum. * @return The category to which the Income belongs to as a value of the IncomeCategory enum. diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Item.java b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Item.java index a04f0bcb7095db7974a2b917a30b08663d12ae0d..57c2a8f77081a8fd391ed66ed461c978ae5475cb 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Item.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/Item.java @@ -112,14 +112,14 @@ public abstract class Item { this.recurring.set(recurring); } - public StringProperty dateProperty() { - return this.dateProperty(); - } /** - public StringProperty dateProperty() { + * The method returns the ObjectProperty of date. + * @return + */ + public ObjectProperty<LocalDate> dateProperty() { return this.date; } - */ + /** * The method returns the date of the item object (income/expense). * @return The date of the transaction. diff --git a/src/main/resources/Budget/Budget.budget b/src/main/resources/Budget/Budget.budget new file mode 100644 index 0000000000000000000000000000000000000000..78b9f48b0b7ef60c96033b2573dfddcd296b6de6 --- /dev/null +++ b/src/main/resources/Budget/Budget.budget @@ -0,0 +1,7 @@ +budgetPeriod=31 +maxAmount=1000.0 + +budgetAmount=500.0 +budgetCategory=FOOD +budgetDescription=dd + diff --git a/src/main/resources/Economics/Expense.register b/src/main/resources/Economics/Expense.register new file mode 100644 index 0000000000000000000000000000000000000000..ec17f6ed2d4603e74ca8e338c12178108b19d29a --- /dev/null +++ b/src/main/resources/Economics/Expense.register @@ -0,0 +1,17 @@ +date=2023-03-01 +description=twelve +amount=12.0 +isRecurring=Not recurring +category=CLOTHES + +date=2023-03-11 +description=1111 +amount=121.0 +isRecurring=Not recurring +category=OTHER + +date=2023-03-26 +amount=10.0 +isRecurring=Not recurring +category=FOOD + diff --git a/src/main/resources/Economics/Income.register b/src/main/resources/Economics/Income.register new file mode 100644 index 0000000000000000000000000000000000000000..bc73c7799d89fc774ba0303cc1f4d105377d2b98 --- /dev/null +++ b/src/main/resources/Economics/Income.register @@ -0,0 +1,17 @@ +date=2023-03-24 +description=studie +amount=1000.0 +isRecurring=Recurring +category=STUDENT_LOAN + +date=2023-03-25 +amount=100.0 +isRecurring=Not recurring +category=GIFT + +date=2023-03-25 +description=airbnb +amount=1000.0 +isRecurring=Not recurring +category=GIFT + diff --git a/src/main/resources/Economics/expenseRegisterTest.itemRegister b/src/main/resources/Economics/expenseRegisterTest.itemRegister deleted file mode 100644 index 7f98526b7b5d9fa27c8d5ec080a8b33f9fb0b143..0000000000000000000000000000000000000000 --- a/src/main/resources/Economics/expenseRegisterTest.itemRegister +++ /dev/null @@ -1,6 +0,0 @@ - -date=03.03.23 -description=description -amount=59.900001525878906 -isReoccuring=Not reoccurring -category=CLOTHES diff --git a/src/main/resources/Economics/incomeRegisterTest.itemRegister b/src/main/resources/Economics/incomeRegisterTest.itemRegister deleted file mode 100644 index 6bfe0943a9c759b6838d594b03262e3727212ce9..0000000000000000000000000000000000000000 --- a/src/main/resources/Economics/incomeRegisterTest.itemRegister +++ /dev/null @@ -1,6 +0,0 @@ - -date=03.03.23 -description=description -amount=59.900001525878906 -isReoccuring=Not reoccurring -category=GIFT diff --git a/src/main/resources/Economics/incomeRegisterTest.register b/src/main/resources/Economics/incomeRegisterTest.register deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/main/resources/Images/add_image 2.png b/src/main/resources/Images/add_image 2.png deleted file mode 100644 index f8fd29245588cf7264711402a4610b4a23e3bfeb..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/add_image 2.png and /dev/null differ diff --git a/src/main/resources/Images/arrow 2.png b/src/main/resources/Images/arrow 2.png deleted file mode 100644 index 9d65c03b2a4d3710c674655f1a3201935735c9f5..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/arrow 2.png and /dev/null differ diff --git a/src/main/resources/Images/delete 2.png b/src/main/resources/Images/delete 2.png deleted file mode 100644 index b23937817cfa4976c74f73288a6c34451934f16b..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/delete 2.png and /dev/null differ diff --git a/src/main/resources/Images/edit 2.png b/src/main/resources/Images/edit 2.png deleted file mode 100644 index 833b336008545736084b8b7178591740a5bd7ac7..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/edit 2.png and /dev/null differ diff --git a/src/main/resources/view/AddExpense.fxml b/src/main/resources/view/AddExpense.fxml index 67cb0b9cd532b1ec998bcbec6a9ce26a79f60d13..4fda6662e04295346ddba7604b7b4ca97f806374 100644 --- a/src/main/resources/view/AddExpense.fxml +++ b/src/main/resources/view/AddExpense.fxml @@ -3,6 +3,7 @@ <?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?> @@ -33,7 +34,6 @@ <Label text="Description:" GridPane.rowIndex="2" /> <Label text="Category" GridPane.rowIndex="3" /> <Label text="Recurring" GridPane.rowIndex="4" /> - <TextField fx:id="dateField" promptText="1/1/23" GridPane.columnIndex="1" /> <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="Food" GridPane.columnIndex="1" GridPane.rowIndex="3" /> @@ -47,6 +47,7 @@ <Insets top="20.0" /> </GridPane.margin> </HBox> + <DatePicker fx:id="datePicker" GridPane.columnIndex="1" /> </children> </GridPane> </content> diff --git a/src/main/resources/view/AddIncome.fxml b/src/main/resources/view/AddIncome.fxml index 097992b0c7320fa41a777df6abb7036ab8274662..abdfe7c23fbc862d64b6015d99064875cfd22693 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.AddIncomeController"> + <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> diff --git a/src/main/resources/view/BudgetNew.fxml b/src/main/resources/view/BudgetNew.fxml new file mode 100644 index 0000000000000000000000000000000000000000..9cda09ce93bc33a044ecfe2a71fc3ff5e4e7edbd --- /dev/null +++ b/src/main/resources/view/BudgetNew.fxml @@ -0,0 +1,188 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.Cursor?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.TableColumn?> +<?import javafx.scene.control.TableView?> +<?import javafx.scene.image.Image?> +<?import javafx.scene.image.ImageView?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.BorderPane?> +<?import javafx.scene.layout.ColumnConstraints?> +<?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.Region?> +<?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.StackPane?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.shape.Rectangle?> +<?import javafx.scene.text.Font?> +<?import javafx.scene.text.Text?> + +<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.BudgetController"> + <children> + <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> + <image> + <Image url="@../Images/backgroundMini.jpg" /> + </image> + <cursor> + <Cursor fx:constant="DEFAULT" /> + </cursor> + </ImageView> + <BorderPane prefHeight="400.0" prefWidth="600.0"> + <top> + <HBox BorderPane.alignment="CENTER"> + <children> + <Button fx:id="returnBtn" mnemonicParsing="false" onAction="#switchScene" text="Return "> + <opaqueInsets> + <Insets left="100.0" /> + </opaqueInsets> + <HBox.margin> + <Insets left="10.0" top="10.0" /> + </HBox.margin> + </Button> + <Region prefHeight="70.0" prefWidth="141.0" /> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Budget" textAlignment="CENTER" wrappingWidth="174.6796875"> + <HBox.margin> + <Insets /> + </HBox.margin> + <font> + <Font size="48.0" /> + </font> + </Text> + </children> + <opaqueInsets> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </opaqueInsets> + </HBox> + </top> + <center> + <GridPane BorderPane.alignment="CENTER"> + <BorderPane.margin> + <Insets bottom="40.0" left="40.0" right="40.0" /> + </BorderPane.margin> + <columnConstraints> + <ColumnConstraints hgrow="ALWAYS" maxWidth="485.3333231608073" minWidth="10.0" prefWidth="427.33335367838544" /> + <ColumnConstraints hgrow="ALWAYS" maxWidth="111.33333333333331" minWidth="10.0" prefWidth="92.66664632161456" /> + </columnConstraints> + <rowConstraints> + <RowConstraints maxHeight="65.33334064483643" minHeight="10.0" prefHeight="65.33334064483643" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="214.00004069010413" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="29.999959309895814" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + </rowConstraints> + <children> + <HBox alignment="BOTTOM_LEFT" prefWidth="410.0" spacing="5.0"> + <children> + <Button fx:id="addBudget" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#switchAddBudget" text="Add" textAlignment="CENTER"> + <graphic> + <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> + <image> + <Image url="@../Images/add_image.png" /> + </image> + </ImageView> + </graphic> + </Button> + <Button fx:id="editBudget" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#switchAddBudget" text="Edit" textAlignment="CENTER"> + <graphic> + <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> + <image> + <Image url="@../Images/edit.png" /> + </image> + </ImageView> + </graphic> + </Button> + <Button fx:id="deleteBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#deleteButton" text="Delete" textAlignment="CENTER"> + <graphic> + <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> + <image> + <Image url="@../Images/delete.png" /> + </image> + </ImageView> + </graphic> + </Button> + </children> + <opaqueInsets> + <Insets /> + </opaqueInsets> + <padding> + <Insets bottom="5.0" /> + </padding> + </HBox> + <VBox alignment="BOTTOM_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1"> + <children> + <ComboBox fx:id="show" prefWidth="150.0" promptText="Show "> + <opaqueInsets> + <Insets /> + </opaqueInsets> + <VBox.margin> + <Insets bottom="5.0" /> + </VBox.margin> + </ComboBox> + </children> + </VBox> + <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="3"> + <children> + <Button fx:id="incomeBtn" mnemonicParsing="false" onAction="#switchScene" text="Income" /> + <Button fx:id="budgetBtn" disable="true" mnemonicParsing="false" onAction="#switchScene" text="Budget" /> + <Button fx:id="expenseBtn" mnemonicParsing="false" onAction="#switchScene" text="Expenses" /> + <Button fx:id="nextBtn" mnemonicParsing="false" onAction="#switchScene" text="Next"> + <HBox.margin> + <Insets left="170.0" /> + </HBox.margin> + </Button> + </children> + <padding> + <Insets top="10.0" /> + </padding> + </HBox> + <TableView fx:id="budgetTableView" prefHeight="260.0" prefWidth="485.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> + <columns> + <TableColumn fx:id="categoryColumn" prefWidth="75.0" text="Category/Title" /> + <TableColumn fx:id="amountColumn" prefWidth="75.0" text="Amount" /> + <TableColumn fx:id="percentageColumn" prefWidth="75.0" text="Percentage" /> + <TableColumn fx:id="descriptionColumn" prefWidth="75.0" text="Description" /> + </columns> + <columnResizePolicy> + <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> + </columnResizePolicy> + </TableView> + <StackPane GridPane.rowIndex="2"> + <children> + <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="209.0" StackPane.alignment="CENTER_LEFT" /> + <HBox prefHeight="18.0" prefWidth="517.0"> + <children> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Sum: "> + <HBox.margin> + <Insets left="2.0" /> + </HBox.margin> + </Text> + <Region prefHeight="18.0" prefWidth="101.0" /> + <Text fx:id="sum" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" /> + </children> + </HBox> + </children> + </StackPane> + </children> + </GridPane> + </center> + <opaqueInsets> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </opaqueInsets> + <left> + <Region prefHeight="330.0" prefWidth="1.0" BorderPane.alignment="CENTER" /> + </left> + <right> + <Region prefHeight="357.0" prefWidth="0.0" BorderPane.alignment="CENTER" /> + </right> + <bottom> + <Region prefHeight="0.0" prefWidth="600.0" BorderPane.alignment="CENTER" /> + </bottom> + </BorderPane> + </children> + <opaqueInsets> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </opaqueInsets> +</AnchorPane> diff --git a/src/main/resources/view/Expenses.fxml b/src/main/resources/view/Expenses.fxml index 7985d6413c4f3ff58c6056a59b26752314f617be..0311ce16a0f244f8d9f857479060df084e45edcb 100644 --- a/src/main/resources/view/Expenses.fxml +++ b/src/main/resources/view/Expenses.fxml @@ -15,7 +15,9 @@ <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.Region?> <?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.VBox?> +<?import javafx.scene.shape.Rectangle?> <?import javafx.scene.text.Font?> <?import javafx.scene.text.Text?> @@ -33,7 +35,7 @@ <top> <HBox BorderPane.alignment="CENTER"> <children> - <Button mnemonicParsing="false" onAction="#switchIncome" text="Return "> + <Button fx:id="returnBtn" mnemonicParsing="false" onAction="#switchScene" text="Return "> <opaqueInsets> <Insets left="100.0" /> </opaqueInsets> @@ -69,6 +71,7 @@ <RowConstraints maxHeight="65.33334064483643" minHeight="10.0" prefHeight="65.33334064483643" vgrow="SOMETIMES" /> <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="214.00004069010413" vgrow="SOMETIMES" /> <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="29.999959309895814" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> </rowConstraints> <children> <HBox alignment="BOTTOM_LEFT" prefWidth="410.0" spacing="5.0"> @@ -117,16 +120,12 @@ </ComboBox> </children> </VBox> - <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="2"> + <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="3"> <children> - <Button mnemonicParsing="false" onAction="#switchOverview" text="Overview"> - <HBox.margin> - <Insets right="5.0" /> - </HBox.margin></Button> - <Button mnemonicParsing="false" onAction="#switchIncome" text="Income" /> + <Button fx:id="incomeBtn" mnemonicParsing="false" onAction="#switchScene" text="Income" /> + <Button fx:id="budgetBtn" mnemonicParsing="false" onAction="#switchScene" text="Budget" /> <Button disable="true" mnemonicParsing="false" text="Expenses" /> - <Button disable="true" mnemonicParsing="false" text="Savings" /> - <Button mnemonicParsing="false" onAction="#switchOverview" text="Next"> + <Button mnemonicParsing="false" onAction="#switchScene" text="Next"> <HBox.margin> <Insets left="170.0" /> </HBox.margin></Button> @@ -134,6 +133,9 @@ <padding> <Insets top="10.0" /> </padding> + <GridPane.margin> + <Insets top="5.0" /> + </GridPane.margin> </HBox> <TableView fx:id="expenseTableView" prefHeight="260.0" prefWidth="485.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> <columns> @@ -147,6 +149,22 @@ <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> </columnResizePolicy> </TableView> + <StackPane GridPane.rowIndex="2"> + <children> + <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="209.0" StackPane.alignment="CENTER_LEFT" /> + <HBox prefHeight="18.0" prefWidth="517.0"> + <children> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Sum: "> + <HBox.margin> + <Insets left="2.0" /> + </HBox.margin> + </Text> + <Region prefHeight="18.0" prefWidth="74.0" /> + <Text fx:id="sum" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" /> + </children> + </HBox> + </children> + </StackPane> </children> </GridPane> </center> diff --git a/src/main/resources/view/Income.fxml b/src/main/resources/view/Income.fxml index 090983dfc1b733b038c77c3a672954876a41a341..f9f1e586fc24bf222024051cd977dbb91d5ef5d7 100644 --- a/src/main/resources/view/Income.fxml +++ b/src/main/resources/view/Income.fxml @@ -15,11 +15,13 @@ <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.Region?> <?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.VBox?> +<?import javafx.scene.shape.Rectangle?> <?import javafx.scene.text.Font?> <?import javafx.scene.text.Text?> -<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SceneController"> +<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.IncomeController"> <children> <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> <image> @@ -33,7 +35,7 @@ <top> <HBox BorderPane.alignment="CENTER"> <children> - <Button mnemonicParsing="false" onAction="#switchStartMenu" text="Return "> + <Button fx:id="returnBtn" mnemonicParsing="false" onAction="#switchScene" text="Return "> <opaqueInsets> <Insets left="100.0" /> </opaqueInsets> @@ -69,11 +71,12 @@ <RowConstraints maxHeight="65.33334064483643" minHeight="10.0" prefHeight="65.33334064483643" vgrow="SOMETIMES" /> <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="214.00004069010413" vgrow="SOMETIMES" /> <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="29.999959309895814" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> </rowConstraints> <children> <HBox alignment="BOTTOM_LEFT" prefWidth="410.0" spacing="5.0"> <children> - <Button fx:id="add" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#addIncome" text="Add" textAlignment="CENTER"> + <Button fx:id="addBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleAddButton" text="Add" textAlignment="CENTER"> <graphic> <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> <image> @@ -82,7 +85,7 @@ </ImageView> </graphic> </Button> - <Button alignment="TOP_CENTER" mnemonicParsing="false" text="Edit" textAlignment="CENTER"> + <Button fx:id="editBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleEditButton" text="Edit" textAlignment="CENTER"> <graphic> <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> <image> @@ -91,7 +94,7 @@ </ImageView> </graphic> </Button> - <Button alignment="TOP_CENTER" mnemonicParsing="false" text="Delete" textAlignment="CENTER"> + <Button fx:id="deleteBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete" textAlignment="CENTER"> <graphic> <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> <image> @@ -120,17 +123,12 @@ </ComboBox> </children> </VBox> - <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="2"> + <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="3"> <children> - <Button mnemonicParsing="false" onAction="#switchOverview" text="Overview"> - <HBox.margin> - <Insets right="5.0" /> - </HBox.margin> - </Button> - <Button disable="true" mnemonicParsing="false" onAction="#switchIncome" text="Income" /> - <Button mnemonicParsing="false" onAction="#switchExpenses" text="Expenses" /> - <Button disable="true" mnemonicParsing="false" text="Savings" /> - <Button mnemonicParsing="false" onAction="#switchExpenses" text="Next"> + <Button disable="true" mnemonicParsing="false" text="Income" /> + <Button fx:id="budgetBtn" mnemonicParsing="false" onAction="#switchScene" text="Budget" /> + <Button fx:id="expenseBtn" mnemonicParsing="false" onAction="#switchScene" text="Expenses" /> + <Button mnemonicParsing="false" onAction="#switchScene" text="Next"> <HBox.margin> <Insets left="170.0" /> </HBox.margin> @@ -140,18 +138,34 @@ <Insets top="10.0" /> </padding> </HBox> - <TableView fx:id="expenseTableView" prefHeight="260.0" prefWidth="485.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> + <TableView fx:id="incomeTableView" prefHeight="260.0" prefWidth="485.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> <columns> - <TableColumn fx:id="date" prefWidth="75.0" text="Date" /> - <TableColumn fx:id="amount" prefWidth="75.0" text="Amount" /> - <TableColumn fx:id="category" prefWidth="75.0" text="Category" /> - <TableColumn fx:id="description" prefWidth="75.0" text="Description" /> - <TableColumn fx:id="recurring" prefWidth="75.0" text="Recurring" /> + <TableColumn fx:id="dateColumn" prefWidth="75.0" text="Date" /> + <TableColumn fx:id="amountColumn" prefWidth="75.0" text="Amount" /> + <TableColumn fx:id="categoryColumn" prefWidth="75.0" text="Category" /> + <TableColumn fx:id="descriptionColumn" prefWidth="75.0" text="Description" /> + <TableColumn fx:id="recurringColumn" prefWidth="75.0" text="Recurring" /> </columns> <columnResizePolicy> <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> </columnResizePolicy> </TableView> + <StackPane GridPane.rowIndex="2"> + <children> + <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="209.0" StackPane.alignment="CENTER_LEFT" /> + <HBox prefHeight="18.0" prefWidth="517.0"> + <children> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Sum: "> + <HBox.margin> + <Insets left="2.0" /> + </HBox.margin> + </Text> + <Region prefHeight="18.0" prefWidth="74.0" /> + <Text fx:id="sum" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" /> + </children> + </HBox> + </children> + </StackPane> </children> </GridPane> </center> diff --git a/src/main/resources/view/MainMenu 2.fxml b/src/main/resources/view/MainMenu 2.fxml deleted file mode 100644 index 109698ac7f27cdb85bb41ba23c4b5af84037a3f8..0000000000000000000000000000000000000000 --- a/src/main/resources/view/MainMenu 2.fxml +++ /dev/null @@ -1,160 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.Cursor?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.DatePicker?> -<?import javafx.scene.control.Label?> -<?import javafx.scene.control.ProgressBar?> -<?import javafx.scene.image.Image?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.BorderPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.StackPane?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> -<?import javafx.scene.text.Text?> - -<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.MainMenuController"> - <children> - <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/backgroundMini.jpg" /> - </image> - </ImageView> - <BorderPane prefHeight="400.0" prefWidth="600.0" AnchorPane.topAnchor="0.0"> - <center> - <GridPane prefWidth="574.0" BorderPane.alignment="CENTER"> - <columnConstraints> - <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> - <children> - <VBox alignment="BOTTOM_RIGHT" GridPane.columnSpan="2"> - <children> - <DatePicker fx:id="date" /> - <HBox alignment="BOTTOM_CENTER" prefHeight="28.0" prefWidth="574.0"> - <children> - <Label text="5000kr left" textAlignment="CENTER"> - <font> - <Font name="System Bold" size="12.0" /> - </font></Label> - </children> - </HBox> - </children> - </VBox> - <StackPane GridPane.columnSpan="2" GridPane.rowIndex="1"> - <children> - <ImageView fx:id="progressMarker" fitHeight="20.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" rotate="-90.0" translateX="-150.0" translateY="25.0"> - <image> - <Image url="@../Images/arrow.png" /> - </image> - </ImageView> - <ProgressBar fx:id="progressbar" prefHeight="40.0" prefWidth="554.0" progress="0.72" translateY="-10.0" /> - <Label fx:id="today" text="Today" textAlignment="CENTER" translateX="-150.0" translateY="-2.0"> - <font> - <Font name="System Bold" size="12.0" /> - </font> - </Label> - </children> - </StackPane> - <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="50.0" GridPane.columnSpan="2" GridPane.rowIndex="2"> - <children> - <Button fx:id="foodButton" contentDisplay="TOP" mnemonicParsing="false" prefHeight="125.0" prefWidth="119.0" text="Food"> - <graphic> - <ImageView fitHeight="63.0" fitWidth="87.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/pizzaslice.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="addExpenseButton" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchExpenses" prefHeight="125.0" prefWidth="125.0" text="Add expense"> - <graphic> - <ImageView fitHeight="79.0" fitWidth="87.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/add_image.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="overviewButton" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchOverview" prefHeight="125.0" prefWidth="125.0" text="Overview"> - <graphic> - <ImageView fitHeight="63.0" fitWidth="87.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/overview_stonks.png" /> - </image> - </ImageView> - </graphic> - </Button> - </children> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <padding> - <Insets top="20.0" /> - </padding> - </HBox> - </children> - </GridPane> - </center> - <bottom> - <Region prefHeight="55.0" prefWidth="600.0" BorderPane.alignment="CENTER" /> - </bottom> - <left> - <Region prefHeight="287.0" prefWidth="14.0" BorderPane.alignment="CENTER" /> - </left> - <right> - <Region prefHeight="287.0" prefWidth="12.0" BorderPane.alignment="CENTER" /> - </right> - <top> - <HBox prefHeight="51.0" prefWidth="600.0" BorderPane.alignment="CENTER"> - <children> - <Button mnemonicParsing="false" text="Return "> - <opaqueInsets> - <Insets left="100.0" /> - </opaqueInsets> - <HBox.margin> - <Insets left="10.0" top="10.0" /> - </HBox.margin> - </Button> - <Region prefHeight="70.0" prefWidth="103.0" /> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="BUDGET FEBRUARY" textAlignment="CENTER"> - <HBox.margin> - <Insets /> - </HBox.margin> - <font> - <Font size="30.0" /> - </font> - </Text> - </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> - </HBox> - </top> - </BorderPane> - </children> -</AnchorPane> diff --git a/src/main/resources/view/MainMenu.fxml b/src/main/resources/view/MainMenu.fxml index 109698ac7f27cdb85bb41ba23c4b5af84037a3f8..a2b96f232db3d473ddd7d56e635705c3270bc70f 100644 --- a/src/main/resources/view/MainMenu.fxml +++ b/src/main/resources/view/MainMenu.fxml @@ -46,14 +46,18 @@ <VBox alignment="BOTTOM_RIGHT" GridPane.columnSpan="2"> <children> <DatePicker fx:id="date" /> - <HBox alignment="BOTTOM_CENTER" prefHeight="28.0" prefWidth="574.0"> + <VBox alignment="BOTTOM_CENTER" prefHeight="67.0" prefWidth="574.0"> <children> - <Label text="5000kr left" textAlignment="CENTER"> + <Label fx:id="balanceLbl" text="Balance:" textAlignment="CENTER"> <font> - <Font name="System Bold" size="12.0" /> - </font></Label> + <Font name="System Bold" size="24.0" /> + </font> + </Label> </children> - </HBox> + <padding> + <Insets bottom="-20.0" /> + </padding> + </VBox> </children> </VBox> <StackPane GridPane.columnSpan="2" GridPane.rowIndex="1"> @@ -65,9 +69,9 @@ </ImageView> <ProgressBar fx:id="progressbar" prefHeight="40.0" prefWidth="554.0" progress="0.72" translateY="-10.0" /> <Label fx:id="today" text="Today" textAlignment="CENTER" translateX="-150.0" translateY="-2.0"> - <font> - <Font name="System Bold" size="12.0" /> - </font> + <StackPane.margin> + <Insets left="300.0" /> + </StackPane.margin> </Label> </children> </StackPane> @@ -85,7 +89,7 @@ </ImageView> </graphic> </Button> - <Button fx:id="addExpenseButton" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchExpenses" prefHeight="125.0" prefWidth="125.0" text="Add expense"> + <Button fx:id="addExpenseBtn" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="125.0" prefWidth="125.0" text="Add expense"> <graphic> <ImageView fitHeight="79.0" fitWidth="87.0" pickOnBounds="true"> <cursor> @@ -97,7 +101,7 @@ </ImageView> </graphic> </Button> - <Button fx:id="overviewButton" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchOverview" prefHeight="125.0" prefWidth="125.0" text="Overview"> + <Button fx:id="overviewBtn" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="125.0" prefWidth="125.0" text="Overview"> <graphic> <ImageView fitHeight="63.0" fitWidth="87.0" pickOnBounds="true"> <cursor> @@ -141,7 +145,7 @@ </HBox.margin> </Button> <Region prefHeight="70.0" prefWidth="103.0" /> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="BUDGET FEBRUARY" textAlignment="CENTER"> + <Text fx:id="budgetMonth" strokeType="OUTSIDE" strokeWidth="0.0" text="BUDGET MARCH" textAlignment="CENTER"> <HBox.margin> <Insets /> </HBox.margin>