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 d4ec105bc241675715d1486ab1112ac8079c59f4..de9c4872ad6e6f9facbb3ecd170004c6b9c63867 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddBudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddBudgetController.java @@ -62,8 +62,8 @@ public class AddBudgetController { //Set default value categoryVariable.setValue(ExpenseCategory.FOOD); + //Adding event filters to buttons addEventFilters(); - } public ExpenseCategory getCategory(){ @@ -120,6 +120,10 @@ public class AddBudgetController { stage.close(); } + /** + * Adds event filter to okBtn. If the budget item is invalid the event is consumed and + * an error message is displayed. + */ private void addEventFilters() { okBtn.addEventFilter( ActionEvent.ACTION, event -> { @@ -133,7 +137,14 @@ public class AddBudgetController { ); } - private boolean validateInputs() { + /** + * Input validation for a budget item. Attempts to instantiate a new item + * and passes only if the item is valid. + + * @return True, only if the item can be instantiated. + * @throws IllegalArgumentException if the input fields contain invalid inputs. + */ + private boolean validateInputs() throws IllegalArgumentException { try { BudgetItem item = new BudgetItem( Double.parseDouble(amountVariable.getText()), 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 2d3af8ca6cb64c766c5193e4c1239db863ed8c48..e24143dfe1548d639e091355b668b2a2c648bd14 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddExpenseController.java @@ -74,6 +74,7 @@ public class AddExpenseController { //Set default value categoryBox.setValue(ExpenseCategory.FOOD); + //Set the recurring field options ObservableList<Boolean> recurring = FXCollections.observableArrayList(true, false); recurringBox.setItems(recurring); recurringBox.setValue(false); @@ -146,8 +147,6 @@ public class AddExpenseController { chosenExpense.setDate(datePicker.getValue()); } - errorMsg.setOpacity(0); - final Node source = (Node) event.getSource(); ((Stage) source.getScene().getWindow()).close(); } @@ -164,6 +163,10 @@ public class AddExpenseController { stage.close(); } + /** + * Adds event filter to okBtn. If the expense is invalid the event is consumed and + * an error message is displayed. + */ private void addEventFilters() { okBtn.addEventFilter( ActionEvent.ACTION, event -> { @@ -175,6 +178,14 @@ public class AddExpenseController { } }); } + + /** + * Input validation for an expense. Attempts to instantiate a new item + * and passes only if the expense is valid. + + * @return True, only if the expense can be instantiated. + * @throws IllegalArgumentException if the input fields contain invalid inputs. + */ private boolean validateInputs() { try { Expense expense = new Expense( @@ -185,6 +196,4 @@ public class AddExpenseController { } 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 a758d154755e00e9017cc933e92db3e8647ef86c..6f2d26d396cc88a015a63d46aadede7baecba960 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIncomeController.java @@ -69,6 +69,7 @@ public class AddIncomeController { //Set default value categoryBox.setValue(IncomeCategory.GIFT); + //Set the possible values for the recurring combo box ObservableList<Boolean> recurring = FXCollections.observableArrayList(true, false); recurringBox.setItems(recurring); recurringBox.setValue(false); @@ -145,6 +146,10 @@ public class AddIncomeController { ((Stage) source.getScene().getWindow()).close(); } + /** + * Adds event filter to okBtn. If the expense is invalid the event is consumed and + * an error message is displayed. + */ private void addEventFilters() { okBtn.addEventFilter( ActionEvent.ACTION, event -> { @@ -156,6 +161,14 @@ public class AddIncomeController { } }); } + + /** + * Input validation for an income. Attempts to instantiate a new item + * and passes only if the income is valid. + + * @return True, only if the income can be instantiated. + * @throws IllegalArgumentException if the input fields contain invalid inputs. + */ private boolean validateInputs() { try { Income income = new Income( 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 aa40ea6f80102216bdb14a7f768b0c7cdbecd760..68c7d89c85f8648319884c5d99a2c388fd18cc22 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java @@ -91,43 +91,35 @@ public class BudgetController extends FinanceController { /** * Initializes the budget register, the observable budget list and the tableview, along with the values of the dropbox used for filtering the tableview. */ - @FXML public void initialize() { - //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")); descriptionCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, String>("budgetDescription")); try { - System.out.println("Just in budget try"); + //Attempt to load budget from file general = loadBudgetDataFromFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Budget"); + //Set observable list and table view to generalbudget budgetList = FXCollections.observableArrayList(general.getBudgetItems()); budgetTableView.setItems(budgetList); - System.out.println("After loading general"); - if (FileHandlingBudgetArchive.isBudgetRegisterEmpty()) { + //Instantiate budget register + if (FileHandlingBudgetArchive.isBudgetRegisterEmpty("budgets/Archive")) { budgetRegister = new BudgetRegister(); } else { - budgetRegister = FileHandlingBudgetArchive.readBudgetArchive(""); + budgetRegister = FileHandlingBudgetArchive + .readBudgetArchive("budgets/Archive"); } - if (FileHandlingBudget.isNewBudget( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget")) { - returnToMainMenuBtn.setOpacity(0); - returnToMainMenuBtn.setDisable(true); - daysLeftLbl.setOpacity(0); - } else { + + //Refresh piecharts only if the budget is old + if (!FileHandlingBudget.isNewBudget( + "budgets/" + FileHandlingSelectedBudget. + readSelectedBudget("budgets/SelectedBudget") + "/Budget")) { refreshPieChart(); - //addBtn.setDisable(true); - //editBtn.setDisable(true); - //deleteBtn.setDisable(true); - backBtn.setDisable(true); - continueBtn.setDisable(true); - backBtn.setOpacity(0); - continueBtn.setOpacity(0); } } catch(IOException ioe) { ioe.printStackTrace(); @@ -136,7 +128,15 @@ public class BudgetController extends FinanceController { formatDatePicker(); } - public ObservableList<PieChart.Data> createPieChart() throws IllegalArgumentException { // + /** + * Method for creating a list of data used for graphing budgets in a pie chart. Only data + * for categories that have been added are included in this list. + + * @return An observable list of the sum of expenditure on each category + * @throws IllegalArgumentException if generalbudget attempts to retrieve a + * category has not been added to the budget + */ + public ObservableList<PieChart.Data> createPieChart() throws IllegalArgumentException { ObservableList<PieChart.Data> budgetData = FXCollections.observableArrayList(); List<ExpenseCategory> chosenCategories = general.getChosenBudgetCategories(); @@ -158,6 +158,9 @@ public class BudgetController extends FinanceController { ); }*/ + /** + * Method for refreshing budget pie chart + */ @Override public void refreshPieChart() { this.budgetPieChart.setData(createPieChart()); @@ -174,6 +177,10 @@ public class BudgetController extends FinanceController { date.getEditor().setStyle("-fx-opacity: 1"); } + /** + * Method for handling button presses on the add button. + * @param event A button click on the add button. + */ @Override public void handleAddBtn(ActionEvent event) { handleEditBtn(event); @@ -189,7 +196,7 @@ public class BudgetController extends FinanceController { String dialogTitle = ""; DialogMode dialogMode; - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/AddBudgetNew.fxml")); + FXMLLoader loader = new FXMLLoader(FirstMenuController.class.getResource("/view/AddBudgetNew.fxml")); Dialog<BudgetItem> dialog = new Dialog<>(); dialog.initModality(Modality.APPLICATION_MODAL); @@ -233,7 +240,7 @@ public class BudgetController extends FinanceController { showErrorDialogBox(e.getMessage(), e.getMessage(), e.getMessage()); } } - //Updates the tableview using the register + //Updates the tableview and pie chart using the register refreshTableView(); refreshPieChart(); } @@ -270,8 +277,6 @@ public class BudgetController extends FinanceController { @Override public void refreshTableView(){ this.budgetList.setAll(general.getBudgetItems()); - //Refreshing the sum of the amounts of the budget - //this.sum.setText(String.valueOf(general.totalSum())); } /** @@ -282,13 +287,20 @@ public class BudgetController extends FinanceController { @Override public void saveDataToFile() throws IOException { FileHandlingBudget.writeGeneralBudgetToFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget", general); + "budgets/" + FileHandlingSelectedBudget. + readSelectedBudget("budgets/SelectedBudget") + "/Budget", general); } + /** + * Updates the contents of the budget registers by adding a given budget name. + + * @param budgetFolderName The name of the budget project that has been newly created. + */ public void updateBudgetRegister(String budgetFolderName) { try { budgetRegister.addBudgetName(budgetFolderName); - FileHandlingBudgetArchive.writeBudgetRegisterToArchive(budgetRegister); + FileHandlingBudgetArchive + .writeBudgetRegisterToArchive(budgetRegister, "budgets/Archive"); } catch(IOException ioe) { showErrorDialogBox(ioe.getMessage(), ioe.getMessage(), ioe.getMessage()); } @@ -307,13 +319,15 @@ public class BudgetController extends FinanceController { //Adds unused categories to the table general.addUnusedCategories(); loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); - //Always saving the data when switching scenes + //Always saving the data when switching to main menu saveDataToFile(); } else if (event.getSource() == continueBtn) { + //Adds unused categories to the table general.addUnusedCategories(); - updateBudgetRegister(FileHandlingSelectedBudget.readSelectedBudget()); + updateBudgetRegister(FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget")); loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); - //Always saving the data when switching scenes + //Always saving the data when switching to main menu saveDataToFile(); } else if (event.getSource() == backBtn) { loader.setLocation(getClass().getResource("/view/dualList.fxml")); diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java index 58d42d7f3f48b406f9fbeb0ed5b04ed42edc6ceb..c3e286235f7acfc41ddae62777683b7312ee664e 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java @@ -16,23 +16,33 @@ import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; import no.ntnu.idatt1002.demo.data.Economics.Expense; +/** + * Controller for the create budget scene in the application. This controller manages everything related to + * creating a new budget, from creating new directories and incomes, to updating the SelectedBudget.current file + * that stores the current budget. + */ public class CreateBudgetController { - - public Button okBtn; - public Button cancelBtn; private String currentMonth; private Expense expense; private String budgetName; + @FXML + public Button okBtn; + @FXML + public Button cancelBtn; + @FXML private TextField nameField; @FXML private Label errorMsg; - + /** + * Initializes the window. Finds the current month, used to make the created budget's name. + * Adds an event filter to the okBtn. + */ @FXML public void initialize() { currentMonth = String.valueOf(LocalDate.now().getMonth()); @@ -43,22 +53,23 @@ public class CreateBudgetController { event.consume(); } }); - okBtn.addEventFilter( - ActionEvent.ACTION, event -> { - //if(hasDuplicate() { //TODO MAYBE THIS IN THE START BUDGET FILE - //errorMsg.setText("Budget for this month already exist") - } - ); } + + /** + * Handles button presses on the OK button. + + * @param event A button press on the OK button. + */ @FXML public void pressOkBtn(ActionEvent event) { String title = "Confirm name"; String header = "Are you sure you to use this name?"; String content = "The name cannot be changed later"; + //Create the budget name budgetName = nameField.getText(); - System.out.println(budgetName); + //Attempts to create a new directory and new files for the new budget if(!createNewFiles(budgetName)) { updateCurrentFile("", ""); errorMsg.setText("A budget of the same name already exists"); @@ -66,6 +77,7 @@ public class CreateBudgetController { return; } + //Requires confirmation for creating the new budget. Optional<ButtonType> isConfirmed = showConfirmationDialog(title, header, content); if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { updateCurrentFile(currentMonth, budgetName); @@ -77,6 +89,11 @@ public class CreateBudgetController { ((Stage) source.getScene().getWindow()).close(); } + /** + * Handles presses on the cancel button. + + * @param event A button press on the cancel button. + */ @FXML public void pressCancelBtn(ActionEvent event) { updateCurrentFile("", ""); @@ -98,6 +115,13 @@ public class CreateBudgetController { return alert.showAndWait(); } + /** + * Displays an error message dialog box with a customizable title, header and content. + + * @param title The dialog title. + * @param header The dialog header. + * @param content The dialog content. + */ private void showErrorMsgBox(String title, String header, String content) { Alert alert = new Alert(AlertType.ERROR); alert.setTitle(title); @@ -107,13 +131,20 @@ public class CreateBudgetController { alert.showAndWait(); } + /** + * Method for creating a new directory for the newly created budget, along with + * three files for storing budget, income and expense data. + + * @param budgetName The name of the budget. + * @return True, if the directories are successfully created. Else, returns false. + */ public boolean createNewFiles(String budgetName) { boolean empty; try { - empty = FileHandlingSelectedBudget.createBudgetDirectory(currentMonth + budgetName); - FileHandlingSelectedBudget.createNewIncomeFile(currentMonth + budgetName, "Income"); - FileHandlingSelectedBudget.createNewExpenseFile(currentMonth + budgetName, "Expense"); - FileHandlingSelectedBudget.createNewBudgetFile(currentMonth + budgetName, "Budget"); + empty = FileHandlingSelectedBudget.createBudgetDirectory("budgets/" + currentMonth + budgetName); + FileHandlingSelectedBudget.createNewIncomeFile("budgets/" + currentMonth + budgetName, "Income"); + FileHandlingSelectedBudget.createNewExpenseFile("budgets/" + currentMonth + budgetName, "Expense"); + FileHandlingSelectedBudget.createNewBudgetFile("budgets/" + currentMonth + budgetName, "Budget"); } catch (IOException ioe) { empty = false; System.out.println(ioe.getMessage()); @@ -123,9 +154,17 @@ public class CreateBudgetController { return empty; } + /** + * Method for updating the currently selected budget in the file that stores which + * budget is currently selected. + + * @param currentMonth The month of the year. + * @param budgetName The name of the budget. + */ public void updateCurrentFile(String currentMonth, String budgetName) { try { - FileHandlingSelectedBudget.updateSelectedBudget(currentMonth + budgetName); + FileHandlingSelectedBudget.updateSelectedBudget(currentMonth + budgetName, + "budgets/SelectedBudget"); } catch (IOException ioe) { showErrorMsgBox(ioe.getMessage(), ioe.getMessage(), ioe.getMessage()); } 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 3b50b49919e4ad50e98764c41eee22bec59a858e..250d1ab1b6ecd6c96ec91f478598c75c4c5af7cb 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java @@ -12,7 +12,7 @@ import no.ntnu.idatt1002.demo.data.Economics.FileHandling; import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; /** - * Interface for controllers for scenes with finance tableviews. + * Abstract class for controllers that control scenes with finance tableviews. * * @author Harry Linrui Xu * @since 29.3.2023 @@ -51,6 +51,10 @@ public abstract class FinanceController { /** * Returns an optional, which is a popup alert box, asking for confirmation for deleting an entry. + + * @param title The dialog box title. + * @param header The dialog box header. + * @param content The dialog box content. * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. */ public Optional<ButtonType> showConfirmationDialog(String title, String header, String content) { @@ -70,7 +74,11 @@ public abstract class FinanceController { abstract void formatDatePicker(); /** - * Displays an alert box of type error, informing of a custom error. + * Displays an error message dialog box with a customizable title, header and content. + + * @param title The dialog title. + * @param header The dialog header. + * @param content The dialog content. */ public void showErrorDialogBox(String title, String header, String content) { Alert alert = new Alert(AlertType.ERROR); @@ -88,9 +96,10 @@ public abstract class FinanceController { */ public GeneralBudget loadBudgetDataFromFile(String fileName) throws IOException { //Instantiate new budget + System.out.println("this is just beofre isempty"); + System.out.println(fileName); if (FileHandlingBudget.isEmpty(fileName)) { general = new GeneralBudget(1000); - //throws new IOException("Not valid budget") } else { //Load previous budget try { general = FileHandlingBudget.readGeneralBudgetFromFile(fileName); @@ -111,10 +120,8 @@ public abstract class FinanceController { //Instantiate new incomeRegister try { if (FileHandling.isEmpty(fileName)) { - System.out.println("Creating new income register"); incomeRegister = new IncomeRegister(); } else { //Load previous income register - System.out.println("Loading old income register"); incomeRegister = FileHandling.readIncomeRegisterFromFile(fileName); } } catch (IOException ioe) { @@ -135,10 +142,8 @@ public abstract class FinanceController { try { if (FileHandling.isEmpty(fileName)) { expenseRegister = new ExpenseRegister(); - System.out.println("Creaging new expense register"); } else { //Load previous income register expenseRegister = FileHandling.readExpenseRegisterFromFile(fileName); - System.out.println("Loading saved expense register"); } } catch (IOException ioe) { showErrorDialogBox("File reading error", "Error in reading from file", "Could not" diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/FirstMenuController.java similarity index 66% rename from src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java rename to src/main/java/no/ntnu/idatt1002/demo/controller/FirstMenuController.java index 9a35491d23414bd45c14871380de3dc56fd2898c..5a5dba9f38c967eaba403c0d5239bebbc57db0c7 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/FirstMenuController.java @@ -17,32 +17,30 @@ import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; import no.ntnu.idatt1002.demo.data.Economics.Income; -public class SceneController { +/** + * Controller for the FirstMenu view. Handles user input on the buttons + * in the scene. + */ +public class FirstMenuController { + /** + * Initializes as soon as the scene is loaded. + */ @FXML public void initialize() { } - /** - * Brings up popup window to name budget - * @throws IOException + * Brings up popup for creating a new budget. + + * @param event A button press on the OK button. */ @FXML - public void switchIncome(ActionEvent event) throws IOException { - //Bring up popup X - //Let user fill in. When OK is pressed, show confirmation dialog as the name cannot be changed X - //Create maybe a folder, and Create three new files, using the budgetName + the dateMonth as the ID // - //Overwrite a "currentFile" file with the fileName - //Then switch scene to the expense vs income - - //Instantiate FXML loader and loads the popup for adding expense + public void createBudget(ActionEvent event) { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/CreateBudget.fxml")); - String budgetName; - String dialogTitle = "Create budget"; Dialog<String> dialog = new Dialog<>(); @@ -62,10 +60,13 @@ public class SceneController { // Show the Dialog and wait for the user to close it dialog.setTitle(dialogTitle); + //Wait for user input dialog.showAndWait(); try { - if (FileHandlingSelectedBudget.readSelectedBudget() != null) { + //Only proceeds to next scene if there is a budget selected + if (FileHandlingSelectedBudget. + readSelectedBudget("budgets/SelectedBudget") != null) { switchNext(event); } } catch (IOException ioe) { @@ -73,15 +74,29 @@ public class SceneController { } } + /** + * Switches to the next scene after creating a new budget. + + * @param event A button press. + * @throws IOException if an input or output error occurred + */ private void switchNext(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); - loader.setLocation(SceneController.class.getResource("/view/dualList.fxml")); + loader.setLocation(FirstMenuController.class.getResource("/view/dualList.fxml")); Parent root = loader.load(); Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } + + /** + * Displays an error message dialog box with a customizable title, header and content. + + * @param title The dialog title. + * @param header The dialog header. + * @param content The dialog content. + */ private void showErrorDialogBox(String title, String header, String content) { Alert alert = new Alert(AlertType.ERROR); alert.setTitle(title); @@ -91,9 +106,15 @@ public class SceneController { alert.showAndWait(); } - public void switchMainMenu(ActionEvent event) throws IOException { + /** + * Method that brings up a popup, allowing users + * to choose which budget to select. The scene is then switched to the main menu + * of that budget. + * @param event A button press. + */ + public void switchMainMenu(ActionEvent event) { FXMLLoader loader = new FXMLLoader(); - loader.setLocation(SceneController.class.getResource("/view/SelectBudget.fxml")); + loader.setLocation(FirstMenuController.class.getResource("/view/SelectBudget.fxml")); String dialogTitle = "Select budget"; // Load the FXML file for your dialog box @@ -113,17 +134,26 @@ public class SceneController { dialog.showAndWait(); try { - if (FileHandlingSelectedBudget.readSelectedBudget() != null) { + //Only switches scenes if there is a budget that can be selected. + if (FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") != null) { switchChosenBudget(event); } } catch(IOException ioe) { + ioe.printStackTrace(); showErrorDialogBox("Loading error", "Could not switch to main menu", ""); } } + /** + * Method for switching to the main menu of the chosen budget. + + * @param event A button press. + * @throws IOException if an input or output error occurred + */ private void switchChosenBudget(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); - loader.setLocation(SceneController.class.getResource("/view/MainMenuNew.fxml")); + loader.setLocation(FirstMenuController.class.getResource("/view/MainMenuNew.fxml")); Parent root = loader.load(); Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); @@ -137,6 +167,11 @@ public class SceneController { stage.show(); } + /** + * Method that closes the first menu. + + * @param actionEvent Button press. + */ public void closeButton(ActionEvent actionEvent) { final Node source = (Node) actionEvent.getSource(); final Stage stage = (Stage) source.getScene().getWindow(); 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 2f0c5bb774f62ff9ae62b52f21ccf4a8df895040..79102961ac5d21d1911d8bc3cab7b5297f0da56b 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java @@ -5,6 +5,7 @@ import java.time.LocalDate; 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.geometry.Side; @@ -115,10 +116,7 @@ public class IncomeExpenseController extends FinanceController { private Button continueBtn; @FXML - private Label title; - - @FXML - private Label errorMsg; + private Label maxAmount; @FXML private MenuItem editIncomeMenu; @@ -136,8 +134,6 @@ public class IncomeExpenseController extends FinanceController { private ExpenseRegister expenseRegister; - private GeneralBudget generalBudget; - private ObservableList<Income> income; private ObservableList<Expense> expenses; @@ -148,45 +144,66 @@ public class IncomeExpenseController extends FinanceController { @FXML private PieChart incomePieChart; + /** + * Initializes the window that is controlled by the controller. + * Instantiates the income and expense registers and set them to + * table views. + */ @FXML public void initialize() { - - System.out.println("Start of initialize"); //Initialize columns setColumns(); try { - //Initialize registers and tableview + //Initialize registers incomeRegister = loadIncomeDataFromFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Income"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Income"); expenseRegister = loadExpenseDataFromFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Expense"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Expense"); } catch(IOException ioe) { showErrorDialogBox("File reading error", "Could not read register", ""); } - + //Set data for tableviews income = FXCollections.observableArrayList(incomeRegister.getItems()); incomeTableView.setItems(income); expenses = FXCollections.observableArrayList(expenseRegister.getItems()); expenseTableView.setItems(expenses); - //Setting pie chart values to correspond with the registers + //Format pie charts incomePieChart.setLegendSide(Side.RIGHT); incomePieChart.setLabelLineLength(10); expensePieChart.setLegendSide(Side.RIGHT); expensePieChart.setLabelLineLength(10); + //Update pie charts and set date refreshPieChart(); formatDatePicker(); //Initialize sum field under the tableview inSum.setText(sumText + String.valueOf(incomeRegister.getTotalSum())); expSum.setText(sumText + String.valueOf(expenseRegister.getTotalSum())); + + //Add event filter to continue, such that budgets cannot have max amount at 1 or less + continueBtn.addEventFilter( + ActionEvent.ACTION, event -> { + if (!isValidMaxAmount(incomeRegister.getTotalSum(), expenseRegister.getTotalSum())) { + event.consume(); + showErrorDialogBox("Invalid disposable income", + "Disposable income must be above 1", + "Please increase the income or decrease the expenses"); + } + } + ); } + /** + * Method for initiating all tableview columns. + */ private void setColumns() { inDateCol.setCellValueFactory(new PropertyValueFactory<>("date")); inAmountCol.setCellValueFactory(new PropertyValueFactory<>("amount")); @@ -201,7 +218,13 @@ public class IncomeExpenseController extends FinanceController { expRecurringCol.setCellValueFactory(new PropertyValueFactory<>("recurring")); } - public ObservableList<PieChart.Data> createExpensePieChart() { + /** + * Method for creating a list of data used for graphing expenses in a pie chart. The categories from the + * expenses register become the pieces of data. + + * @return An observable list of the sum of expenditure on each category + */ + private ObservableList<PieChart.Data> createExpensePieChart() { return FXCollections.observableArrayList( new Data("Food", expenseRegister.getExpenseByCategory(ExpenseCategory.FOOD).getTotalSum()), new Data("Books", expenseRegister.getExpenseByCategory(ExpenseCategory.BOOKS).getTotalSum()), @@ -210,6 +233,12 @@ public class IncomeExpenseController extends FinanceController { ); } + /** + * Method for creating a list of data used for graphing income in a pie chart. The categories from the + * income register become the pieces of data. + + * @return An observable list of the sum of earnings on each category + */ private ObservableList<PieChart.Data> createIncomePieChart() { return FXCollections.observableArrayList( new Data("Gift", incomeRegister.getIncomeByCategory(IncomeCategory.GIFT).getTotalSum()), @@ -230,6 +259,7 @@ public class IncomeExpenseController extends FinanceController { } /** * Method for handling the adding of new entries in the tableview. + * @param event A button click on the add button. */ @@ -247,6 +277,7 @@ public class IncomeExpenseController extends FinanceController { if (sizeAf != sizeBf) { refreshTableView(); + refreshDisposableIncome(); } } @@ -260,6 +291,7 @@ public class IncomeExpenseController extends FinanceController { Income chosenIncome = incomeTableView.getSelectionModel().getSelectedItem(); Expense chosenExpense = expenseTableView.getSelectionModel().getSelectedItem(); + //Determines which editing or deleting option has been chosen. boolean isEditIncome = event.getSource() == editIncomeMenu; boolean isDeleteIncome = event.getSource() == deleteIncomeMenu; @@ -268,6 +300,7 @@ public class IncomeExpenseController extends FinanceController { boolean isDeleteExpense = event.getSource() == deleteExpenseMenu; + //Initiate the chosen editing/deleting option if (isEditIncome) { handleEditIncome(chosenIncome); } else if (isDeleteIncome) { @@ -280,6 +313,7 @@ public class IncomeExpenseController extends FinanceController { //Updates the tableview and pie chart using the register refreshTableView(); + refreshDisposableIncome(); } /** @@ -307,12 +341,18 @@ public class IncomeExpenseController extends FinanceController { this.expSum.setText("Sum: " + String.valueOf(expenseRegister.getTotalSum())); } + /** + * Method for synching the pie charts to the registers. + */ @Override public void refreshPieChart() { this.incomePieChart.setData(createIncomePieChart()); this.expensePieChart.setData(createExpensePieChart()); } + /** + * Method for adding income to the income register + */ @FXML private void handleAddIncome() { //Instantiate FXML loader and loads the popup for adding income @@ -345,10 +385,14 @@ public class IncomeExpenseController extends FinanceController { //Adds the new item to the register if (newIncome != null) { incomeRegister.addItem(newIncome); + //update just the income pie chart incomePieChart.setData(createIncomePieChart()); } } + /** + * Method for adding expense to the expense register. + */ @FXML private void handleAddExpense() { //Instantiate FXML loader and loads the popup for adding expense @@ -381,10 +425,16 @@ public class IncomeExpenseController extends FinanceController { //Adds the new item to the register if (newExpense != null) { expenseRegister.addItem(newExpense); + //Update just the expense pie chart. expensePieChart.setData(createExpensePieChart()); } } + /** + * Method for editing a chosen income in the income register. + + * @param chosenIncome The chosen income. + */ @FXML private void handleEditIncome(Income chosenIncome) { //Create copy of chosenIncome before changes @@ -415,10 +465,16 @@ public class IncomeExpenseController extends FinanceController { // Show the Dialog and wait for the user to close it dialog.showAndWait(); + //Refresh just the income pie chart incomePieChart.setData(createIncomePieChart()); } + /** + * Method for editing a chosen expense in the expense register. + + * @param chosenExpense The chosen expense + */ @FXML private void handleEditExpense(Expense chosenExpense) { //Instantiate FXML loader and loads the popup for adding expense @@ -446,9 +502,15 @@ public class IncomeExpenseController extends FinanceController { // Show the Dialog and wait for the user to close it dialog.showAndWait(); + //Update just the expense pie chart this.expensePieChart.setData(createExpensePieChart()); } - + + /** + * Method for deleting a chosen income from the income register. + + * @param chosenIncome The chosen income. + */ @FXML private void handleDeleteIncome(Income chosenIncome) { String title = "Confirm Delete" ; @@ -458,9 +520,15 @@ public class IncomeExpenseController extends FinanceController { if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { incomeRegister.removeItem(chosenIncome); } + //Update pie chart this.incomePieChart.setData(createIncomePieChart()); } + /** + * Method for deleting a chosen expense from the expenses register. + + * @param chosenExpense The chosen expense. + */ @FXML private void handleDeleteExpense(Expense chosenExpense) { String title = "Confirm Delete" ; @@ -470,6 +538,7 @@ public class IncomeExpenseController extends FinanceController { if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { expenseRegister.removeItem(chosenExpense); } + //Update pie chart this.expensePieChart.setData(createExpensePieChart()); } @@ -480,16 +549,43 @@ public class IncomeExpenseController extends FinanceController { @Override public void saveDataToFile() throws IOException { FileHandling.writeItemRegisterToFile(incomeRegister, - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Income"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Income"); FileHandling.writeItemRegisterToFile(expenseRegister, - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Expense"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Expense"); } - public void saveDisposableIncomeToFile() throws IOException { + /** + * Method for automatically updating the disposable income label. + */ + private void refreshDisposableIncome() { + maxAmount.setText(String.valueOf(incomeRegister.getTotalSum() - expenseRegister.getTotalSum())); + } + + /** + * Writes the disposable income amount to the budget file as the max amount field. + * @throws IOException if there is an input or exception. + */ + private void saveDisposableIncomeToFile() throws IOException { String disposableIncomeAsString = String.valueOf(incomeRegister.getTotalSum() - expenseRegister.getTotalSum()); FileHandlingBudget.writeMaxAmountToFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget", disposableIncomeAsString); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Budget", disposableIncomeAsString); + } + + + /** + * Method for validating if the max amount is above 1. + + * @param sumIncome Sum of incomes. + * @param sumExpense Sum of expenses. + * @return True, if the amount is above 1. Else, returns false + */ + private boolean isValidMaxAmount(double sumIncome, double sumExpense) { + return sumIncome - sumExpense > 1; } + /** * 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 @@ -497,6 +593,7 @@ public class IncomeExpenseController extends FinanceController { @FXML public void switchScene(javafx.event.ActionEvent event) { try { + //Determine which scene to switch to FXMLLoader loader = new FXMLLoader(); if (event.getSource() == returnToMainMenuBtn) { saveDataToFile(); @@ -506,9 +603,11 @@ public class IncomeExpenseController extends FinanceController { saveDisposableIncomeToFile(); } else if (event.getSource() == returnBtn) { loader.setLocation(getClass().getResource("/view/FirstMenu.fxml")); - FileHandlingBudgetArchive.deleteBudgetDirectory(FileHandlingSelectedBudget.readSelectedBudget()); - FileHandlingSelectedBudget.clearSelectedBudget(); + FileHandlingBudgetArchive.deleteBudgetDirectory("budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget")); + FileHandlingSelectedBudget.clearSelectedBudget("budgets/SelectedBudget"); } + //Load the scene Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java similarity index 80% rename from src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java rename to src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java index 52283c5c72911e211dbb4fb7929f2c20ebfc8191..46b048c9e0db845216bf77f5872fb8f967e28542 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java @@ -32,7 +32,14 @@ import no.ntnu.idatt1002.demo.data.Economics.FileHandling; import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; import no.ntnu.idatt1002.demo.data.Economics.Overview; -public class MainMenu { +/** + * Controller for the main menu of the application. Handles all inputs related + * to buttons and actively updates the progress overview. + * + * @author Harry Linrui Xu + * @since 29.03.2023 + */ +public class MainMenuController { @FXML private Label balanceLbl; @@ -104,17 +111,25 @@ public class MainMenu { Overview overview; + /** + * Initializes the registers and overviews in addition to all dynamic labels + * and progress bars. + */ @FXML public void initialize() { //Initialize all registers + overview try { incomeRegister = loadIncomeDataFromFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Income"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Income"); expenseRegister = loadExpenseDataFromFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Expense"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Expense"); generalBudget = loadBudgetDataFromFile( - "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget"); + "budgets/" + FileHandlingSelectedBudget + .readSelectedBudget("budgets/SelectedBudget") + "/Budget"); } catch (IOException ioe) { + ioe.printStackTrace(); Alert alert = new Alert(AlertType.ERROR); alert.setTitle("Could not load register data"); alert.setHeaderText("Could not load register data"); @@ -126,10 +141,24 @@ public class MainMenu { mainBar.setStyle("-fx-accent: rgb(48,215,106);"); + //Ensures all budget categories have been added + if (generalBudget.getBudgetItems().size() != 4) { + generalBudget.addUnusedCategories(); + } + //Set progress and balance refreshProgressBars(); + //Set values of labels refreshLabels(); - //Set progress when opening scene + //Make calendar uneditable + formatDatePicker(); + daysLeftLbl.setText("Days left: 31"); //TODO + } + + /** + * Method for setting the values of the dynamic labels. + */ + private void refreshLabels() { double maxAmount = generalBudget.getMaxAmount(); double expenseSum = expenseRegister.getTotalSum(); @@ -144,14 +173,6 @@ public class MainMenu { if (balance < 0) { balanceLbl.setTextFill(Color.RED); } - //Make calendar uneditable - formatDatePicker(); - daysLeftLbl.setText("Days left: 31"); - //date.restrict - } - - private void refreshLabels() { - } /** @@ -207,7 +228,8 @@ public class MainMenu { try { incomeRegister = FileHandling.readIncomeRegisterFromFile(fileDestination); } catch (IOException e) { - e.printStackTrace(); + showErrorDialogBox("Loading error", "Could not load income register", + "The income register could not be loaded"); } } return incomeRegister; @@ -227,7 +249,8 @@ public class MainMenu { try { expenseRegister = FileHandling.readExpenseRegisterFromFile(fileDestination); } catch (IOException e) { - e.printStackTrace(); + showErrorDialogBox("Loading error", "Expense register could not be loaded" + , "The expense register failed to load"); } } return expenseRegister; @@ -248,7 +271,8 @@ public class MainMenu { try { generalBudget = FileHandlingBudget.readGeneralBudgetFromFile(fileDestination); } catch (IOException e) { - e.printStackTrace(); + showErrorDialogBox("Loading error", "The general budget" + + "could not be loaded", ""); } } return generalBudget; @@ -265,8 +289,29 @@ public class MainMenu { date.getEditor().setStyle("-fx-opacity: 1"); } + /** + * Displays an error message dialog box with a customizable title, header and content. + + * @param title The dialog title. + * @param header The dialog header. + * @param content The dialog content. + */ + public void showErrorDialogBox(String title, String header, String content) { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle(title); + alert.setHeaderText(header); + alert.setContentText(content); + alert.showAndWait(); + } + /** + * Switches the scenes from the main menu to a target scene. + + * @param event A button press that takes on to another scene. + * @throws IOException if an input or output exception occurs + */ @FXML private void switchScene(ActionEvent event) throws IOException { + //Find new location FXMLLoader loader = new FXMLLoader(); if (event.getSource() == foodBtn) { loader.setLocation(getClass().getResource("/view/SuggestRecipes.fxml")); @@ -279,6 +324,7 @@ public class MainMenu { } else if (event.getSource() == returnBtn) { loader.setLocation(getClass().getResource("/view/FirstMenu.fxml")); } + //Load new location Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/SelectBudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/SelectBudgetController.java index 3feecc26f109cdfebd91109aa4242df3fd94a5d2..d744fe85668aad490f789aa662ba47df0478eeaa 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/SelectBudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/SelectBudgetController.java @@ -15,6 +15,12 @@ import no.ntnu.idatt1002.demo.data.Budget.BudgetRegister; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudgetArchive; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; +/** + * Class for selecting a budget from the archive. + + * @author Harry Linrui Xu + * @since 19.04.2023 + */ public class SelectBudgetController { @FXML @@ -41,10 +47,10 @@ public class SelectBudgetController { }); try { - if (FileHandlingBudgetArchive.isBudgetRegisterEmpty()) { + if (FileHandlingBudgetArchive.isBudgetRegisterEmpty("budgets/Archive")) { budgetRegister = new BudgetRegister(); } else { - budgetRegister = FileHandlingBudgetArchive.readBudgetArchive(""); + budgetRegister = FileHandlingBudgetArchive.readBudgetArchive("budgets/Archive"); } } catch (IOException ioe) { ioe.printStackTrace(); @@ -65,8 +71,7 @@ public class SelectBudgetController { @FXML public void selectBudget(ActionEvent event) throws IOException { String name = budgetListView.getSelectionModel().getSelectedItem(); - System.out.println(name); - FileHandlingSelectedBudget.updateSelectedBudget(name); + FileHandlingSelectedBudget.updateSelectedBudget(name, "budgets/SelectedBudget"); final Node source = (Node) event.getSource(); ((Stage) source.getScene().getWindow()).close(); @@ -74,7 +79,7 @@ public class SelectBudgetController { @FXML public void exitWindow(ActionEvent event) throws IOException { - FileHandlingSelectedBudget.clearSelectedBudget(); + FileHandlingSelectedBudget.clearSelectedBudget("budgets/SelectedBudget"); final Node source = (Node) event.getSource(); ((Stage) source.getScene().getWindow()).close(); } diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegister.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegister.java index 256aa5ed9d73fb68e323c3bf4f0b2aaa752377e6..7f9270a926c06dbcc9ce522c9e2cd4958797c830 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegister.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegister.java @@ -3,9 +3,20 @@ package no.ntnu.idatt1002.demo.data.Budget; import java.util.ArrayList; import java.util.List; +/** + * Class for containing and organizing budget names. + * A budget name is the name that is given to a budget when it is created. + + * @author Harry Linrui Xu + * @since 19.04.2023 + */ public class BudgetRegister { private final List<String> budgetNames; + /** + * Constructor for the register. Instantiates the arraylist + * that contains all budget names. + */ public BudgetRegister() { budgetNames = new ArrayList<>(); } @@ -14,17 +25,30 @@ public class BudgetRegister { return this.budgetNames; } - public void addBudgetName(String name) { + /** + * Method for adding a budget name to the register. + + * @param name The name of the budget. + * @throws IllegalArgumentException If name is null, blank or already + * exists within the register. + */ + public void addBudgetName(String name) throws IllegalArgumentException { if (name == null) throw new IllegalArgumentException("Name cannot be null"); if (name.isBlank()) throw new IllegalArgumentException("Name cannot be blank"); - //if(budgetNames.contains(name)) throw new IllegalArgumentException("Duplicate entry"); + if(budgetNames.contains(name)) throw new IllegalArgumentException("Duplicate entry"); budgetNames.add(name); } - public void removeBudgetName(String name) { + /** + * Method for removing a budget name from the register. + + * @param name The name of the budget. + * @throws IllegalArgumentException If name is null or blank. + */ + public void removeBudgetName(String name) throws IllegalArgumentException { if (name == null) throw new IllegalArgumentException("Name cannot be null"); if (name.isBlank()) throw new IllegalArgumentException("Name cannot be blank"); - budgetNames.add(name); + budgetNames.remove(name); } @Override 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 938ae9c7b65d105d930f5f8683cd7b9e23da8e47..3c4e6c4951d039ce1a33a00f1b65eb66a134270e 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 @@ -12,16 +12,12 @@ import java.io.*; */ public class FileHandlingBudget { - private static final String filePath = "src/main/resources/budgets/Budget/"; private static final String fileType = ".budget"; - - private static final String path = "src/main/resources/"; - private static final String type = ".register"; + private static final String filePath = "src/main/resources/"; private static final String maxAmount = "maxAmount="; private static final String budgetAmount = "budgetAmount="; private static final String budgetCategory = "budgetCategory="; private static final String budgetDescription = "budgetDescription="; - public static String id = ""; /** * Method for writing (adding) a budget to a file. @@ -31,8 +27,7 @@ public class FileHandlingBudget { * @throws IOException if an input or output exception occurred. */ public static void writeGeneralBudgetToFile(String fileTitle, GeneralBudget generalBudget) throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(path + fileTitle + fileType))) { - //try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { bw.write(generalBudget.toString()); } catch (IOException ex) { ex.printStackTrace(); @@ -48,11 +43,7 @@ public class FileHandlingBudget { * @throws IOException if an input or output exception occurred. */ public static boolean isEmpty(String fileTitle) throws IOException { - /*try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { - return br.readLine() == null; - }*/ - try (BufferedReader br = new BufferedReader(new FileReader(path + fileTitle + fileType))) { - System.out.println("Trying budget isEmpty in: " + path + FileHandlingSelectedBudget.readSelectedBudget() + "/" + fileTitle + fileType); + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { return br.readLine() == null; } } @@ -60,34 +51,39 @@ public class FileHandlingBudget { /** * Method for checking if a .budget file is new (no categories) - * or old (has budget categories) + * or old (has budget categories). + * @param fileTitle The name of the file * @return True, if the budget is new. Else, returns false - * @throws IOException + * @throws IOException if an input or output exception occurred. */ public static boolean isNewBudget(String fileTitle) throws IOException { try (BufferedReader br = new BufferedReader( - new FileReader(path + fileTitle + fileType))) { - //new FileReader(filePath + fileTitle + fileType))) { + new FileReader(filePath + fileTitle + fileType))) { for (int i = 0; i < 2; ++i) { br.readLine(); } if (br.readLine() == null) { - System.out.println("Is new budget - no max amount"); return true; } } - System.out.println("Is 'old' budget - has max amount"); return false; } - + + /** + * Method for writing the disposable income, the "max amount" of the budget + * to file. + + * @param fileDestination The file destination that max amount will be written into. + * @param maxAmount The disposable income of the budget. + * @throws IOException if an input or output exception occurred. + */ public static void writeMaxAmountToFile(String fileDestination, String maxAmount) throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(path + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileDestination + fileType))) { bw.write("maxAmount=" + maxAmount); - System.out.println("Max amount is..."); } catch (IOException ex) { throw new IOException("Error writing to file: " + fileDestination); } @@ -107,7 +103,7 @@ public class FileHandlingBudget { ExpenseCategory expenseCategory = null; String budgetDescription = null; - try (BufferedReader br = new BufferedReader(new FileReader(path + fileTitle + fileType))) { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { String line; String nextLine = br.readLine(); while ((line = nextLine) != null) { @@ -120,8 +116,11 @@ public class FileHandlingBudget { line = line.replace(FileHandlingBudget.budgetCategory, ""); expenseCategory = switch (line) { case "FOOD" -> ExpenseCategory.FOOD; + case "RENT" -> ExpenseCategory.RENT; case "CLOTHES" -> ExpenseCategory.CLOTHES; case "BOOKS" -> ExpenseCategory.BOOKS; + case "HEALTH" -> ExpenseCategory.HEALTH; + case "ACTIVITIES" -> ExpenseCategory.ACTIVITIES; default -> ExpenseCategory.OTHER; }; } else if (line.startsWith(FileHandlingBudget.budgetDescription)) { diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchive.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchive.java index 5d0541c29243483c292592c52595a8fbf282eb55..5b559c569dba441578daecbf16f6562fc3f4bcd8 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchive.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchive.java @@ -7,19 +7,21 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -//Disable next i dualList før income har blitt lagt til. Kanksje filter som prevneter negativ max amount (if balance < 1) -//MÅTE Å FIKSE TESTER PÅ: LA SELECTEDBUDGET.CURRENT VÆRE EN PARAMETER I METODENE //Disable next i newBudgetbert til maxamount har blitt burkt opp -//Sette label til total balance i dualList +//Set titler på hvert vindu - kan gjøres i switch scene +//Close program properly +//close button i first menu +//remove printstackstraces //HVIS CONTINUE I BUDGET PRESSES, SHOWCONFIRMATION //VIKTIG_ BALANCE LABEL ER RØD PÅ GRØNN BAKGRUNN!!! //Binde label to total balance i budget window (newBUdgetBert) +//En delete funksjon i select old budget +//Endre pakkenavn +//Public vs private metoder må sjekkes //Popup for edit og delete button -//La next button save dataene i to nye filer for persisterign i tilfelle "back" trykkes i newBudgetbudget //confirmation for når returnBtn som returner til start. "Are you sure you want to go back. Changes will not be saved" // FIKSE TRY CATCHES I ALLE METODENE!!!!!!!!!! -//tester for nye klasserr -//resize fordi tabellkolonner er for små, fontsize, font +//tester for nye filklasser //set all windows unresizable //Bytte oversikt på dualList til Monthly .... @@ -29,32 +31,63 @@ import java.io.IOException; //(System.getProperty("user.dir") + "/" + path) = //(path) = //(src/main/resources) + +/** + * Class that handles the reading and writing to the budget archive file, + * which contains all existing budget projects. New budgets are added to the archive + * through this class. + + * @author Harry Linrui Xu + * @since 19.04.2023 + */ public class FileHandlingBudgetArchive { - private static final String filePath = "src/main/resources/budgets/"; + private static final String filePath = "src/main/resources/"; private static final String fileType = ".archive"; - public static void writeBudgetRegisterToArchive(BudgetRegister budgetNames) throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + "Archive" + fileType))) { + /** + * Method for writing (adding) a budget register to the archive. + + * @param budgetNames The budget register. + * @throws IOException if an input or output exception occurred. + */ + public static void writeBudgetRegisterToArchive(BudgetRegister budgetNames, + String fileTitle) throws IOException { + + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { bw.write(budgetNames.toString()); } catch (IOException ioe) { - ioe.printStackTrace(); throw new IOException("Could not write to file: Archive", ioe); } } - public static boolean isBudgetRegisterEmpty() throws IOException { + /** + * Checks if the budget register in the archive contains any budget names. + * In other words, if it is empty. + + * @return True, if only "null" is read. Else, returns false. + * @throws IOException if an input or output exception occurred. + */ + public static boolean isBudgetRegisterEmpty(String fileTitle) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(filePath - + "Archive" + fileType))) { + + fileTitle + fileType))) { return br.readLine() == null; } } - public static BudgetRegister readBudgetArchive(String fileTitle) throws IOException { + + /** + * Method for reading the budget register from the archive. + * @param fileTitle The name of the file that contains the register. + + * @return The budget register that is read from file. + * @throws IOException if an input or output exception occurred. + */ + public static BudgetRegister readBudgetArchive(String fileTitle) throws IOException { //TODO BudgetRegister budgetRegister = null; String budgetName; String line; try (BufferedReader br = new BufferedReader( - new FileReader(filePath + "Archive" + fileType))) { + new FileReader(filePath + fileTitle + fileType))) { String nextLine = br.readLine(); while ((line = nextLine) != null) { @@ -71,19 +104,24 @@ public class FileHandlingBudgetArchive { return budgetRegister; } - public static void writeSavingsToFile() { - - } + /** + * Method for deleting a budget directory which holds all budget, income and expense + * data for a particular budget. This class holds this responsibility, as any budgets + * that should be removed should have their directory deleted. - public static boolean deleteBudgetDirectory(String budgetID) { - File targetDirectory = new File(filePath + budgetID); + * @param budgetId The name of the budget directory that holds all the data + * for a given budget. + * @return True, if the directory is successfully deleted. Else, returns false. + */ + public static boolean deleteBudgetDirectory(String budgetId) { + File targetDirectory = new File(filePath + budgetId); System.out.println("Deleting directory:" + targetDirectory.getPath()); String[]entries = targetDirectory.list(); assert entries != null; for(String file : entries){ File currentFile = new File(targetDirectory.getPath(),file); - System.out.println("Deleting file:" + currentFile.delete()); + currentFile.delete(); } return targetDirectory.delete(); diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudget.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudget.java index 067abebbd607d34f83fcf324b0daaf1118a9701e..20b1ea92724b1ddcfd0760645631f2bf3d114e05 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudget.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudget.java @@ -7,18 +7,31 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -public class FileHandlingSelectedBudget { - - private static final String filePath = "src/main/resources/budgets/"; +/** + * Class that holds the responsibility of any action relating to the SelectedBudget.current file + * which holds the budget name of the budget that currently is viewed. + * @author Harry Linrui Xu + * @since 19.04.2023 + */ +public class FileHandlingSelectedBudget { + private static final String filePath = "src/main/resources/"; private static final String selectedBudgetFileType = ".current"; private static final String registerFileType = ".register"; private static final String budgetFileType = ".budget"; private static final String slash = "/"; - public static String readSelectedBudget() throws IOException { - try (BufferedReader br = new BufferedReader(new FileReader(filePath + "SelectedBudget" + + /** + * Reads the name of the currently selected budget. + + * @return A string of the budget name. + * @throws IOException if an input or output exception occurred. + */ + public static String readSelectedBudget(String fileTitle) throws IOException {//TODO + System.out.println("Reading current file: " + filePath + fileTitle + + selectedBudgetFileType); + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + selectedBudgetFileType))) { return br.readLine(); } catch (IOException ioException) { @@ -26,51 +39,103 @@ public class FileHandlingSelectedBudget { } } - public static void updateSelectedBudget(String budgetName) throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + "SelectedBudget" + + /** + * Writes the currently used budget name to file, essentially updating the + * file. + * @param budgetName The name of the budget. + * @throws IOException if an input or output exception occurred. + */ + public static void updateSelectedBudget(String budgetName, String fileTitle) throws IOException { + System.out.print("Updating current file to: " + filePath + fileTitle + + selectedBudgetFileType + "->" + budgetName); + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + selectedBudgetFileType))) { bw.write(budgetName); - System.out.println("Current file is: " + budgetName); + System.out.println("-----Budget name: " + budgetName); } catch (IOException ex) { throw new IOException("Error writing to file: " + "SelectedBudget.current"); } } - public static void clearSelectedBudget() throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + "SelectedBudget" + + /** + * Clears the entire file that holds the current budget. In case a budget is deleted, + * this method prevents the file of containing a budget name that no longer exists. + + * @throws IOException if an input or output exception occurred. + */ + public static void clearSelectedBudget(String fileTitle) throws IOException { + System.out.println("Clearing current file from: " + filePath + fileTitle + + selectedBudgetFileType); + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + selectedBudgetFileType))) { bw.write(""); - System.out.println("Current file is: "); } catch (IOException ex) { throw new IOException("Error writing to file: " + "SelectedBudget.current"); } } + /** + * Checks if the file that holds the selected budget contains any budget. In other words, + * the method checks if this file is empty. + + * @param fileTitle The file name of the file. + * @return True, if only "null" is read from the file. Else, returns false. + * @throws IOException if an input or output exception occurred. + */ public static boolean isSelectedBudgetEmpty(String fileTitle) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(filePath - + "SelectedBudget" + selectedBudgetFileType))) { + + fileTitle + selectedBudgetFileType))) { return br.readLine() == null; } } - + + /** + * Method for creating a new directory for a newly created budget. + + * @param budgetId The name of the directory that stores all the data for a + * given budget. + * @return True, if a directory is successfully created. Else, returns false. + */ public static boolean createBudgetDirectory(String budgetId) { - System.out.println("Directory: " + filePath + budgetId); File f = new File(filePath + budgetId); return f.mkdir(); } - + + /** + * Method for creating a file holding all income data. + + * @param budgetId The name of the directory that stores all the data for a + * given budget. + * @param incomeFileTitle The name of the income file. + * @throws IOException if an input or output exception occurred. + */ public static void createNewIncomeFile(String budgetId, String incomeFileTitle) throws IOException { - System.out.println("Income filepath: " + filePath + budgetId + "/" + incomeFileTitle + registerFileType); File incomeFile = new File(filePath + budgetId + "/" + incomeFileTitle + registerFileType); incomeFile.createNewFile(); } + /** + * Method for creating a file holding all expense data. + + * @param budgetId The name of the directory that stores all the data for a + * given budget. + * @param expenseFileTitle The name of the expense file. + * @throws IOException if an input or output exception occurred. + */ public static void createNewExpenseFile(String budgetId, String expenseFileTitle) throws IOException { System.out.println("Expense filePath: " + filePath + budgetId + "/" + expenseFileTitle + registerFileType); File expenseFile = new File(filePath + budgetId + "/" + expenseFileTitle + registerFileType); expenseFile.createNewFile(); } + /** + * Method for creating a file holding all income data. + + * @param budgetId The name of the directory that stores all the data for a + * given budget. + * @param budgetFileTitle The name of the budget file. + * @throws IOException if an input or output exception occurred. + */ public static void createNewBudgetFile(String budgetId, String budgetFileTitle) throws IOException { System.out.println("Budget filePath: " + filePath + budgetId + "/" + budgetFileTitle + budgetFileType); File budgetFile = new File(filePath + budgetId + "/" + budgetFileTitle + budgetFileType); diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/ExpenseCategory.java b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/ExpenseCategory.java index f5af9a40e675e00a08149df7301e18b85d57b752..4a94a25690394e97fc1eabcf4ba2654194fa453c 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Economics/ExpenseCategory.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Economics/ExpenseCategory.java @@ -3,8 +3,11 @@ package no.ntnu.idatt1002.demo.data.Economics; public enum ExpenseCategory { FOOD("food"), + RENT("rent"), CLOTHES("clothes"), BOOKS("books"), + HEALTH("health"), + ACTIVITIES("activities"), OTHER("other"); 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 004b34b4d9a1daedb7ce8ee40487cfbac526adc1..6051903b7869156dc163890f8bcd6bdffaa5788f 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 @@ -14,9 +14,7 @@ import java.time.LocalDate; * @author andreas */ public class FileHandling{ - private static final String filePath = "src/main/resources/budgets/Economics/"; - - private static final String path = "src/main/resources/"; + private static final String filePath = "src/main/resources/"; private static final String fileType = ".register"; private static final String date = "date="; private static final String description = "description="; @@ -32,8 +30,7 @@ public class FileHandling{ * @throws IOException if an input or output exception occurred. */ public static <T extends Item>void writeItemRegisterToFile(final ItemRegister<T> itemRegister, String fileTitle) throws IOException { - //try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(path + fileTitle + fileType))) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { if (itemRegister.isEmpty()){ bw.write(""); } else{ @@ -52,14 +49,7 @@ public class FileHandling{ * @throws IOException if an input or output exception occurred. */ public static 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; - } - }*/ - try (BufferedReader br = new BufferedReader(new FileReader(path + fileTitle + fileType))) { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { return br.readLine() == null; } } @@ -78,8 +68,7 @@ public class FileHandling{ double amount = 0; boolean reoccuring = false; IncomeCategory incomeCategory = null; - try (BufferedReader br = new BufferedReader(new FileReader(path + fileTitle + fileType))) { - //try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { String line; String nextLine = br.readLine(); while ((line = nextLine) != null) { @@ -126,8 +115,7 @@ public class FileHandling{ double amount = 0; boolean reoccuring = false; ExpenseCategory expenseCategory = null; - try (BufferedReader br = new BufferedReader(new FileReader(path + fileTitle + fileType))) { - //try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { String line; String nextLine = br.readLine(); while ((line = nextLine) != null) { diff --git a/src/main/resources/Images/add_expense.png b/src/main/resources/Images/add_expense.png deleted file mode 100644 index 0c0773f42c667ed370652c4b5e75cb993a0bf2cf..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/add_expense.png and /dev/null differ diff --git a/src/main/resources/Images/arrow.png b/src/main/resources/Images/arrow.png deleted file mode 100644 index 9d65c03b2a4d3710c674655f1a3201935735c9f5..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/arrow.png and /dev/null differ diff --git a/src/main/resources/Images/budgetbuddycover.jpeg b/src/main/resources/Images/budgetbuddycover.jpeg deleted file mode 100644 index 75e7f244e9d27b0416904cef73a52d3d88111f20..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/budgetbuddycover.jpeg and /dev/null differ diff --git a/src/main/resources/Images/overview_stonks.png b/src/main/resources/Images/overview_stonks.png deleted file mode 100644 index b9cbdc6e52faf7102423b713a3e72152375f5f59..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/overview_stonks.png and /dev/null differ diff --git a/src/main/resources/Images/pizzaslice.png b/src/main/resources/Images/pizzaslice.png deleted file mode 100644 index ad2aebbc8a93ef297a2a82229d385f655d9e88bc..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/pizzaslice.png and /dev/null differ diff --git a/src/main/resources/Images/underProgress.png b/src/main/resources/Images/underProgress.png deleted file mode 100644 index 74a260f5f282404981802a61eb99c830318a8880..0000000000000000000000000000000000000000 Binary files a/src/main/resources/Images/underProgress.png and /dev/null differ diff --git a/src/main/resources/budgets/SelectedBudget.current b/src/main/resources/budgets/SelectedBudget.current index 06b279097892ff167d38ffe92f919d36d811db9d..5d60f791060cd30d347b32fc1ff332ce182e0c55 100644 --- a/src/main/resources/budgets/SelectedBudget.current +++ b/src/main/resources/budgets/SelectedBudget.current @@ -1 +1 @@ -APRILreasonable \ No newline at end of file +APRILreasonable diff --git a/src/main/resources/testFiles/budget/emptyFile b/src/main/resources/testFiles/budget/emptyFile new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/resources/view/BudgetNewest.fxml b/src/main/resources/view/BudgetNewest.fxml index a5f38f9e4c2e41c71da6bbeeee8ff088f5665bb8..3319d2c4146239cfde9f7ee9d10163d1f7c0fdcc 100644 --- a/src/main/resources/view/BudgetNewest.fxml +++ b/src/main/resources/view/BudgetNewest.fxml @@ -59,7 +59,7 @@ <left> <HBox prefHeight="64.0" prefWidth="326.0" spacing="10.0" BorderPane.alignment="CENTER"> <children> - <Button id="small-button" fx:id="addBtn" mnemonicParsing="false" onAction="#handleAddBtn" prefHeight="38.0" prefWidth="75.0" styleClass="button-style" stylesheets="@../style.css" text="Add"> + <Button id="small-button" fx:id="addBtn" disable="true" mnemonicParsing="false" onAction="#handleAddBtn" opacity="0.0" prefHeight="38.0" prefWidth="75.0" styleClass="button-style" stylesheets="@../style.css" text="Add"> <font> <Font name="Lucida Console" size="14.0" /> </font> @@ -71,7 +71,7 @@ </ImageView> </graphic> </Button> - <Button id="small-button" fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="39.0" prefWidth="91.0" styleClass="button-style" stylesheets="@../style.css" text="Edit"> + <Button id="small-button" fx:id="editBtn" disable="true" mnemonicParsing="false" onAction="#handleEditBtn" opacity="0.0" prefHeight="39.0" prefWidth="91.0" styleClass="button-style" stylesheets="@../style.css" text="Edit"> <font> <Font name="Lucida Console" size="14.0" /> </font> @@ -83,7 +83,7 @@ </ImageView> </graphic> </Button> - <Button id="small-button" fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="39.0" prefWidth="119.0" styleClass="button-style" stylesheets="@../style.css" text="Delete"> + <Button id="small-button" fx:id="deleteBtn" disable="true" mnemonicParsing="false" onAction="#handleDeleteBtn" opacity="0.0" prefHeight="39.0" prefWidth="119.0" styleClass="button-style" stylesheets="@../style.css" text="Delete"> <font> <Font name="Lucida Console" size="14.0" /> </font> @@ -164,8 +164,8 @@ </TableView> <HBox alignment="TOP_RIGHT"> <children> - <Button fx:id="backBtn" mnemonicParsing="false" styleClass="button-style" stylesheets="@../style.css" text="back" /> - <Button fx:id="continueBtn" mnemonicParsing="false" styleClass="button-style" stylesheets="@../style.css" text="continue" /> + <Button fx:id="backBtn" disable="true" mnemonicParsing="false" opacity="0.0" styleClass="button-style" stylesheets="@../style.css" text="back" /> + <Button fx:id="continueBtn" disable="true" mnemonicParsing="false" opacity="0.0" styleClass="button-style" stylesheets="@../style.css" text="continue" /> </children> </HBox> </children> diff --git a/src/main/resources/view/FirstMenu.fxml b/src/main/resources/view/FirstMenu.fxml index a12ffabc4ed0395e88bed132e77ca6d6e749a11f..d3f59261cc689689b68f1cc800908a9528b12607 100644 --- a/src/main/resources/view/FirstMenu.fxml +++ b/src/main/resources/view/FirstMenu.fxml @@ -5,7 +5,7 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> -<AnchorPane maxHeight="600" maxWidth="607.0" minHeight="406.0" minWidth="600" prefHeight="406.0" prefWidth="607.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SceneController"> +<AnchorPane maxHeight="600" maxWidth="607.0" minHeight="406.0" minWidth="600" prefHeight="406.0" prefWidth="607.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.FirstMenuController"> <ImageView fitHeight="412.0" fitWidth="614.0" layoutX="-7.0" layoutY="-6.0" pickOnBounds="true" smooth="false"> <Image url="@../Images/backgroundMini.jpg" /> </ImageView> @@ -19,7 +19,7 @@ <Font name="Verdana" size="18.0" /> </font> </Label> - <Button layoutX="69.0" layoutY="212.0" mnemonicParsing="false" onAction="#switchIncome" styleClass="welcome-button" stylesheets="@../style.css" text="New Budget"> + <Button layoutX="69.0" layoutY="212.0" mnemonicParsing="false" onAction="#createBudget" styleClass="welcome-button" stylesheets="@../style.css" text="New Budget"> <font> <Font size="24.0" /> </font> diff --git a/src/main/resources/view/IncomeAndExpenses.fxml b/src/main/resources/view/IncomeAndExpenses.fxml index c33f765e71ec1bb59b3b3baeaaa7af210819cb1a..14d870328f4060ade3f85131fcb832e2b294695c 100644 --- a/src/main/resources/view/IncomeAndExpenses.fxml +++ b/src/main/resources/view/IncomeAndExpenses.fxml @@ -42,6 +42,7 @@ </font> </Button> <Button fx:id="returnBtn" disable="true" layoutX="136.0" layoutY="117.0" mnemonicParsing="false" opacity="0.0" text="Button" /> + <Button fx:id="continueBtn" disable="true" layoutX="136.0" layoutY="105.0" mnemonicParsing="false" opacity="0.0" text="Button" /> </children> </Pane> </left> @@ -191,6 +192,7 @@ </ContextMenu> </contextMenu> </TableView> + <Label fx:id="maxAmount" disable="true" opacity="0.0" text="Label" /> </children> </VBox> <Pane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2"> diff --git a/src/main/resources/view/MainMenuNew.fxml b/src/main/resources/view/MainMenuNew.fxml index 00e1dbb01242affb6c59f4e695aa490fd75d4fa6..aef63ce60ef994fe60ffd51a60a2ae254d29920d 100644 --- a/src/main/resources/view/MainMenuNew.fxml +++ b/src/main/resources/view/MainMenuNew.fxml @@ -7,7 +7,7 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> -<AnchorPane fx:id="root" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.MainMenu"> +<AnchorPane fx:id="root" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.MainMenuController"> <children> <ImageView fitHeight="719.0" fitWidth="1130.0" layoutY="-3.0" pickOnBounds="true" preserveRatio="true"> <image> @@ -117,7 +117,7 @@ <graphic> <ImageView fitHeight="75.0" fitWidth="75.0" pickOnBounds="true" preserveRatio="true"> <image> - <Image url="@../Images/income.png" /> + <Image url="@../Images/incomeExpense.png" /> </image> </ImageView> </graphic> diff --git a/src/main/resources/view/dualList.fxml b/src/main/resources/view/dualList.fxml index 154eb7849ccebbbfb843e11ae86d99e0fe49bf42..b5230dbb20d87e6cf6f4d0fb79ef4834cf4f5453 100644 --- a/src/main/resources/view/dualList.fxml +++ b/src/main/resources/view/dualList.fxml @@ -190,7 +190,7 @@ </HBox.margin> </Text> <Region prefHeight="18.0" prefWidth="100.0" /> - <Label fx:id="maxAmount" text="Label" /> + <Label fx:id="maxAmount" /> </children> <StackPane.margin> <Insets bottom="4.0" /> diff --git a/src/main/resources/view/newBudgetBudgert.fxml b/src/main/resources/view/newBudgetBudgert.fxml index ffafab793f40e1ccf53f6a5322ed4aac0aaf0ed0..227a1d3e1ee6a67e9818aee013a663e80e957ab8 100644 --- a/src/main/resources/view/newBudgetBudgert.fxml +++ b/src/main/resources/view/newBudgetBudgert.fxml @@ -181,7 +181,7 @@ <Pane GridPane.columnIndex="2"> <children> <StackPane /> - <Label fx:id="daysLeftLbl" layoutX="33.0" layoutY="62.0" styleClass="font" stylesheets="@../style.css" text="Days left: 31"> + <Label fx:id="daysLeftLbl" disable="true" layoutX="33.0" layoutY="62.0" opacity="0.0" styleClass="font" stylesheets="@../style.css" text="Days left: 31"> <font> <Font name="Lucida Console" size="14.0" /> </font> @@ -189,7 +189,7 @@ <DatePicker fx:id="date" layoutX="3.0" layoutY="32.0" prefWidth="175.0" /> </children> </Pane> - <Button fx:id="returnToMainMenuBtn" disable="true" mnemonicParsing="false" onAction="#switchScene" opacity="0.0" text="Button" /> + <Button fx:id="returnToMainMenuBtn" disable="true" mnemonicParsing="false" onAction="#switchScene" opacity="0.0" text="returnToMainMenuBtn" /> <Button fx:id="backBtn" mnemonicParsing="false" onAction="#switchScene" prefWidth="100.0" styleClass="button-style" stylesheets="@../style.css" text="Go back"> <font> <Font size="14.0" /> diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegisterTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegisterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..22093b58e2a8a2936afd6d4422f499045283c752 --- /dev/null +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegisterTest.java @@ -0,0 +1,95 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class BudgetRegisterTest { + + @Nested + @DisplayName("Test addBudgetName") + class AddBudgetName { + BudgetRegister budgetRegister; + + String name, nameCopy, blankName; + + @BeforeEach + void setUp() { + budgetRegister = new BudgetRegister(); + name = "Name"; + nameCopy = "Name"; + blankName = ""; + } + + @Test + @DisplayName("Test adding valid name to budget register") + void testAddingValidName() { + budgetRegister.addBudgetName(name); + assertEquals(1, budgetRegister.getBudgetNames().size()); + } + + @Test + @DisplayName("Test adding blank name throws Illegal Argument exception") + void testAddingBlankString() { + assertThrows(IllegalArgumentException.class, () -> + budgetRegister.addBudgetName(blankName)); + } + + @Test + @DisplayName("Test adding null throws Illegal Argument exception") + void testAddingNull() { + assertThrows(IllegalArgumentException.class, () -> + budgetRegister.addBudgetName(null)); + } + + @Test + @DisplayName("Test adding duplicate name throws Illegal Argument exception") + void testAddingDuplicate() { + budgetRegister.addBudgetName(name); + assertThrows(IllegalArgumentException.class, () -> + budgetRegister.addBudgetName(nameCopy)); + } + } + + @Nested + @DisplayName("Test removeBudgetName") + class RemoveBudgetName { + + BudgetRegister budgetRegister; + + String name, blankName; + + @BeforeEach + void setUp() { + budgetRegister = new BudgetRegister(); + name = "Name"; + blankName = ""; + budgetRegister.addBudgetName(name); + } + + @Test + @DisplayName("Test removing valid name from budget register") + void testRemovingValidName() { + budgetRegister.removeBudgetName(name); + assertEquals(0, budgetRegister.getBudgetNames().size()); + } + + @Test + @DisplayName("Test removing blank name throws Illegal Argument exception") + void testRemovingBlankString() { + assertThrows(IllegalArgumentException.class, () -> + budgetRegister.removeBudgetName(blankName)); + } + + @Test + @DisplayName("Test removing null throws Illegal Argument exception") + void testRemovingNull() { + assertThrows(IllegalArgumentException.class, () -> + budgetRegister.removeBudgetName(null)); + } + } + +} diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchiveTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchiveTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b0a828f81529c8ca799200901199e88bd7e5b4b0 --- /dev/null +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchiveTest.java @@ -0,0 +1,26 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class FileHandlingBudgetArchiveTest { + + BudgetRegister budgetRegister; + + @Nested + @DisplayName("Test isBudgetRegisterEmpty") + class IsBudgetRegisterEmpty { + + String filePath; + + @BeforeEach + void setUp() { + budgetRegister = new BudgetRegister(); + filePath = null; + } + } +} diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudgetTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudgetTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8264f3421b44f7463196fe2558340e6b78fadbe9 --- /dev/null +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudgetTest.java @@ -0,0 +1,14 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class FileHandlingSelectedBudgetTest { + + + +} diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java index 22467b8e22578de2fdc8a79f42ca1fb0dc2b795e..d433d051008277d624f148f070a4a618fd5d0f8b 100644 --- a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudgetTest.java @@ -117,7 +117,7 @@ class GeneralBudgetTest { assertEquals(1, budget.getBudgetItems().size()); budget.addUnusedCategories(); - assertEquals(4, budget.getBudgetItems().size()); + assertEquals(ExpenseCategory.values().length, budget.getBudgetItems().size()); } }