From 2297af9604b8e6925ac167a3917bd2f89a66707a Mon Sep 17 00:00:00 2001 From: Harry Linrui Xu <harrylx@stud.ntnu.no> Date: Tue, 11 Apr 2023 10:32:08 +0200 Subject: [PATCH] Added input validation to add dialog boxes. --- .../demo/controller/AddBudgetController.java | 46 ++- .../demo/controller/AddExpenseController.java | 34 ++ .../demo/controller/AddIncomeController.java | 32 +- .../demo/controller/BudgetController.java | 50 ++- .../demo/controller/FinanceController.java | 7 + .../controller/IncomeExpenseController.java | 101 ++++-- .../idatt1002/demo/controller/MainMenu.java | 3 + .../demo/controller/SceneController.java | 2 +- src/main/resources/Budget/Budget.budget | 4 + src/main/resources/view/AddBudgetNew.fxml | 75 +++++ src/main/resources/view/AddExpense.fxml | 46 ++- src/main/resources/view/AddIncome.fxml | 55 ++- src/main/resources/view/Income.fxml | 312 +++++++++++------- .../resources/view/IncomeAndExpenses.fxml | 34 +- 14 files changed, 583 insertions(+), 218 deletions(-) create mode 100644 src/main/resources/view/AddBudgetNew.fxml diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AddBudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AddBudgetController.java index 8a44c9b3..d4ec105b 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddBudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddBudgetController.java @@ -7,8 +7,10 @@ import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.control.TextField; +import javafx.scene.text.Text; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Budget.BudgetItem; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; @@ -37,7 +39,14 @@ public class AddBudgetController { private Button okBtn; @FXML - private Button cancelButton; + private Button cancelBtn; + + /** + * Initializes the category drop box by filling it with all the values from the ExpenseCategory enum. + * It then sets a prompt text on the box. + */ + @FXML + private Text errorMsg; /** * Initializes the category drop box by filling it with all the values from the ExpenseCategory enum. @@ -51,7 +60,10 @@ public class AddBudgetController { //Set the values inside the dropbox categoryVariable.setItems(expenseCategories); //Set default value - categoryVariable.setPromptText("Category"); + categoryVariable.setValue(ExpenseCategory.FOOD); + + addEventFilters(); + } public ExpenseCategory getCategory(){ @@ -89,7 +101,7 @@ public class AddBudgetController { * @param event If the OK button is pressed. */ @FXML - public void pressOkBtn(ActionEvent event) { + private void pressOkBtn(ActionEvent event) { //Instantiates a new budget item if(newBudgetItem == null){ ExpenseCategory category = getCategory(); @@ -108,11 +120,37 @@ public class AddBudgetController { stage.close(); } + private void addEventFilters() { + okBtn.addEventFilter( + ActionEvent.ACTION, event -> { + try { + validateInputs(); + } catch(IllegalArgumentException e) { + event.consume(); + errorMsg.setOpacity(1); + } + } + ); + } + + private boolean validateInputs() { + try { + BudgetItem item = new BudgetItem( + Double.parseDouble(amountVariable.getText()), + descriptionVariable.getText(), + categoryVariable.getValue()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid inputs. Cannot instantiate item", e); + } + return true; + } + /** * Closes the dialog box. * @param actionEvent A button click on the close button. */ - public void closeButton(ActionEvent actionEvent) { + @FXML + private void pressCancelBtn(ActionEvent actionEvent) { final Node source = (Node) actionEvent.getSource(); final Stage stage = (Stage) source.getScene().getWindow(); stage.close(); 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 1356e31a..2d3af8ca 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java @@ -14,7 +14,9 @@ import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.DatePicker; import javafx.scene.control.TextField; +import javafx.scene.text.Text; import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Budget.BudgetItem; import no.ntnu.idatt1002.demo.data.Economics.Expense; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; import no.ntnu.idatt1002.demo.data.Economics.Expense; @@ -39,6 +41,9 @@ public class AddExpenseController { @FXML private TextField dateField; + @FXML + private Text errorMsg; + @FXML private DatePicker datePicker; @@ -75,6 +80,9 @@ public class AddExpenseController { //Set date to today datePicker.setValue(LocalDate.now()); + + //Adding event filter to okBtn + addEventFilters(); } public ExpenseCategory getCategory() { @@ -138,6 +146,8 @@ public class AddExpenseController { chosenExpense.setDate(datePicker.getValue()); } + errorMsg.setOpacity(0); + final Node source = (Node) event.getSource(); ((Stage) source.getScene().getWindow()).close(); } @@ -153,4 +163,28 @@ public class AddExpenseController { stage.close(); } + + private void addEventFilters() { + okBtn.addEventFilter( + ActionEvent.ACTION, event -> { + try { + validateInputs(); + } catch(IllegalArgumentException e) { + event.consume(); + errorMsg.setOpacity(1); + } + }); + } + private boolean validateInputs() { + try { + Expense expense = new Expense( + Double.parseDouble(amountField.getText()), recurringBox.getValue(), + categoryBox.getValue(), datePicker.getValue()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid input. Cannot instantiate expense", e); + } + return true; + } + + } \ No newline at end of file diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java index 9c96a53c..a758d154 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java @@ -14,6 +14,7 @@ import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.DatePicker; import javafx.scene.control.TextField; +import javafx.scene.text.Text; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Economics.Expense; import no.ntnu.idatt1002.demo.data.Economics.Income; @@ -36,6 +37,8 @@ public class AddIncomeController { @FXML private Button okBtn; + @FXML + private Text errorMsg; @FXML private DatePicker datePicker; @@ -72,6 +75,8 @@ public class AddIncomeController { //Set date to today datePicker.setValue(LocalDate.now()); + + addEventFilters(); } public IncomeCategory getCategory() { @@ -100,9 +105,7 @@ public class AddIncomeController { 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()); + //Set the values of the input fields of the dialog box descriptionField.textProperty().set(income.getDescription()); @@ -121,7 +124,7 @@ public class AddIncomeController { @FXML public void pressOkBtn(ActionEvent event) { //Instantiates a new income - if (chosenIncome == null) { + if (newIncome == null) { LocalDate date = datePicker.getValue(); double amount = Double.parseDouble(amountField.getText()); String description = descriptionField.getText(); @@ -142,6 +145,27 @@ public class AddIncomeController { ((Stage) source.getScene().getWindow()).close(); } + private void addEventFilters() { + okBtn.addEventFilter( + ActionEvent.ACTION, event -> { + try { + validateInputs(); + } catch(IllegalArgumentException e) { + event.consume(); + errorMsg.setOpacity(1); + } + }); + } + private boolean validateInputs() { + try { + Income income = new Income( + Double.parseDouble(amountField.getText()), recurringBox.getValue(), + categoryBox.getValue(), datePicker.getValue()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid inputs. Cannot instantiate income", e); + } + return true; + } /** * Closes the dialog box and cancels any pending changes. diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java index 45f7fdea..1325d296 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java @@ -1,5 +1,6 @@ package no.ntnu.idatt1002.demo.controller; +import java.time.LocalDate; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; @@ -60,6 +61,9 @@ public class BudgetController implements FinanceController { @FXML private Text sum; + @FXML + private DatePicker date; + @FXML private TableColumn<BudgetItem, Double> percentageColumn; @@ -74,7 +78,11 @@ public class BudgetController implements FinanceController { @FXML public void initialize() throws IOException { - //TODO if budget is not empty - disable + //TODO if budget is not empty (HAS VALUES) -> make uneditable -> EVENT FILTER TO CONTEXT MENU + //TODO disable return to main menu when creating budget because this is the same view as when you create budeget + //TODO make budget item throw exception with negative amount + //TODO specify error messgage for when amount is exceeded / duplicate exists + //todo properly close screen so things are saved //Initialize table columns categoryCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, ExpenseCategory>("budgetCategory")); amountCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, Double>("budgetAmount")); @@ -85,18 +93,34 @@ public class BudgetController implements FinanceController { budgetList = FXCollections.observableArrayList(general.getBudgetItems()); budgetTableView.setItems(budgetList); + formatDatePicker(); //createBudgetPieChart(); //Initialize sum field under the tableview //sum.setText(String.valueOf(general.totalSum())); } - private ObservableList<PieChart.Data> createBudgetPieChart() { //TODO DOESNT WORK IF BUDGETITEM HAS NO BUDGET - return FXCollections.observableArrayList( - new Data("Food", general.getBudgetItem(ExpenseCategory.FOOD).getBudgetAmount()), - new Data("Books", general.getBudgetItem(ExpenseCategory.BOOKS).getBudgetAmount()), - new Data("Clothes", general.getBudgetItem(ExpenseCategory.CLOTHES).getBudgetAmount()), - new Data("Other", general.getBudgetItem(ExpenseCategory.OTHER).getBudgetAmount()) - ); + private ObservableList<PieChart.Data> createBudgetPieChart() throws IllegalArgumentException { //TODO DOESNT WORK IF BUDGETITEM HAS NO BUDGET + try { + return FXCollections.observableArrayList( + new Data("Food", general.getBudgetItem(ExpenseCategory.FOOD).getBudgetAmount()), + new Data("Books", general.getBudgetItem(ExpenseCategory.BOOKS).getBudgetAmount()), + new Data("Clothes", + general.getBudgetItem(ExpenseCategory.CLOTHES).getBudgetAmount()), + new Data("Other", general.getBudgetItem(ExpenseCategory.OTHER).getBudgetAmount()) + ); + } catch(IllegalArgumentException iae) { + return FXCollections.observableArrayList(); + } + } + + /** + * Method for disabling the date picker, yet having its opacity at max. + */ + private void formatDatePicker() { + date.setValue(LocalDate.now()); + date.setDisable(true); + date.setStyle("-fx-opacity: 1"); + date.getEditor().setStyle("-fx-opacity: 1"); } @Override @@ -114,7 +138,7 @@ public class BudgetController implements FinanceController { String dialogTitle = ""; DialogMode dialogMode; - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/AddBudget.fxml")); + FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/AddBudgetNew.fxml")); Dialog<BudgetItem> dialog = new Dialog<>(); dialog.initModality(Modality.APPLICATION_MODAL); @@ -189,7 +213,7 @@ public class BudgetController implements FinanceController { public void refreshTableView(){ this.budgetList.setAll(general.getBudgetItems()); //Refreshing the sum of the amounts of the budget - this.sum.setText(String.valueOf(general.totalSum())); + //this.sum.setText(String.valueOf(general.totalSum())); } /** @@ -240,6 +264,7 @@ public class BudgetController implements FinanceController { //Instantiate new budget if (fileHandlingBudget.isEmpty(fileName)) { general = new GeneralBudget(31, 1000); + //throws new IOException("Not valid budget") } else { //Load previous budget try { general = fileHandlingBudget.readGeneralBudgetFromFile(fileName); @@ -251,9 +276,8 @@ public class BudgetController implements FinanceController { } /** - * Switches scenes from the budget scene to another, by loading a new FXML file and setting the scene to this location. - * The destination depends entirely on which button is pressed. - * @param event A button click on the buttons on the buttonbar or the next button + * Switches scenes back to main menu, by loading a new FXML file and setting the scene to this location. + * @param event A button click on the return to main menu button * @throws IOException If an error occurs with loading any of the FXML files. */ @FXML diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java index 96efb651..09b60937 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java @@ -49,4 +49,11 @@ public interface FinanceController { * @throws IOException If an error occurs while writing to the file. */ void saveDataToFile() throws IOException; + + /** + * Switches scenes back to main menu, by loading a new FXML file and setting the scene to this location. + * @param event A button click on the return to main menu button + * @throws IOException If an error occurs with loading any of the FXML files. + */ + void returnToMainMenu(javafx.event.ActionEvent event) throws IOException; } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java index 4b3014da..4e9f1bc7 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java @@ -2,6 +2,7 @@ package no.ntnu.idatt1002.demo.controller; import java.awt.event.ActionEvent; import java.io.IOException; +import java.time.LocalDate; import java.util.Optional; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -89,12 +90,6 @@ public class IncomeExpenseController implements FinanceController { @FXML private MenuItem addIncome; - @FXML - private Button deleteBtn; - - @FXML - private Button editBtn; - @FXML private ProgressBar budgetProgress; @@ -112,6 +107,19 @@ public class IncomeExpenseController implements FinanceController { @FXML private Label title; + + @FXML + private MenuItem editIncomeMenu; + + @FXML + private MenuItem deleteIncomeMenu; + + @FXML + private MenuItem editExpenseMenu; + + @FXML + private MenuItem deleteExpenseMenu; + private IncomeRegister incomeRegister; private ExpenseRegister expenseRegister; @@ -147,15 +155,15 @@ public class IncomeExpenseController implements FinanceController { expenseTableView.setItems(expenses); //Setting pie chart values to correspond with the registers - refreshPieCharts(); incomePieChart.setLegendSide(Side.RIGHT); - refreshPieCharts(); expensePieChart.setLegendSide(Side.RIGHT); expensePieChart.setLabelLineLength(10); + refreshPieCharts(); refreshProgress(); + formatDatePicker(); //Initialize sum field under the tableview // inSum.setText(String.valueOf(incomeRegister.getTotalSum())); //expSum.setText(String.valueOf(expenseRegister.getTotalSum())); @@ -192,20 +200,35 @@ public class IncomeExpenseController implements FinanceController { ); } + /** + * Method for disabling the date picker, yet having its opacity at max. + */ + private void formatDatePicker() { + date.setValue(LocalDate.now()); + date.setDisable(true); + date.setStyle("-fx-opacity: 1"); + date.getEditor().setStyle("-fx-opacity: 1"); + } /** * Method for handling the adding of new entries in the tableview. * @param event A button click on the add button. */ @Override public void handleAddBtn(javafx.event.ActionEvent event) { + int sizeBf = (expenseRegister.getItems().size() + incomeRegister.getItems().size()); + if (event.getSource() == addIncome) { handleAddIncome(); } else if (event.getSource() == addExpense){ handleAddExpense(); } - refreshTableView(); - refreshPieCharts(); - refreshProgress(); + + int sizeAf = (expenseRegister.getItems().size() + incomeRegister.getItems().size()); + + if (sizeAf != sizeBf) { + refreshTableView(); + refreshProgress(); + } } /** @@ -214,26 +237,34 @@ public class IncomeExpenseController implements FinanceController { * @param event A button click on the edit button. */ @Override - public void handleEditBtn(javafx.event.ActionEvent event) { + public void handleEditBtn(javafx.event.ActionEvent event) { + System.out.println(event.getSource()); Income chosenIncome = incomeTableView.getSelectionModel().getSelectedItem(); Expense chosenExpense = expenseTableView.getSelectionModel().getSelectedItem(); - if (event.getSource() == editBtn) { - if (chosenIncome!= null) { - handleEditIncome(chosenIncome); - } else if (chosenExpense != null) { - handleEditExpense(chosenExpense); - } - } else if (event.getSource() == deleteBtn) { - if (chosenIncome != null) { - handleDeleteIncome(chosenIncome); - } else if (chosenExpense != null) { - handleDeleteExpense(chosenExpense); - } + boolean isEditIncome = event.getSource() == editIncomeMenu; + + boolean isDeleteIncome = event.getSource() == deleteIncomeMenu; + + boolean isEditExpense = event.getSource() == editExpenseMenu; + + boolean isDeleteExpense = event.getSource() == deleteExpenseMenu; + + System.out.println(chosenIncome); + System.out.println(chosenExpense); + + if (isEditIncome) { + handleEditIncome(chosenIncome); + } else if (isDeleteIncome) { + handleDeleteIncome(chosenIncome); + } else if (isEditExpense) { + handleEditExpense(chosenExpense); + } else if (isDeleteExpense) { + handleDeleteExpense(chosenExpense); } else return; + //Updates the tableview and pie chart using the register refreshTableView(); - refreshPieCharts(); refreshProgress(); } @@ -261,7 +292,7 @@ public class IncomeExpenseController implements FinanceController { this.expenses.setAll(expenseRegister.getItems()); //this.sum.setText(String.valueOf(incomeRegister.getTotalSum())); } - + private void refreshPieCharts() { this.incomePieChart.setData(createIncomePieChart()); this.expensePieChart.setData(createExpensePieChart()); @@ -302,6 +333,7 @@ public class IncomeExpenseController implements FinanceController { //Adds the new item to the register if (newIncome != null) { incomeRegister.addItem(newIncome); + incomePieChart.setData(createIncomePieChart()); } } @@ -337,11 +369,14 @@ public class IncomeExpenseController implements FinanceController { //Adds the new item to the register if (newExpense != null) { expenseRegister.addItem(newExpense); + expensePieChart.setData(createExpensePieChart()); } } @FXML private void handleEditIncome(Income chosenIncome) { + //Create copy of chosenIncome before changes + //Instantiate FXML loader and loads the popup for adding income FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/AddIncome.fxml")); @@ -366,6 +401,9 @@ public class IncomeExpenseController implements FinanceController { dialog.setTitle(dialogTitle); // Show the Dialog and wait for the user to close it dialog.showAndWait(); + + this.incomePieChart.setData(createIncomePieChart()); + } @FXML @@ -393,6 +431,8 @@ public class IncomeExpenseController implements FinanceController { dialog.setTitle(dialogTitle); // Show the Dialog and wait for the user to close it dialog.showAndWait(); + + this.expensePieChart.setData(createExpensePieChart()); } @FXML @@ -401,6 +441,7 @@ public class IncomeExpenseController implements FinanceController { if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { incomeRegister.removeItem(chosenIncome); } + this.incomePieChart.setData(createIncomePieChart()); } @FXML @@ -409,7 +450,7 @@ public class IncomeExpenseController implements FinanceController { if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { expenseRegister.removeItem(chosenExpense); } - + this.expensePieChart.setData(createExpensePieChart()); } /** * Returns an optional, which is a popup alert box, asking for confirmation for deleting an @@ -499,10 +540,12 @@ public class IncomeExpenseController implements FinanceController { } /** - * Switches the scene to the Main Menu scene. + * Switches scenes back to main menu, by loading a new FXML file and setting the scene to this location. + * @param event A button click on the return to main menu button + * @throws IOException If an error occurs with loading any of the FXML files. */ @FXML - private void returnToMainMenu(javafx.event.ActionEvent event) throws IOException { + public void returnToMainMenu(javafx.event.ActionEvent event) throws IOException { saveDataToFile(); FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java index c785b25e..14dd1ef7 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java @@ -93,6 +93,8 @@ public class MainMenu { //Initialize all controllers initializeControllers(); + mainBar.setStyle("-fx-accent: green;"); + double incomeSum = incomeRegister.getTotalSum(); double expenseSum = expenseRegister.getTotalSum(); @@ -163,6 +165,7 @@ public class MainMenu { Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); + stage.setResizable(false); stage.show(); } } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java index a94b8678..dae0ae45 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java @@ -33,7 +33,7 @@ public class SceneController { } public void switchIncome(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Income.fxml")); + FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/IncomeAndExpenses.fxml")); Parent root = loader.load(); stage = (Stage)((Node)event.getSource()).getScene().getWindow(); scene = new Scene(root); diff --git a/src/main/resources/Budget/Budget.budget b/src/main/resources/Budget/Budget.budget index 78b9f48b..08268ba2 100644 --- a/src/main/resources/Budget/Budget.budget +++ b/src/main/resources/Budget/Budget.budget @@ -5,3 +5,7 @@ budgetAmount=500.0 budgetCategory=FOOD budgetDescription=dd +budgetAmount=100.0 +budgetCategory=CLOTHES +budgetDescription= + diff --git a/src/main/resources/view/AddBudgetNew.fxml b/src/main/resources/view/AddBudgetNew.fxml new file mode 100644 index 00000000..080d9ae9 --- /dev/null +++ b/src/main/resources/view/AddBudgetNew.fxml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?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?> +<?import javafx.scene.text.Font?> +<?import javafx.scene.text.Text?> + +<DialogPane prefHeight="295.0" prefWidth="360.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.AddBudgetController"> + <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> + <children> + <Label text="Category"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <Label text="Amount:" GridPane.rowIndex="1"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <Label text="Description:" GridPane.rowIndex="2"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <TextField fx:id="amountVariable" promptText="100" GridPane.columnIndex="1" GridPane.rowIndex="1" /> + <TextField fx:id="descriptionVariable" promptText="(optional)" GridPane.columnIndex="1" GridPane.rowIndex="2" /> + <HBox alignment="BOTTOM_RIGHT" prefHeight="100.0" prefWidth="200.0" spacing="10.0" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="4"> + <children> + <Button fx:id="cancelBtn" mnemonicParsing="false" onAction="#pressCancelBtn" prefHeight="25.0" prefWidth="60.0" text="Cancel"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Button> + <Button fx:id="okBtn" mnemonicParsing="false" onAction="#pressOkBtn" prefHeight="25.0" prefWidth="60.0" text="OK"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Button> + </children> + <GridPane.margin> + <Insets top="20.0" /> + </GridPane.margin> + </HBox> + <Text fx:id="errorMsg" fill="#d90808" opacity="0.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Invalid input. Make sure that amount is an integer above 1" wrappingWidth="300.0" GridPane.columnSpan="3" GridPane.rowIndex="3" GridPane.rowSpan="2"> + <font> + <Font name="Lucida Console" size="11.0" /> + </font> + </Text> + <ComboBox fx:id="categoryVariable" prefWidth="150.0" GridPane.columnIndex="1" /> + </children> + </GridPane> + </content> +</DialogPane> diff --git a/src/main/resources/view/AddExpense.fxml b/src/main/resources/view/AddExpense.fxml index 4fda6662..b7ee352d 100644 --- a/src/main/resources/view/AddExpense.fxml +++ b/src/main/resources/view/AddExpense.fxml @@ -11,6 +11,8 @@ <?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.text.Font?> +<?import javafx.scene.text.Text?> <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> @@ -27,27 +29,55 @@ <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" /> + <Label text="Date:"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Label> + <Label text="Amount:" GridPane.rowIndex="1"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Label> + <Label text="Description:" GridPane.rowIndex="2"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Label> + <Label text="Category: " GridPane.rowIndex="3"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Label> + <Label text="Recurring: " GridPane.rowIndex="4"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Label> <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" /> <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"> + <HBox alignment="BOTTOM_RIGHT" prefHeight="100.0" prefWidth="200.0" spacing="10.0" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="7"> <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" /> + <Button fx:id="cancelBtn" mnemonicParsing="false" onAction="#pressCancelBtn" prefHeight="25.0" prefWidth="60.0" text="Cancel"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Button> + <Button fx:id="okBtn" mnemonicParsing="false" onAction="#pressOkBtn" prefHeight="25.0" prefWidth="60.0" text="OK"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font></Button> </children> <GridPane.margin> <Insets top="20.0" /> </GridPane.margin> </HBox> <DatePicker fx:id="datePicker" GridPane.columnIndex="1" /> + <Text fx:id="errorMsg" fill="#d90808" opacity="0.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Invalid input. Please make sure that amount is an integer above 1." wrappingWidth="300.0" GridPane.columnSpan="3" GridPane.rowIndex="5" GridPane.rowSpan="2"> + <font> + <Font name="Lucida Console" size="11.0" /> + </font> + </Text> </children> </GridPane> </content> diff --git a/src/main/resources/view/AddIncome.fxml b/src/main/resources/view/AddIncome.fxml index abdfe7c2..f25c1bef 100644 --- a/src/main/resources/view/AddIncome.fxml +++ b/src/main/resources/view/AddIncome.fxml @@ -11,6 +11,8 @@ <?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.text.Font?> +<?import javafx.scene.text.Text?> <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> @@ -27,27 +29,62 @@ <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" /> + <Label text="Date:"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <Label text="Amount:" GridPane.rowIndex="1"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <Label text="Description:" GridPane.rowIndex="2"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <Label text="Category: " GridPane.rowIndex="3"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> + <Label text="Recurring: " GridPane.rowIndex="4"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Label> <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="categoryBox" prefWidth="150.0" promptText="Food" 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"> + <HBox alignment="BOTTOM_RIGHT" prefHeight="100.0" prefWidth="200.0" spacing="10.0" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="7"> <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" /> + <Button fx:id="cancelBtn" mnemonicParsing="false" onAction="#pressCancelBtn" prefHeight="25.0" prefWidth="60.0" text="Cancel"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Button> + <Button fx:id="okBtn" mnemonicParsing="false" onAction="#pressOkBtn" prefHeight="25.0" prefWidth="60.0" text="OK"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> + </Button> </children> <GridPane.margin> <Insets top="20.0" /> </GridPane.margin> </HBox> <DatePicker fx:id="datePicker" GridPane.columnIndex="1" /> + <Text fx:id="errorMsg" fill="#d90808" opacity="0.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Invalid input. Please make sure that amount is an integer above 1." wrappingWidth="300.0" GridPane.columnSpan="3" GridPane.rowIndex="5" GridPane.rowSpan="2"> + <font> + <Font name="Lucida Console" size="11.0" /> + </font> + </Text> </children> </GridPane> </content> diff --git a/src/main/resources/view/Income.fxml b/src/main/resources/view/Income.fxml index f9f1e586..448891dd 100644 --- a/src/main/resources/view/Income.fxml +++ b/src/main/resources/view/Income.fxml @@ -2,8 +2,15 @@ <?import javafx.geometry.Insets?> <?import javafx.scene.Cursor?> +<?import javafx.scene.chart.PieChart?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.ContextMenu?> +<?import javafx.scene.control.DatePicker?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.MenuButton?> +<?import javafx.scene.control.MenuItem?> +<?import javafx.scene.control.ProgressBar?> <?import javafx.scene.control.TableColumn?> <?import javafx.scene.control.TableView?> <?import javafx.scene.image.Image?> @@ -13,17 +20,15 @@ <?import javafx.scene.layout.ColumnConstraints?> <?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> +<?import javafx.scene.layout.Pane?> <?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.IncomeController"> +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="695.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.IncomeExpenseController"> <children> - <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> + <ImageView fitHeight="695.0" fitWidth="1130.0" pickOnBounds="true"> <image> <Image url="@../Images/backgroundMini.jpg" /> </image> @@ -31,72 +36,78 @@ <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="Income" textAlignment="CENTER" wrappingWidth="174.6796875"> - <HBox.margin> - <Insets /> - </HBox.margin> + <VBox prefHeight="695.0" prefWidth="1100.0"> + <children> + <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="143.0" prefWidth="1100.0"> + <right> + <Pane BorderPane.alignment="CENTER"> + <children> + <Label fx:id="daysLeftLbl" layoutX="27.0" layoutY="83.0" text="Days left: 31"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Label> + <DatePicker fx:id="date" layoutX="-4.0" layoutY="55.0" prefWidth="175.0" /> + </children> + </Pane> + </right> + <left> + <Pane prefWidth="175.0" BorderPane.alignment="CENTER"> + <children> + <Button fx:id="returnBtn" alignment="CENTER" layoutX="-2.0" layoutY="58.0" mnemonicParsing="false" onAction="#returnToMainMenu" text="Return to Main Menu"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Button> + </children> + </Pane> + </left> + <center> + <Label fx:id="title" text="INCOME AND EXPENSES" textAlignment="CENTER" BorderPane.alignment="CENTER"> <font> - <Font size="48.0" /> + <Font name="Lucida Console" 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"> + </Label> + </center> + <VBox.margin> + <Insets left="15.0" /> + </VBox.margin> + </BorderPane> + <BorderPane prefHeight="64.0" prefWidth="1100.0"> + <left> + <HBox prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER"> <children> - <Button fx:id="addBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleAddButton" text="Add" textAlignment="CENTER"> + <MenuButton mnemonicParsing="false" prefHeight="25.0" prefWidth="50.0"> + <items> + <MenuItem fx:id="addIncome" mnemonicParsing="false" onAction="#handleAddBtn" text="Income" /> + <MenuItem fx:id="addExpense" mnemonicParsing="false" onAction="#handleAddBtn" text="Expense" /> + </items> <graphic> - <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> + <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> <image> - <Image url="@../Images/add_image.png" /> + <Image url="@../Images/add.png" /> </image> </ImageView> </graphic> - </Button> - <Button fx:id="editBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleEditButton" text="Edit" textAlignment="CENTER"> + </MenuButton> + <Button fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="25.0" prefWidth="60.0"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> <graphic> - <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> + <ImageView fitHeight="30.0" fitWidth="50.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="#handleDeleteBtn" text="Delete" textAlignment="CENTER"> + <Button fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="25.0" prefWidth="60.0"> + <font> + <Font name="Lucida Console" size="12.0" /> + </font> <graphic> - <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> + <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> <image> <Image url="@../Images/delete.png" /> </image> @@ -104,86 +115,143 @@ </graphic> </Button> </children> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <padding> - <Insets bottom="5.0" /> - </padding> + <BorderPane.margin> + <Insets left="30.0" /> + </BorderPane.margin> </HBox> - <VBox alignment="BOTTOM_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1"> + </left> + <right> + <Pane BorderPane.alignment="CENTER"> <children> - <ComboBox fx:id="show" prefWidth="150.0" promptText="Show "> + <ProgressBar fx:id="budgetProgress" prefWidth="200.0" progress="0.0" /> + </children> + </Pane> + </right> + <opaqueInsets> + <Insets /> + </opaqueInsets> + <VBox.margin> + <Insets left="10.0" right="15.0" /> + </VBox.margin> + <center> + <Pane BorderPane.alignment="CENTER"> + <children> + <ComboBox fx:id="filter" layoutX="134.0" layoutY="2.0" prefWidth="150.0" promptText="Show"> <opaqueInsets> <Insets /> </opaqueInsets> - <VBox.margin> - <Insets bottom="5.0" /> - </VBox.margin> </ComboBox> </children> + </Pane> + </center> + </BorderPane> + <GridPane prefHeight="473.0" prefWidth="1055.0"> + <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" percentHeight="5.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" percentHeight="4.0" prefHeight="30.0" vgrow="SOMETIMES" /> + <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> + </rowConstraints> + <children> + <VBox maxWidth="490.0" prefHeight="215.0" prefWidth="490.0" GridPane.rowIndex="1"> + <children> + <TableView fx:id="incomeTableView" maxHeight="175.0" prefHeight="175.0" prefWidth="264.0"> + <columns> + <TableColumn fx:id="inDateCol" prefWidth="75.0" text="Date" /> + <TableColumn fx:id="inAmountCol" prefWidth="75.0" text="Amount" /> + <TableColumn fx:id="inCategoryCol" prefWidth="75.0" text="Category" /> + <TableColumn fx:id="inDescriptionCol" prefWidth="75.0" text="Description" /> + <TableColumn fx:id="inRecurringCol" prefWidth="75.0" text="Recurring" /> + </columns> + <columnResizePolicy> + <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> + </columnResizePolicy> + <contextMenu> + <ContextMenu> + <items> + <MenuItem mnemonicParsing="false" onAction="#handleEditBtn" text="Edit" /> + <MenuItem fx:id="handleDeleteIncome" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete " /> + </items> + </ContextMenu> + </contextMenu> + </TableView> + <Label text="Sum: "> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Label> + </children> </VBox> - <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="3"> + <Pane GridPane.columnIndex="1" GridPane.rowIndex="1"> <children> - <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> - </Button> + <PieChart fx:id="incomePieChart" layoutX="4.0" layoutY="-41.0" legendSide="RIGHT" maxHeight="244.0" maxWidth="512.0" prefHeight="244.0" prefWidth="350.0" title="Income" /> </children> - <padding> - <Insets top="10.0" /> - </padding> - </HBox> - <TableView fx:id="incomeTableView" prefHeight="260.0" prefWidth="485.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> - <columns> - <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"> + </Pane> + <Pane GridPane.columnIndex="1" GridPane.rowIndex="3"> + <children> + <PieChart fx:id="expensePieChart" layoutX="-2.0" layoutY="-37.0" legendSide="RIGHT" maxHeight="261.0" maxWidth="519.0" prefHeight="237.0" prefWidth="350.0" title="Expenses" /> + </children> + </Pane> + <Pane prefHeight="20.0" prefWidth="1046.0"> + <children> + <Text layoutY="16.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Income" textAlignment="CENTER"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Text> + </children> + </Pane> + <VBox GridPane.rowIndex="3"> + <children> + <TableView fx:id="expenseTableView" maxHeight="175.0" maxWidth="490.0" prefHeight="172.0" prefWidth="264.0"> + <columns> + <TableColumn fx:id="expDateCol" prefWidth="75.0" text="Date" /> + <TableColumn fx:id="expAmountCol" prefWidth="75.0" text="Amount" /> + <TableColumn fx:id="expCategoryCol" prefWidth="75.0" text="Category" /> + <TableColumn fx:id="expDescriptionCol" prefWidth="75.0" text="Description" /> + <TableColumn fx:id="expRecurringCol" prefWidth="75.0" text="Recurring" /> + </columns> + <columnResizePolicy> + <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> + </columnResizePolicy> + <contextMenu> + <ContextMenu> + <items> + <MenuItem mnemonicParsing="false" onAction="#handleEditBtn" text="Edit" /> + <MenuItem fx:id="handleDeleteExpense" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete" /> + </items> + </ContextMenu> + </contextMenu> + </TableView> + <Label text="Sum: "> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Label> + </children> + </VBox> + <Pane prefHeight="200.0" prefWidth="200.0" 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> + <Text layoutY="14.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Expenses" textAlignment="CENTER"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Text> </children> - </StackPane> + </Pane> </children> + <padding> + <Insets left="10.0" /> + </padding> + <VBox.margin> + <Insets left="30.0" right="30.0" /> + </VBox.margin> </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> + </VBox> </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> </AnchorPane> diff --git a/src/main/resources/view/IncomeAndExpenses.fxml b/src/main/resources/view/IncomeAndExpenses.fxml index 0680964f..4482bd92 100644 --- a/src/main/resources/view/IncomeAndExpenses.fxml +++ b/src/main/resources/view/IncomeAndExpenses.fxml @@ -75,7 +75,7 @@ </BorderPane> <BorderPane prefHeight="64.0" prefWidth="1100.0"> <left> - <HBox prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER"> + <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER"> <children> <MenuButton mnemonicParsing="false" prefHeight="25.0" prefWidth="50.0"> <items> @@ -90,30 +90,6 @@ </ImageView> </graphic> </MenuButton> - <Button fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="25.0" prefWidth="60.0"> - <font> - <Font name="Lucida Console" size="12.0" /> - </font> - <graphic> - <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/edit.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="25.0" prefWidth="60.0"> - <font> - <Font name="Lucida Console" size="12.0" /> - </font> - <graphic> - <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/delete.png" /> - </image> - </ImageView> - </graphic> - </Button> </children> <BorderPane.margin> <Insets left="30.0" /> @@ -136,7 +112,7 @@ <center> <Pane BorderPane.alignment="CENTER"> <children> - <ComboBox fx:id="filter" layoutX="134.0" layoutY="2.0" prefWidth="150.0" promptText="Show"> + <ComboBox fx:id="filter" layoutX="135.0" layoutY="25.0" prefWidth="150.0" promptText="Show"> <opaqueInsets> <Insets /> </opaqueInsets> @@ -173,7 +149,8 @@ <contextMenu> <ContextMenu> <items> - <MenuItem mnemonicParsing="false" text="Unspecified Action" /> + <MenuItem fx:id="editIncomeMenu" mnemonicParsing="false" onAction="#handleEditBtn" text="Edit" /> + <MenuItem fx:id="deleteIncomeMenu" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete " /> </items> </ContextMenu> </contextMenu> @@ -220,7 +197,8 @@ <contextMenu> <ContextMenu> <items> - <MenuItem mnemonicParsing="false" text="Unspecified Action" /> + <MenuItem fx:id="editExpenseMenu" mnemonicParsing="false" onAction="#handleEditBtn" text="Edit" /> + <MenuItem fx:id="deleteExpenseMenu" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete" /> </items> </ContextMenu> </contextMenu> -- GitLab