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 3d33f030565c21a0aaf643e6aa699b38a467c732..aa40ea6f80102216bdb14a7f768b0c7cdbecd760 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/BudgetController.java @@ -1,29 +1,30 @@ package no.ntnu.idatt1002.demo.controller; import java.time.LocalDate; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.geometry.Rectangle2D; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.chart.PieChart; import javafx.scene.chart.PieChart.Data; import javafx.scene.control.*; -import javafx.scene.control.Alert.AlertType; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.text.Text; import javafx.stage.Modality; +import javafx.stage.Screen; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Budget.BudgetItem; +import no.ntnu.idatt1002.demo.data.Budget.BudgetRegister; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudgetArchive; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget; -import no.ntnu.idatt1002.demo.data.Economics.Expense; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; import java.io.IOException; @@ -36,8 +37,7 @@ import java.util.Optional; * @author Anders Emil Bergan * @since 24.3.2023 */ -public class BudgetController implements FinanceController { - +public class BudgetController extends FinanceController { private GeneralBudget general; @FXML @@ -50,7 +50,14 @@ public class BudgetController implements FinanceController { private Button deleteBtn; @FXML - private Button returnBtn; + private Button returnToMainMenuBtn; + + @FXML + private Button backBtn; + + @FXML + private Button continueBtn; + @FXML private TableColumn<BudgetItem, Double> amountCol; @@ -69,15 +76,17 @@ public class BudgetController implements FinanceController { @FXML private DatePicker date; - @FXML - private TableColumn<BudgetItem, Double> percentageColumn; - @FXML private ObservableList<BudgetItem> budgetList; @FXML private PieChart budgetPieChart; + @FXML + private Label daysLeftLbl; + + BudgetRegister budgetRegister = new BudgetRegister(); + /** * Initializes the budget register, the observable budget list and the tableview, along with the values of the dropbox used for filtering the tableview. @@ -85,7 +94,6 @@ public class BudgetController implements FinanceController { @FXML public void initialize() { - //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 @@ -93,63 +101,73 @@ public class BudgetController implements FinanceController { amountCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, Double>("budgetAmount")); descriptionCol.setCellValueFactory(new PropertyValueFactory<BudgetItem, String>("budgetDescription")); - try { //Initialize registers, tableview and pie charts - //if (FileHandlingBudget.hasBudgetSet - from line 4/5, so after the general amount and such) { - //add, edit and delete buttons are removed. - general = loadBudgetDataFromFile("Budget"); + try { + System.out.println("Just in budget try"); + general = loadBudgetDataFromFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget"); budgetList = FXCollections.observableArrayList(general.getBudgetItems()); budgetTableView.setItems(budgetList); - refreshPieChart(); + System.out.println("After loading general"); + + if (FileHandlingBudgetArchive.isBudgetRegisterEmpty()) { + budgetRegister = new BudgetRegister(); + } else { + budgetRegister = FileHandlingBudgetArchive.readBudgetArchive(""); + } + if (FileHandlingBudget.isNewBudget( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget")) { + returnToMainMenuBtn.setOpacity(0); + returnToMainMenuBtn.setDisable(true); + daysLeftLbl.setOpacity(0); + } else { + 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) { - showErrorDialogBox("File reading error", "Error in reading from file", "An error occurred" - + "when reading the registers from file"); + ioe.printStackTrace(); + showErrorDialogBox(ioe.getMessage(), ioe.getMessage(), ioe.getMessage()); } - - setButtons(); formatDatePicker(); - - //Initialize sum field under the tableview - //sum.setText(String.valueOf(general.totalSum())); } - private void setButtons() { - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); - try { - if (fileHandlingBudget.isEmpty("Budget")) { - returnBtn.setOpacity(0); - } else { - addBtn.setDisable(true); - editBtn.setDisable(true); - deleteBtn.setDisable(true); - } + public ObservableList<PieChart.Data> createPieChart() throws IllegalArgumentException { // + ObservableList<PieChart.Data> budgetData = FXCollections.observableArrayList(); + List<ExpenseCategory> chosenCategories = general.getChosenBudgetCategories(); - } catch(IOException ioe) { - Alert alert = new Alert(AlertType.CONFIRMATION); - alert.setTitle("Confirm Delete"); - alert.setHeaderText("Delete Confirmation"); - alert.setContentText("Are you sure you would like to delete the selected entry?"); - - alert.show(); + //Only adds the budget data for chosen categories to the pie chart + for (ExpenseCategory category : chosenCategories) { + budgetData.add(new Data(category.toString().substring(0, 1).toUpperCase(). + concat(category.toString().substring(1)), + general.getBudgetItem(category).getBudgetAmount())); } + return budgetData; } - private ObservableList<PieChart.Data> createBudgetPieChart() { // + /*private ObservableList<PieChart.Data> createBudgetPieChart() { 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 void refreshPieChart() { - this.budgetPieChart.setData(createBudgetPieChart()); + @Override + public void refreshPieChart() { + this.budgetPieChart.setData(createPieChart()); } /** * Method for disabling the date picker, yet having its opacity at max. */ - private void formatDatePicker() { + @Override + public void formatDatePicker() { date.setValue(LocalDate.now()); date.setDisable(true); date.setStyle("-fx-opacity: 1"); @@ -212,10 +230,7 @@ public class BudgetController implements FinanceController { try { general.addToBudgetBudgetItem(item); } catch(IllegalArgumentException e) { - String title = "Budget amount exceeded/Category already exists"; - String header = "Your budget exceeds the max limit OR a budget item of the same category already exists in the table"; - String content = "The total budget sum must be below " + general.getMaxAmount() + " OR Each category can only have one entry in the budget table"; - showErrorDialogBox(title, header, content); + showErrorDialogBox(e.getMessage(), e.getMessage(), e.getMessage()); } } //Updates the tableview using the register @@ -252,26 +267,13 @@ public class BudgetController implements FinanceController { * Method for synching the register with the tableview. The observable list to which the tableview is set, is being refilled with all the entries * in the register, keeping it updated with new changes. */ + @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())); } - /** - * Returns an optional, which is a popup alert box, asking for confirmation for deleting an entry. - * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. - */ - @Override - public Optional<ButtonType> showConfirmationDialog(String title, String header, String content) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("Confirm Delete"); - alert.setHeaderText("Delete Confirmation"); - alert.setContentText("Are you sure you would like to delete the selected entry?"); - - return alert.showAndWait(); - } - /** * Saves the changes made to the tableview by writing the information to a file. * @@ -279,62 +281,59 @@ public class BudgetController implements FinanceController { */ @Override public void saveDataToFile() throws IOException { - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); - fileHandlingBudget.writeGeneralBudgetToFile("Budget", general); - } - - /** - * Displays an alert box of type error, informing of a custom error. - */ - private 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(); + FileHandlingBudget.writeGeneralBudgetToFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget", general); } - /** - * Method that either reads data from a file with which it fills a budget register, if this is an old budget, or instantiates a budget register if this is a new budget. - * @param fileName The name of the file that is being read from. - * @return An object of type GeneralBudget. - * @throws IOException If an error occurs while reading from the file. - */ - public GeneralBudget loadBudgetDataFromFile(String fileName) throws IOException { - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); - //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); - } catch (IOException e) { - showErrorDialogBox("File error", "Error in reading from fil", "An error occurred" - + "when reading GeneralBudget from the file"); - } + public void updateBudgetRegister(String budgetFolderName) { + try { + budgetRegister.addBudgetName(budgetFolderName); + FileHandlingBudgetArchive.writeBudgetRegisterToArchive(budgetRegister); + } catch(IOException ioe) { + showErrorDialogBox(ioe.getMessage(), ioe.getMessage(), ioe.getMessage()); } - return general; + } /** - * Switches scenes back to main menu, by loading a new FXML file and setting the scene to this location. + * Switches scene, 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 - public void returnToMainMenu(ActionEvent event) throws IOException { - //Adds unused categories to the table - general.addUnusedCategories(); - //Always saving the data when switching scenes - saveDataToFile(); + @Override + public void switchScene(ActionEvent event) { FXMLLoader loader = new FXMLLoader(); - loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); - - Parent root = loader.load(); - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); + try { + if (event.getSource() == returnToMainMenuBtn) { + //Adds unused categories to the table + general.addUnusedCategories(); + loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); + //Always saving the data when switching scenes + saveDataToFile(); + } else if (event.getSource() == continueBtn) { + general.addUnusedCategories(); + updateBudgetRegister(FileHandlingSelectedBudget.readSelectedBudget()); + loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); + //Always saving the data when switching scenes + saveDataToFile(); + } else if (event.getSource() == backBtn) { + loader.setLocation(getClass().getResource("/view/dualList.fxml")); + } + Parent root = loader.load(); + Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); + Scene scene = new Scene(root); + stage.setScene(scene); + + //Centralize the new screen + Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds(); + stage.setX((primScreenBounds.getWidth() - stage.getWidth()) / 2); + stage.setY((primScreenBounds.getHeight() - stage.getHeight()) / 2); + + stage.show(); + + } catch(Exception ioe) { + ioe.printStackTrace(); + showErrorDialogBox("Loading error", "Error in loading", "Could not load" + + " FXML file in: " + loader.getLocation()); + } } } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java new file mode 100644 index 0000000000000000000000000000000000000000..e061094c62103ef3d9fb5ee147467c08e4987347 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/CreateBudgetController.java @@ -0,0 +1,134 @@ +package no.ntnu.idatt1002.demo.controller; + +import java.io.IOException; +import java.time.LocalDate; +import java.util.Optional; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; +import no.ntnu.idatt1002.demo.data.Economics.Expense; + +public class CreateBudgetController { + + public Button okBtn; + public Button cancelBtn; + private String currentMonth; + + private Expense expense; + + private String budgetName; + + @FXML + private TextField nameField; + + @FXML + private Label errorMsg; + + + @FXML + public void initialize() { + currentMonth = String.valueOf(LocalDate.now().getMonth()); + okBtn.addEventFilter( + ActionEvent.ACTION, event -> { + if(nameField.getText().equals("")) { + errorMsg.setOpacity(1); + 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") + } + ); + } + @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"; + + budgetName = nameField.getText(); + System.out.println(budgetName); + + if(!createNewFiles(budgetName)) { + updateCurrentFile("", ""); + errorMsg.setText("A budget of the same name already exists"); + errorMsg.setOpacity(1); + return; + } + + Optional<ButtonType> isConfirmed = showConfirmationDialog(title, header, content); + if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { + updateCurrentFile(currentMonth, budgetName); + } else { + updateCurrentFile("", ""); + } + + final Node source = (Node) event.getSource(); + ((Stage) source.getScene().getWindow()).close(); + } + + @FXML + public void pressCancelBtn(ActionEvent event) { + updateCurrentFile("", ""); + final Node source = (Node) event.getSource(); + ((Stage) source.getScene().getWindow()).close(); + } + + /** + * Returns an optional, which is a popup alert box, asking for confirmation for deleting an entry. + * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. + */ + @FXML + private Optional<ButtonType> showConfirmationDialog(String title, String header, String content) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle(title); + alert.setHeaderText(header); + alert.setContentText(content); + + return alert.showAndWait(); + } + + private void showErrorMsgBox(String title, String header, String content) { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle(title); + alert.setHeaderText(header); + alert.setContentText(content); + + alert.showAndWait(); + } + + 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"); + } catch (IOException ioe) { + empty = false; + System.out.println(ioe.getMessage()); + ioe.printStackTrace(); + showErrorMsgBox(ioe.getMessage(), ioe.getMessage(), ioe.getMessage()); + } + return empty; + } + + public void updateCurrentFile(String currentMonth, String budgetName) { + try { + FileHandlingSelectedBudget.updateSelectedBudget(currentMonth + budgetName); + } catch (IOException ioe) { + showErrorMsgBox(ioe.getMessage(), ioe.getMessage(), ioe.getMessage()); + } + } +} diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java deleted file mode 100644 index d3ac8a5ad8cbe7a8374ab5986fef07869f3a1ec1..0000000000000000000000000000000000000000 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/ExpensesController.java +++ /dev/null @@ -1,286 +0,0 @@ -package no.ntnu.idatt1002.demo.controller; - -import java.io.IOException; - -import java.util.Optional; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Dialog; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.text.Text; -import javafx.stage.Modality; -import javafx.stage.Stage; -import no.ntnu.idatt1002.demo.data.Economics.Expense; -import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; -import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister; -import no.ntnu.idatt1002.demo.data.Economics.FileHandling; -import no.ntnu.idatt1002.demo.data.Economics.Income; -import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; -import no.ntnu.idatt1002.demo.data.Economics.Item; -import no.ntnu.idatt1002.demo.data.Economics.ItemRegister; - -/** - * Controller for expense scene in the application. This controller manages all actions that relates to the expense tableview (add, edit and delete), the switching - * of scenes from the expense scene to another scene, and the saving of the table, whenever the user switches to another scene. - * - * @author Harry Linrui Xu - * @since 13.3.2023 - */ -public class ExpensesController { - - @FXML - private Button addBtn; - @FXML - private Button editBtn; - - @FXML - private Button deleteBtn; - - @FXML - private ComboBox<String> show; - - @FXML - private Button incomeBtn; - - @FXML - private Text sum; - - @FXML - private Button budgetBtn; - - @FXML - private Button returnBtn; - - - @FXML - private TableColumn<Expense, Double> amountColumn; - - @FXML - private TableColumn<Expense, ExpenseCategory> categoryColumn; - - @FXML - private TableColumn<Expense, String> dateColumn; - - @FXML - private TableColumn<Expense, String> descriptionColumn; - - @FXML - private TableColumn<Expense, Boolean> recurringColumn; - - @FXML - private TableView<Expense> expenseTableView; - - @FXML - ExpenseRegister expenseRegister; - ObservableList<Expense> expenses; - - ObservableList<String> filter; - - /** - * Initializes the expense register, the observable expense list and the tableview, along values of the dropbox used for filtering the tableview. - * The method is called each time the FXML of this scene is loaded. - * @throws IOException If there occurs any exception when loading the budget register from a file. - */ - @FXML - public void initialize() throws IOException { - //Initialize table columns - dateColumn.setCellValueFactory(new PropertyValueFactory<Expense, String>("date")); - amountColumn.setCellValueFactory(new PropertyValueFactory<Expense, Double>("amount")); - categoryColumn.setCellValueFactory(new PropertyValueFactory<Expense, ExpenseCategory>("category")); - descriptionColumn.setCellValueFactory(new PropertyValueFactory<Expense, String>("description")); - recurringColumn.setCellValueFactory(new PropertyValueFactory<Expense, Boolean>("recurring")); - - //Initialize the filter box - filter = FXCollections.observableArrayList("All", "Food", "Clothes", "Books", "Other", - "Fixed expense"); - show.setItems(filter); - show.setValue("All"); - - //Initialize registers and tableview - expenseRegister = loadExpenseDataFromFile("Expense"); - expenses = FXCollections.observableArrayList(expenseRegister.getItems()); - expenseTableView.setItems(expenses); - - //Initialize sum field under the tableview - sum.setText(String.valueOf(expenseRegister.getTotalSum())); - } - - /** - * Method for handling the adding of new entries in the tableview. - * @param event A button click on the add button. - */ - @FXML - protected void handleAddButton(ActionEvent event) { - handleEditButton(event); - } - - /** - * Method for handling the editing of a chosen entry in the tableview. - * @param event A button click on the edit button. - */ - @FXML - protected void handleEditButton(ActionEvent event) { - //Instantiate FXML loader and loads the popup for adding expense - FXMLLoader loader = new FXMLLoader(); - loader.setLocation(getClass().getResource("/view/AddExpense.fxml")); - - Expense newExpense = null; - String dialogTitle = ""; - // Load the FXML file for your dialog box - Dialog<Expense> dialog = new Dialog<>(); - dialog.initModality(Modality.APPLICATION_MODAL); - - try { - // Set the Dialog's content to the loaded FXML file - dialog.getDialogPane().setContent(loader.load()); - } catch (IOException e) { - e.printStackTrace(); - } - - // Get the controller for the loaded FXML file - AddExpenseController dialogController = loader.getController(); - - /** - * The mode of the dialog. NEW if new contact, EDIT if edit existing contact. - */ - DialogMode dialogMode; - //Sets the title of the dialog box - if (event.getSource().equals(addBtn)) { - dialogMode = DialogMode.ADD; - dialogTitle = "Add expense"; - - - } else if (event.getSource().equals(editBtn) - && expenseTableView.getSelectionModel().getSelectedItem() != null) { - dialogMode = DialogMode.EDIT; - dialogTitle = "Edit expense"; - //Gets the selected item from the table - newExpense = expenseTableView.getSelectionModel().getSelectedItem(); - //Binds the selected item to another item which is defined in the ItemController - dialogController.setExpense(newExpense); - } else { - return; - } - dialog.setTitle(dialogTitle); - // Show the Dialog and wait for the user to close it - dialog.showAndWait(); - - //Get the newly created expense from the dialog pane - newExpense = dialogController.getNewExpense(); - - //Adds the new item to the register - if (newExpense != null && dialogMode == DialogMode.ADD) { - expenseRegister.addItem(newExpense); - } - //Updates the tableview using the register - refreshTableView(); - } - - /** - * Deletes an entry from the tableview, if an entry has been selected. The method brings up a popup window, asking for confirmation for deleting the entry. - * @param event A button click on the delete button - */ - @FXML - public void handleDeleteBtn(ActionEvent event) { - Expense chosenExpense = expenseTableView.getSelectionModel().getSelectedItem(); - if (chosenExpense == null) { - return; - } - Optional<ButtonType> isConfirmed = showConfirmationDialog(); - if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { - expenseRegister.removeItem(chosenExpense); - refreshTableView(); - } - } - - /** - * Method for synching the register with the tableview. The observable list to which the tableview is set, is being refilled with all the entries - * in the register, keeping it updated with new changes. - */ - protected void refreshTableView() { - this.expenses.setAll(expenseRegister.getItems()); - this.sum.setText(String.valueOf(expenseRegister.getTotalSum())); - - } - - /** - * Returns an optional, which is a popup alert box, asking for confirmation for deleting an entry. - * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. - */ - private Optional<ButtonType> showConfirmationDialog() { - Alert alert = new Alert(AlertType.CONFIRMATION); - alert.setTitle("Confirm Delete"); - alert.setHeaderText("Delete Confirmation"); - alert.setContentText("Are you sure you would like to delete the selected entry?"); - - return alert.showAndWait(); - } - - /** - * Method that either reads data from a file with which it fills an expense register, if older changes exist, or instantiates an expense register if the file is empty. - * @param fileName The name of the file that is being read from. - * @return An object of type IncomeRegister. - * @throws IOException If an error occurs while reading from the file. - */ - public ExpenseRegister loadExpenseDataFromFile(String fileName) throws IOException { - //ItemRegister<T extends Item> - FileHandling fileHandling = new FileHandling(); - if (fileHandling.isEmpty(fileName)) { - expenseRegister = new ExpenseRegister(); - } else { - try { - expenseRegister = fileHandling.readExpenseRegisterFromFile(fileName); - } catch (IOException e) { - e.printStackTrace(); - } - } - return expenseRegister; - } - - /** - * Saves the changes made to the expense tableview by writing the information to a file. - * @param fileName The name of the file that is written to. - * @throws IOException If an error occurs while writing to the file. - */ - public void saveDataToFile(String fileName) throws IOException { - FileHandling fileHandling = new FileHandling(); - fileHandling.writeItemRegisterToFile(expenseRegister, fileName); - } - - /** - * Switches scenes from the expense 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 - * @throws IOException If an error occurs with loading any of the FXML files. - */ - @FXML - public void switchScene(ActionEvent event) throws IOException { - saveDataToFile("Expense"); - FXMLLoader loader = new FXMLLoader(); - if (event.getSource() == incomeBtn) { - loader.setLocation(SceneController.class.getResource("/view/Income.fxml")); - } else if (event.getSource() == returnBtn) { - loader.setLocation(SceneController.class.getResource("/view/FirstMenu.fxml")); - } else if (event.getSource() == budgetBtn) { - loader.setLocation(SceneController.class.getResource("/view/BudgetNew.fxml")); - } - Parent root = loader.load(); - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); - } - } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java index 4e63594465fe17a9985f94c7274956aaa7e40064..36a538221a4bc5b5b24b698619a6b32cb62ca6d0 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/FinanceController.java @@ -2,8 +2,19 @@ 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.ObservableList; +import javafx.scene.chart.PieChart; +import javafx.scene.chart.PieChart.Data; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ButtonType; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget; +import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister; +import no.ntnu.idatt1002.demo.data.Economics.FileHandling; +import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; /** * Interface for controllers for scenes with finance tableviews. @@ -11,49 +22,146 @@ import javafx.scene.control.ButtonType; * @author Harry Linrui Xu * @since 29.3.2023 */ -public interface FinanceController { +public abstract class FinanceController { + private ExpenseRegister expenseRegister; + + private IncomeRegister incomeRegister; + + private GeneralBudget general; /** * Method for handling the adding of new entries in the tableview. * @param event A button click on the add button. */ - void handleAddBtn(javafx.event.ActionEvent event); + abstract void handleAddBtn(javafx.event.ActionEvent event); /** * Method for handling the editing of a chosen entry in the tableview. * @param event A button click on the edit button. */ - void handleEditBtn(javafx.event.ActionEvent event); + abstract void handleEditBtn(javafx.event.ActionEvent event); /** * Deletes an entry from the tableview, if an entry has been selected. The method brings up a popup window, asking for confirmation for deleting the entry. * @param event A button click on the delete button */ - void handleDeleteBtn(javafx.event.ActionEvent event); + abstract void handleDeleteBtn(javafx.event.ActionEvent event); /** * Method for synching the register with the tableview. The observable list to which the tableview is set, is being refilled with all the entries * in the register, keeping it updated with new changes. */ - void refreshTableView(); + abstract void refreshTableView(); /** * Returns an optional, which is a popup alert box, asking for confirmation for deleting an entry. * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. */ - Optional<ButtonType> showConfirmationDialog(String title, String header, String content); + public Optional<ButtonType> showConfirmationDialog(String title, String header, String content) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle(title); + alert.setHeaderText(header); + alert.setContentText(content); + + return alert.showAndWait(); + } + + abstract void refreshPieChart(); + + /** + * Method for disabling the date picker, yet having its opacity at max. + */ + abstract void formatDatePicker(); + + /** + * Displays an alert box of type error, informing of a custom error. + */ + 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(); + } + + /** + * Method that either reads data from a file with which it fills a budget register, if this is an old budget, or instantiates a budget register if this is a new budget. + * @param fileName The name of the file that is being read from. + * @return An object of type GeneralBudget. + * @throws IOException If an error occurs while reading from the file. + */ + public GeneralBudget loadBudgetDataFromFile(String fileName) throws IOException { + //Instantiate new budget + if (FileHandlingBudget.isEmpty(fileName)) { + general = new GeneralBudget(1000); + //throws new IOException("Not valid budget") + } else { //Load previous budget + try { + general = FileHandlingBudget.readGeneralBudgetFromFile(fileName); + } catch (IOException e) { + showErrorDialogBox("File error", "Error in reading from fil", "An error occurred" + + "when reading GeneralBudget from the file"); + } + } + return general; + } + + /** + * Method that either reads data from a file with which it fills an income register, if older changes exist, or instantiates an income register if the file is empty. + * @param fileName The name of the file that is being read from. + * @return An object of type IncomeRegister. + */ + public IncomeRegister loadIncomeDataFromFile(String fileName) { + //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) { + ioe.printStackTrace(); + showErrorDialogBox("File reading error", "Error in reading from file", "Could not" + + "read the IncomeRegister from file"); + } + return incomeRegister; + } + + /** + * Method that either reads data from a file with which it fills an expense register, if older changes exist, or instantiates an expense register if the file is empty. + * @param fileName The name of the file that is being read from. + * @return An object of type IncomeRegister. + */ + public ExpenseRegister loadExpenseDataFromFile(String fileName) { + //Instantiate expense register + 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" + + "read the ExpenseRegister from file"); + } + return expenseRegister; + } + /** * Saves the changes made to the tableview by writing the information to a file. * @throws IOException If an error occurs while writing to the file. */ - void saveDataToFile() throws IOException; + abstract void saveDataToFile() throws IOException; /** - * Switches scenes back to main menu, by loading a new FXML file and setting the scene to this location. + * Switches scenes, 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; + abstract void switchScene(javafx.event.ActionEvent event); } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeController.java deleted file mode 100644 index c25c5ebb849641cf227e291b9ab05e3568cc8cb1..0000000000000000000000000000000000000000 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeController.java +++ /dev/null @@ -1,283 +0,0 @@ -package no.ntnu.idatt1002.demo.controller; - -import java.io.IOException; - -import java.util.Optional; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Dialog; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.text.Text; -import javafx.stage.Modality; -import javafx.stage.Stage; -import no.ntnu.idatt1002.demo.data.Economics.Income; -import no.ntnu.idatt1002.demo.data.Economics.IncomeCategory; -import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; -import no.ntnu.idatt1002.demo.data.Economics.FileHandling; - -/** - * Controller for income scene in the application. This controller manages all actions that relates to the income tableview (add, edit and delete), the switching - * of scenes from the income scene to another scene, and the saving of the table, whenever the user switches to another scene. - * - * @author Harry Linrui Xu - * @since 24.3.2023 - */ -public class IncomeController { - - @FXML - private Button addBtn; - @FXML - private Button editBtn; - - @FXML - private Button deleteBtn; - - @FXML - private ComboBox<String> show; - - @FXML - private Button expenseBtn; - - @FXML - private Button overviewBtn; - - @FXML - private Button budgetBtn; - @FXML - private Button returnBtn; - - @FXML - private Text sum; - @FXML - private TableColumn<Income, Double> amountColumn; - - @FXML - private TableColumn<Income, IncomeCategory> categoryColumn; - - @FXML - private TableColumn<Income, String> dateColumn; - - @FXML - private TableColumn<Income, String> descriptionColumn; - - @FXML - private TableColumn<Income, Boolean> recurringColumn; - - @FXML - private TableView<Income> incomeTableView; - - IncomeRegister incomeRegister; - ObservableList<Income> income; - - ObservableList<String> filter; - - /** - * Initializes the income register, the observable income list and the tableview, along values of the dropbox used for filtering the tableview. - * The method is called each time the FXML of this scene is loaded. - * @throws IOException If there occurs any exception when loading the budget register from a file. - */ - @FXML - public void initialize() throws IOException { - //Initialize table columns - dateColumn.setCellValueFactory(new PropertyValueFactory<Income, String>("date")); - amountColumn.setCellValueFactory(new PropertyValueFactory<Income, Double>("amount")); - categoryColumn.setCellValueFactory(new PropertyValueFactory<Income, IncomeCategory>("category")); - descriptionColumn.setCellValueFactory(new PropertyValueFactory<Income, String>("description")); - recurringColumn.setCellValueFactory(new PropertyValueFactory<Income, Boolean>("recurring")); - - //Initialize the filter box - filter = FXCollections.observableArrayList("All", "Gift", "Salary", "Student loan", "Fixed income"); - show.setItems(filter); - show.setValue("All"); - - //Initialize registers and tableview - incomeRegister = loadIncomeDataFromFile("Income"); - income = FXCollections.observableArrayList(incomeRegister.getItems()); - incomeTableView.setItems(income); - - //Initialize sum field under the tableview - sum.setText(String.valueOf(incomeRegister.getTotalSum())); - //if budget.register isEmpty -> disable expense - } - - /** - * Method for handling the adding of new entries in the tableview. - * @param event A button click on the add button. - */ - @FXML - protected void handleAddButton(ActionEvent event) { - handleEditButton(event); - } - - /** - * Method for handling the editing of a chosen entry in the tableview. - * @param event A button click on the edit button. - */ - @FXML - protected void handleEditButton(ActionEvent event) { - //Instantiate FXML loader and loads the popup for adding income - FXMLLoader loader = new FXMLLoader(); - loader.setLocation(getClass().getResource("/view/AddIncome.fxml")); - - Income newIncome = null; - String dialogTitle = ""; - // Load the FXML file for your dialog box - Dialog<Income> dialog = new Dialog<>(); - dialog.initModality(Modality.APPLICATION_MODAL); - - try { - // Set the Dialog's content to the loaded FXML file - dialog.getDialogPane().setContent(loader.load()); - } catch (IOException e) { - e.printStackTrace(); - } - - // Get the controller for the loaded FXML file - AddIncomeController dialogController = loader.getController(); - - /** - * The mode of the dialog. NEW if new contact, EDIT if edit existing contact. - */ - DialogMode dialogMode; - //Sets the title of the dialog box - if (event.getSource().equals(addBtn)) { - dialogMode = DialogMode.ADD; - dialogTitle = "Add income"; - } - else if (event.getSource().equals(editBtn) && incomeTableView.getSelectionModel().getSelectedItem() != null) { - dialogMode = DialogMode.EDIT; - dialogTitle = "Edit income"; - //Gets the selected item from the table - newIncome = incomeTableView.getSelectionModel().getSelectedItem(); - //Binds the selected item to another item which is defined in the ItemController - dialogController.setIncome(newIncome); - } - else { - return; - } - - dialog.setTitle(dialogTitle); - // Show the Dialog and wait for the user to close it - dialog.showAndWait(); - //Get the newly created income from the dialog pane - newIncome = dialogController.getNewIncome(); - - //Adds the new item to the register - if (newIncome != null && dialogMode == DialogMode.ADD) { - incomeRegister.addItem(newIncome); - } - //Updates the tableview using the register - refreshTableView(); - } - - /** - * Deletes an entry from the tableview, if an entry has been selected. The method brings up a popup window, asking for confirmation for deleting the entry. - * @param event A button click on the delete button - */ - @FXML - public void handleDeleteBtn(ActionEvent event) { - //Gets the selected item from the tableview - Income chosenIncome = incomeTableView.getSelectionModel().getSelectedItem(); - //Exits the method if nothing is selected - if (chosenIncome == null) { - return; - } - //Brings up a confirmation popup - Optional<ButtonType> isConfirmed = showConfirmationDialog(); - if (isConfirmed.isPresent() && isConfirmed.get() == ButtonType.OK) { - incomeRegister.removeItem(chosenIncome); - refreshTableView(); - } - } - - /** - * Method for synching the register with the tableview. The observable list to which the tableview is set, is being refilled with all the entries - * in the register, keeping it updated with new changes. - */ - protected void refreshTableView() { - this.income.setAll(incomeRegister.getItems()); - this.sum.setText(String.valueOf(incomeRegister.getTotalSum())); - } - - /** - * Returns an optional, which is a popup alert box, asking for confirmation for deleting an entry. - * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. - */ - private Optional<ButtonType> showConfirmationDialog() { - Alert alert = new Alert(AlertType.CONFIRMATION); - alert.setTitle("Confirm Delete"); - alert.setHeaderText("Delete Confirmation"); - alert.setContentText("Are you sure you would like to delete the selected entry?"); - - return alert.showAndWait(); - } - - /** - * Method that either reads data from a file with which it fills an income register, if older changes exist, or instantiates an income register if the file is empty. - * @param fileName The name of the file that is being read from. - * @return An object of type IncomeRegister. - * @throws IOException If an error occurs while reading from the file. - */ - public IncomeRegister loadIncomeDataFromFile(String fileName) throws IOException { - FileHandling fileHandling = new FileHandling(); - //Instantiate new incomeRegister - if (fileHandling.isEmpty(fileName)) { - incomeRegister = new IncomeRegister(); - } else { //Load previous income register - try { - incomeRegister = fileHandling.readIncomeRegisterFromFile(fileName); - } catch (IOException e) { - e.printStackTrace(); - } - } - return incomeRegister; - } - - /** - * Saves the changes made to the income tableview by writing the information to a file. - * @param fileName The name of the file that is written to. - * @throws IOException If an error occurs while writing to the file. - */ - public void saveDataToFile(String fileName) throws IOException { - FileHandling fileHandling = new FileHandling(); - fileHandling.writeItemRegisterToFile(incomeRegister, fileName); - } - - /** - * Switches scenes from the income 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 - * @throws IOException If an error occurs with loading any of the FXML files. - */ - @FXML - public void switchScene(ActionEvent event) throws IOException { - //Always saving the data when switching scenes - saveDataToFile("Income"); - FXMLLoader loader = new FXMLLoader(); - if (event.getSource() == overviewBtn) { - loader.setLocation(SceneController.class.getResource("/view/Overview.fxml")); - } else if (event.getSource() == returnBtn) { - loader.setLocation(SceneController.class.getResource("/view/FirstMenu.fxml")); - } else if (event.getSource() == budgetBtn) { - loader.setLocation(SceneController.class.getResource("/view/BudgetNewest.fxml")); - } - Parent root = loader.load(); - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); - } - } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java index 27996dca15ac873a7e1b27289a6be97ae769e1c9..2f0c5bb774f62ff9ae62b52f21ccf4a8df895040 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/IncomeExpenseController.java @@ -13,8 +13,6 @@ import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.chart.PieChart; import javafx.scene.chart.PieChart.Data; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.control.ComboBox; @@ -22,13 +20,14 @@ import javafx.scene.control.DatePicker; import javafx.scene.control.Dialog; import javafx.scene.control.Label; import javafx.scene.control.MenuItem; -import javafx.scene.control.ProgressBar; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.stage.Modality; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudgetArchive; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget; import no.ntnu.idatt1002.demo.data.Economics.Expense; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; @@ -47,7 +46,7 @@ import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; * @author Harry Linrui Xu * @since 30.03.2023 */ -public class IncomeExpenseController implements FinanceController { +public class IncomeExpenseController extends FinanceController { private final static String sumText = "Sum: "; @FXML private TableColumn<Expense, Double> expAmountCol; @@ -97,9 +96,6 @@ public class IncomeExpenseController implements FinanceController { @FXML private MenuItem addIncome; - @FXML - private ProgressBar budgetProgress; - @FXML private DatePicker date; @@ -109,9 +105,15 @@ public class IncomeExpenseController implements FinanceController { @FXML private ComboBox<?> filter; + @FXML + private Button returnToMainMenuBtn; + @FXML private Button returnBtn; + @FXML + private Button continueBtn; + @FXML private Label title; @@ -146,43 +148,43 @@ public class IncomeExpenseController implements FinanceController { @FXML private PieChart incomePieChart; - - FileHandling fileHandling; - @FXML public void initialize() { - fileHandling = new FileHandling(); + System.out.println("Start of initialize"); //Initialize columns setColumns(); - + try { //Initialize registers and tableview - incomeRegister = loadIncomeDataFromFile("Income"); - income = FXCollections.observableArrayList(incomeRegister.getItems()); - incomeTableView.setItems(income); + incomeRegister = loadIncomeDataFromFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Income"); + expenseRegister = loadExpenseDataFromFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Expense"); + } catch(IOException ioe) { + showErrorDialogBox("File reading error", "Could not read register", ""); + } - expenseRegister = loadExpenseDataFromFile("Expense"); - expenses = FXCollections.observableArrayList(expenseRegister.getItems()); - expenseTableView.setItems(expenses); - //Setting pie chart values to correspond with the registers - incomePieChart.setLegendSide(Side.RIGHT); + income = FXCollections.observableArrayList(incomeRegister.getItems()); + incomeTableView.setItems(income); - expensePieChart.setLegendSide(Side.RIGHT); - expensePieChart.setLabelLineLength(10); + expenses = FXCollections.observableArrayList(expenseRegister.getItems()); + expenseTableView.setItems(expenses); - refreshPieCharts(); + //Setting pie chart values to correspond with the registers + incomePieChart.setLegendSide(Side.RIGHT); + incomePieChart.setLabelLineLength(10); - refreshPieCharts(); - refreshProgress(); + expensePieChart.setLegendSide(Side.RIGHT); + expensePieChart.setLabelLineLength(10); + refreshPieChart(); formatDatePicker(); //Initialize sum field under the tableview inSum.setText(sumText + String.valueOf(incomeRegister.getTotalSum())); expSum.setText(sumText + String.valueOf(expenseRegister.getTotalSum())); - } private void setColumns() { @@ -199,7 +201,7 @@ public class IncomeExpenseController implements FinanceController { expRecurringCol.setCellValueFactory(new PropertyValueFactory<>("recurring")); } - private ObservableList<PieChart.Data> createExpensePieChart() { + public ObservableList<PieChart.Data> createExpensePieChart() { return FXCollections.observableArrayList( new Data("Food", expenseRegister.getExpenseByCategory(ExpenseCategory.FOOD).getTotalSum()), new Data("Books", expenseRegister.getExpenseByCategory(ExpenseCategory.BOOKS).getTotalSum()), @@ -219,7 +221,8 @@ public class IncomeExpenseController implements FinanceController { /** * Method for disabling the date picker, yet having its opacity at max. */ - private void formatDatePicker() { + @Override + public void formatDatePicker() { date.setValue(LocalDate.now()); date.setDisable(true); date.setStyle("-fx-opacity: 1"); @@ -229,6 +232,7 @@ public class IncomeExpenseController implements FinanceController { * 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()); @@ -243,7 +247,6 @@ public class IncomeExpenseController implements FinanceController { if (sizeAf != sizeBf) { refreshTableView(); - refreshProgress(); } } @@ -254,7 +257,6 @@ public class IncomeExpenseController implements FinanceController { */ @Override public void handleEditBtn(javafx.event.ActionEvent event) { - System.out.println(event.getSource()); Income chosenIncome = incomeTableView.getSelectionModel().getSelectedItem(); Expense chosenExpense = expenseTableView.getSelectionModel().getSelectedItem(); @@ -278,7 +280,6 @@ public class IncomeExpenseController implements FinanceController { //Updates the tableview and pie chart using the register refreshTableView(); - refreshProgress(); } /** @@ -306,15 +307,12 @@ public class IncomeExpenseController implements FinanceController { this.expSum.setText("Sum: " + String.valueOf(expenseRegister.getTotalSum())); } - private void refreshPieCharts() { + @Override + public void refreshPieChart() { this.incomePieChart.setData(createIncomePieChart()); this.expensePieChart.setData(createExpensePieChart()); } - private void refreshProgress() { - budgetProgress.setProgress(expenseRegister.getTotalSum()/incomeRegister.getTotalSum()); - } - @FXML private void handleAddIncome() { //Instantiate FXML loader and loads the popup for adding income @@ -359,7 +357,6 @@ public class IncomeExpenseController implements FinanceController { Expense newExpense; String dialogTitle = "Add expense"; - // Load the FXML file for your dialog box Dialog<Expense> dialog = new Dialog<>(); dialog.initModality(Modality.APPLICATION_MODAL); @@ -475,34 +472,6 @@ public class IncomeExpenseController implements FinanceController { } this.expensePieChart.setData(createExpensePieChart()); } - /** - * Returns an optional, which is a popup alert box, asking for confirmation for deleting an - * entry. - * - * @return An alert box, asking for confirmation for deleting the selected entry of the tableview. - */ - @Override - public Optional<ButtonType> showConfirmationDialog(String title, String header, String content) { - Alert alert = new Alert(AlertType.CONFIRMATION); - alert.setTitle("Confirm Delete"); - alert.setHeaderText("Delete Confirmation"); - alert.setContentText("Are you sure you would like to delete the selected entry?"); - - return alert.showAndWait(); - } - - - /** - * Displays an alert box of type error, informing of a custom error. - */ - private 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(); - } - /** * Saves the changes made to the tableview by writing the information to a file. @@ -510,92 +479,45 @@ public class IncomeExpenseController implements FinanceController { */ @Override public void saveDataToFile() throws IOException { - fileHandling.writeItemRegisterToFile(incomeRegister, "Income"); - fileHandling.writeItemRegisterToFile(expenseRegister, "Expense"); + FileHandling.writeItemRegisterToFile(incomeRegister, + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Income"); + FileHandling.writeItemRegisterToFile(expenseRegister, + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Expense"); } - - /** - * Method that either reads data from a file with which it fills an income register, if older changes exist, or instantiates an income register if the file is empty. - * @param fileName The name of the file that is being read from. - * @return An object of type IncomeRegister. - */ - public IncomeRegister loadIncomeDataFromFile(String fileName) { - //Instantiate new incomeRegister - try { - if (fileHandling.isEmpty(fileName)) { - incomeRegister = new IncomeRegister(); - } else { //Load previous income register - incomeRegister = fileHandling.readIncomeRegisterFromFile(fileName); - } - } catch (IOException ioe) { - showErrorDialogBox("File reading error", "Error in reading from file", "Could not" - + "read the IncomeRegister from file"); - } - return incomeRegister; + public void saveDisposableIncomeToFile() throws IOException { + String disposableIncomeAsString = String.valueOf(incomeRegister.getTotalSum() - expenseRegister.getTotalSum()); + FileHandlingBudget.writeMaxAmountToFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget", disposableIncomeAsString); } - - /** - * Method that either reads data from a file with which it fills an expense register, if older changes exist, or instantiates an expense register if the file is empty. - * @param fileName The name of the file that is being read from. - * @return An object of type IncomeRegister. - */ - public ExpenseRegister loadExpenseDataFromFile(String fileName) { - //ItemRegister<T extends Item> - try { - if (fileHandling.isEmpty(fileName)) { - expenseRegister = new ExpenseRegister(); - } else { //Load previous income register - expenseRegister = fileHandling.readExpenseRegisterFromFile(fileName); - } - } catch (IOException ioe) { - showErrorDialogBox("File reading error", "Error in reading from file", "Could not" - + "read the ExpenseRegister from file"); - } - return expenseRegister; - } - - /** - * Method that either reads data from a file with which it fills a budget register, if this is an old budget, or instantiates a budget register if this is a new budget. - * @param fileName The name of the file that is being read from. - * @return An object of type GeneralBudget. - */ - public GeneralBudget loadBudgetDataFromFile(String fileName) { - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); - //Instantiate new budget - try { - if (fileHandling.isEmpty(fileName)) { - generalBudget = new GeneralBudget(31, 1000); - } else { //Load previous income register - generalBudget = fileHandlingBudget.readGeneralBudgetFromFile(fileName); - } - } catch (IOException ioe) { - showErrorDialogBox("File reading error", "Error in reading from file", "Could not" - + "read the GeneralBudget from file"); - } - return generalBudget; - } - /** * 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 */ @FXML - public void returnToMainMenu(javafx.event.ActionEvent event) { + public void switchScene(javafx.event.ActionEvent event) { try { - saveDataToFile(); FXMLLoader loader = new FXMLLoader(); - loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); - + if (event.getSource() == returnToMainMenuBtn) { + saveDataToFile(); + loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); + } else if (event.getSource() == continueBtn) { + loader.setLocation(getClass().getResource("/view/newBudgetBudgert.fxml")); + saveDisposableIncomeToFile(); + } else if (event.getSource() == returnBtn) { + loader.setLocation(getClass().getResource("/view/FirstMenu.fxml")); + FileHandlingBudgetArchive.deleteBudgetDirectory(FileHandlingSelectedBudget.readSelectedBudget()); + FileHandlingSelectedBudget.clearSelectedBudget(); + } Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } catch(IOException ioe) { - showErrorDialogBox("Loading error", "Error in loading", "Could not save" + ioe.printStackTrace(); + showErrorDialogBox("Loading error", "Error in loading", "Could not save" + "to file"); } - } } 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 7e37ae10765388d4b137cb627a2c19130365e49e..2d62ad8bf5a89d7b949b237ddc5e627f1ce6804c 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenu.java @@ -9,6 +9,7 @@ import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.geometry.Rectangle2D; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; @@ -20,8 +21,10 @@ import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; +import javafx.stage.Screen; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; import no.ntnu.idatt1002.demo.data.Budget.GeneralBudget; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister; @@ -96,18 +99,18 @@ public class MainMenu { IncomeRegister incomeRegister; - FileHandling fileHandling; - Overview overview; @FXML public void initialize() { - fileHandling = new FileHandling(); //Initialize all registers + overview try { - incomeRegister = loadIncomeDataFromFile("Income"); - expenseRegister = loadExpenseDataFromFile("Expense"); - generalBudget = loadBudgetDataFromFile("Budget"); + incomeRegister = loadIncomeDataFromFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Income"); + expenseRegister = loadExpenseDataFromFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Expense"); + generalBudget = loadBudgetDataFromFile( + "budgets/" + FileHandlingSelectedBudget.readSelectedBudget() + "/Budget"); } catch (IOException ioe) { Alert alert = new Alert(AlertType.ERROR); alert.setTitle("Could not load register data"); @@ -153,6 +156,9 @@ public class MainMenu { */ private void refreshProgressBars() { mainBar.setProgress(expenseRegister.getTotalSum()/generalBudget.getMaxAmount()); + if (mainBar.getProgress() >= 1) { + mainBar.setStyle("-fx-accent: #fa5959;"); + } foodBar.setProgress((generalBudget.getBudgetItem(ExpenseCategory.FOOD).getBudgetAmount() - overview.getBudgetItemMinusExpense(ExpenseCategory.FOOD))/generalBudget.getBudgetItem(ExpenseCategory.FOOD).getBudgetAmount()); clothesBar.setProgress((generalBudget.getBudgetItem(ExpenseCategory.CLOTHES).getBudgetAmount() - overview.getBudgetItemMinusExpense(ExpenseCategory.CLOTHES))/generalBudget.getBudgetItem(ExpenseCategory.CLOTHES).getBudgetAmount()); @@ -162,17 +168,17 @@ public class MainMenu { /** * Method that either reads data from a file with which it fills an income register, if older changes exist, or instantiates an income register if the file is empty. - * @param fileName The name of the file that is being read from. + * @param fileDestination The name of the file that is being read from. * @return An object of type IncomeRegister. * @throws IOException If an error occurs while reading from the file. */ - public IncomeRegister loadIncomeDataFromFile(String fileName) throws IOException { + public IncomeRegister loadIncomeDataFromFile(String fileDestination) throws IOException { //Instantiate incomeRegister - if (fileHandling.isEmpty(fileName)) { + if (FileHandling.isEmpty(fileDestination)) { incomeRegister = new IncomeRegister(); } else { //Load previous income register try { - incomeRegister = fileHandling.readIncomeRegisterFromFile(fileName); + incomeRegister = FileHandling.readIncomeRegisterFromFile(fileDestination); } catch (IOException e) { e.printStackTrace(); } @@ -182,17 +188,17 @@ public class MainMenu { /** * Method that either reads data from a file with which it fills an expense register, if older changes exist, or instantiates an expense register if the file is empty. - * @param fileName The name of the file that is being read from. + * @param fileDestination The name of the file that is being read from. * @return An object of type IncomeRegister. * @throws IOException If an error occurs while reading from the file. */ - public ExpenseRegister loadExpenseDataFromFile(String fileName) throws IOException { + public ExpenseRegister loadExpenseDataFromFile(String fileDestination) throws IOException { //Instantiate expense register - if (fileHandling.isEmpty(fileName)) { + if (FileHandling.isEmpty(fileDestination)) { expenseRegister = new ExpenseRegister(); } else { try { - expenseRegister = fileHandling.readExpenseRegisterFromFile(fileName); + expenseRegister = FileHandling.readExpenseRegisterFromFile(fileDestination); } catch (IOException e) { e.printStackTrace(); } @@ -202,18 +208,18 @@ public class MainMenu { /** * Method that either reads data from a file with which it fills a budget register, if this is an old budget, or instantiates a budget register if this is a new budget. - * @param fileName The name of the file that is being read from. + * @param fileDestination The name of the file that is being read from. * @return An object of type GeneralBudget. * @throws IOException If an error occurs while reading from the file. */ - public GeneralBudget loadBudgetDataFromFile(String fileName) throws IOException { - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); + public GeneralBudget loadBudgetDataFromFile(String fileDestination) throws IOException { //Instantiate new budget - if (fileHandlingBudget.isEmpty(fileName)) { - generalBudget = new GeneralBudget(31, 1000); + if (FileHandlingBudget.isEmpty(fileDestination)) { + System.out.println("hey"); + generalBudget = new GeneralBudget(1000); } else { //Load previous budget try { - generalBudget = fileHandlingBudget.readGeneralBudgetFromFile(fileName); + generalBudget = FileHandlingBudget.readGeneralBudgetFromFile(fileDestination); } catch (IOException e) { e.printStackTrace(); } @@ -250,6 +256,12 @@ public class MainMenu { Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); + + //Centralize the new screen + Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds(); + stage.setX((primScreenBounds.getWidth() - stage.getWidth()) / 2); + stage.setY((primScreenBounds.getHeight() - stage.getHeight()) / 2); + stage.setResizable(false); stage.show(); } diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java deleted file mode 100644 index 9a0fe9bca61214305b834ce9d82cee0f098a066c..0000000000000000000000000000000000000000 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/MainMenuController.java +++ /dev/null @@ -1,114 +0,0 @@ -package no.ntnu.idatt1002.demo.controller; -import java.io.IOException; -import java.time.LocalDate; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.DatePicker; -import javafx.scene.control.Label; -import javafx.scene.control.ProgressBar; -import javafx.scene.image.ImageView; -import javafx.scene.paint.Color; -import javafx.scene.text.Text; -import javafx.stage.Stage; -import no.ntnu.idatt1002.demo.data.Economics.ExpenseRegister; -import no.ntnu.idatt1002.demo.data.Economics.FileHandling; -import no.ntnu.idatt1002.demo.data.Economics.IncomeRegister; - -/** - * Class that acts as both a main menu and monthly budget overview that shows the monthly progress of a users account. - * The main menu act as a hub that branches to numerous other windows, such as adding expenses or looking into food recipes. - */ -public class MainMenuController { - - @FXML - private Button addExpenseBtn; - - @FXML - private Button foodButton; - - @FXML - private Button overviewBtn; - - @FXML - private ProgressBar progressbar; - - @FXML - private DatePicker date; - - @FXML - private ImageView progressMarker; - - @FXML - private Label today; - - @FXML - private Text budgetMonth; - - @FXML - private Label balanceLbl; - - - /** - * Initializes various classes that relates to income and expense, in order to present the overview that depends on the - * income (money inflow) and expense (money outflow). - * Sets the progress bar, budget month, balance label, date and how much of the monthly budget has been spent. - * @throws IOException Upon errors with file reading/writing. - */ - @FXML - public void initialize() throws IOException { - //Instantiate the income- controller and register - IncomeController incomeController = new IncomeController(); - IncomeRegister incomeRegister = incomeController.loadIncomeDataFromFile("Income"); - - //Instantiate the expense- controller and register - ExpensesController expensesController = new ExpensesController(); - ExpenseRegister expenseRegister = expensesController.loadExpenseDataFromFile("Expense"); - - double incomeSum = incomeRegister.getTotalSum(); - double expenseSum = expenseRegister.getTotalSum(); - - //Set progress - progressbar.setProgress(expenseSum/incomeSum); - //progressMarker.setTranslateX(-275 + progressbar.getProgress()); - - //Displaying month - budgetMonth.setText("BUDGET " + (LocalDate.EPOCH.getMonth())); - double balance = incomeSum - expenseSum; - //Set balance - balanceLbl.setText("Balance: " + (balance)); - - //Displaying how much of the monthly budget has been spent. - today.setText("Used " + expenseSum + " out of " + incomeSum + " this month"); - - if (balance < 0) { - balanceLbl.setTextFill(Color.RED); - } - - date.setValue(LocalDate.now()); - //date.restrict - } - - /** - * Switches scenes from the main menu 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. - * @throws IOException If an error occurs with loading any of the FXML files. - */ - @FXML - public void switchScene(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(); - loader.setLocation(SceneController.class.getResource("/view/Budget.fxml")); - - - Parent root = loader.load(); - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); - } -} diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java index 8a95589edbe458e647af77461866141986bd2889..92f9f3b73934645fae914584ca0a54bf0c6015da 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/SceneController.java @@ -3,83 +3,142 @@ package no.ntnu.idatt1002.demo.controller; import java.io.IOException; import javafx.event.ActionEvent; +import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.geometry.Rectangle2D; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Dialog; import javafx.stage.Modality; +import javafx.stage.Screen; import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; +import no.ntnu.idatt1002.demo.data.Economics.Income; public class SceneController { - private Stage stage; - private Scene scene; - - public void switchStartMenu(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/FirstMenu.fxml")); - Parent root = loader.load(); - stage = (Stage)((Node)event.getSource()).getScene().getWindow(); - scene = new Scene(root); - stage.setScene(scene); - stage.show(); - } - public void switchNewBudget(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/NewBudget.fxml")); - Parent root = loader.load(); - stage = (Stage)((Node)event.getSource()).getScene().getWindow(); - scene = new Scene(root); - stage.setScene(scene); - stage.show(); + @FXML + public void initialize() { } + + /** + * Brings up popup window to name budget + * @throws IOException + */ + @FXML public void switchIncome(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/MainMenuNew.fxml")); - Parent root = loader.load(); - stage = (Stage)((Node)event.getSource()).getScene().getWindow(); - scene = new Scene(root); - stage.setScene(scene); - stage.show(); + //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 + + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(getClass().getResource("/view/CreateBudget.fxml")); + + String budgetName; + + String dialogTitle = "Create budget"; + + Dialog<String> dialog = new Dialog<>(); + dialog.initModality(Modality.APPLICATION_MODAL); + + + try { + // Set the Dialog's content to the loaded FXML file + dialog.getDialogPane().setContent(loader.load()); + } catch (IOException e) { + showErrorDialogBox("Loading", "Error in loading dialog box", "Could not load" + + "the AddExpense window"); + } + + // Get the controller for the loaded FXML file + CreateBudgetController createBudgetController = new CreateBudgetController(); + // Show the Dialog and wait for the user to close it + dialog.setTitle(dialogTitle); + + dialog.showAndWait(); + + try { + if (FileHandlingSelectedBudget.readSelectedBudget() != null) { + switchNext(event); + } + } catch (IOException ioe) { + showErrorDialogBox("", "", ""); + } } - public void switchOverview(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/Overview.fxml")); - Parent root = loader.load(); - stage = (Stage)((Node)event.getSource()).getScene().getWindow(); - scene = new Scene(root); - stage.setScene(scene); - stage.show(); + private void switchNext(ActionEvent event) throws IOException { + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(SceneController.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(); } + private void showErrorDialogBox(String title, String header, String content) { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle(title); + alert.setHeaderText(header); + alert.setContentText(content); - public void switchMainMenu(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/MainMenu.fxml")); - Parent root = loader.load(); - stage = (Stage)((Node)event.getSource()).getScene().getWindow(); - scene = new Scene(root); - stage.setScene(scene); - stage.show(); + alert.showAndWait(); } - public void addIncome(ActionEvent event) throws IOException { - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/addIncome.fxml")); - Scene newScene = new Scene(loader.load()); - Stage newStage = new Stage(); - newStage.setScene(newScene); - newStage.setResizable(false); - newStage.initModality(Modality.APPLICATION_MODAL); + public void switchMainMenu(ActionEvent event) throws IOException { + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(SceneController.class.getResource("/view/SelectBudget.fxml")); + + String dialogTitle = "Select budget"; + // Load the FXML file for your dialog box + Dialog<Income> dialog = new Dialog<>(); + + try { + // Set the Dialog's content to the loaded FXML file + dialog.getDialogPane().setContent(loader.load()); + } catch (IOException e) { + showErrorDialogBox("Loading error", "Error in loading dialog box", "Could not load" + + "the AddIncome window"); + } - newStage.show(); + //Sets the title of the dialog box + dialog.setTitle(dialogTitle); + // Show the Dialog and wait for the user to close it + dialog.showAndWait(); + + try { + if (FileHandlingSelectedBudget.readSelectedBudget() != null) { + switchChosenBudget(event); + } + } catch(IOException ioe) { + showErrorDialogBox("Loading error", "Could not switch to main menu", ""); + } } - public void underProgress(ActionEvent event) throws IOException{ - FXMLLoader loader = new FXMLLoader(SceneController.class.getResource("/view/underProgress.fxml")); - Scene newScene = new Scene(loader.load()); - Stage newStage = new Stage(); - newStage.setScene(newScene); - newStage.setResizable(false); - newStage.initModality(Modality.APPLICATION_MODAL); + private void switchChosenBudget(ActionEvent event) throws IOException { + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(SceneController.class.getResource("/view/MainMenuNew.fxml")); + Parent root = loader.load(); + Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow(); + Scene scene = new Scene(root); + stage.setScene(scene); + + //Centralize the new screen + Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds(); + stage.setX((primScreenBounds.getWidth() - stage.getWidth()) / 2); + stage.setY((primScreenBounds.getHeight() - stage.getHeight()) / 2); - newStage.show(); + stage.show(); } + 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/SelectBudgetController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/SelectBudgetController.java new file mode 100644 index 0000000000000000000000000000000000000000..35a213b509d5372a91de3e495306dab4363b6390 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/SelectBudgetController.java @@ -0,0 +1,83 @@ +package no.ntnu.idatt1002.demo.controller; + +import java.io.IOException; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.input.MouseButton; +import javafx.stage.Stage; +import no.ntnu.idatt1002.demo.data.Budget.BudgetRegister; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudgetArchive; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; + +public class SelectBudgetController { + + @FXML + Button okBtn; + + @FXML + private Label errorMsg; + + @FXML + private ListView<String> budgetListView; + + private BudgetRegister budgetRegister; + + private ObservableList<String> budgetList; + + @FXML + public void initialize() throws IOException { + okBtn.addEventFilter( + ActionEvent.ACTION, event -> { + if (budgetListView.getSelectionModel().getSelectedItem() == null) { + errorMsg.setOpacity(1); + event.consume(); + } + }); + + try { + if (FileHandlingBudgetArchive.isBudgetRegisterEmpty()) { + budgetRegister = new BudgetRegister(); + } else { + budgetRegister = FileHandlingBudgetArchive.readBudgetArchive(""); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + System.out.println("budget register is: " + budgetRegister); + budgetList = FXCollections.observableList(budgetRegister.getBudgetNames()); + budgetListView.setItems(budgetList); + + budgetListView.setOnMouseClicked(mouseEvent-> { + if(mouseEvent.getButton().equals(MouseButton.PRIMARY)){ + if(mouseEvent.getClickCount() == 2){ + System.out.println("Double clicked"); + } + } + }); + } + + @FXML + public void selectBudget(ActionEvent event) throws IOException { + String name = budgetListView.getSelectionModel().getSelectedItem(); + System.out.println(name); + FileHandlingSelectedBudget.updateSelectedBudget(name); + + final Node source = (Node) event.getSource(); + ((Stage) source.getScene().getWindow()).close(); + } + + @FXML + public void exitWindow(ActionEvent event) throws IOException { + FileHandlingSelectedBudget.clearSelectedBudget(); + 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 new file mode 100644 index 0000000000000000000000000000000000000000..256aa5ed9d73fb68e323c3bf4f0b2aaa752377e6 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/BudgetRegister.java @@ -0,0 +1,36 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import java.util.ArrayList; +import java.util.List; + +public class BudgetRegister { + private final List<String> budgetNames; + + public BudgetRegister() { + budgetNames = new ArrayList<>(); + } + + public List<String> getBudgetNames() { + return this.budgetNames; + } + + public void addBudgetName(String name) { + 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"); + budgetNames.add(name); + } + + public void removeBudgetName(String name) { + if (name == null) throw new IllegalArgumentException("Name cannot be null"); + if (name.isBlank()) throw new IllegalArgumentException("Name cannot be blank"); + budgetNames.add(name); + } + + @Override + public String toString() { + StringBuilder namesToString = new StringBuilder(); + budgetNames.forEach(name -> namesToString.append(name).append("\n")); + return namesToString.toString(); + } +} 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 c39321868e3685847d9eb0a920828f81937778e4..938ae9c7b65d105d930f5f8683cd7b9e23da8e47 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 @@ -3,8 +3,6 @@ package no.ntnu.idatt1002.demo.data.Budget; import no.ntnu.idatt1002.demo.data.Economics.*; import java.io.*; -import java.time.LocalDate; -import java.util.ArrayList; /** * FileHandling is a class for writing and reading @@ -12,14 +10,18 @@ import java.util.ArrayList; * * @author andreas */ + public class FileHandlingBudget { - private static final String filePath = "src/main/resources/Budget/"; + private static final String filePath = "src/main/resources/budgets/Budget/"; private static final String fileType = ".budget"; - private static final String budgetPeriod = "budgetPeriod="; + + private static final String path = "src/main/resources/"; + private static final String type = ".register"; 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. @@ -28,29 +30,67 @@ public class FileHandlingBudget { * @param fileTitle the name of the file you want to check * @throws IOException if an input or output exception occurred. */ - public void writeGeneralBudgetToFile(String fileTitle, GeneralBudget generalBudget) throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { + 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))) { bw.write(generalBudget.toString()); } catch (IOException ex) { - throw new IOException("Error writing story to file: " + ex.getMessage()); + ex.printStackTrace(); + throw new IOException("Error writing to file: " + fileTitle); } } /** - * Method for checking if a .register file is empty. + * Method for checking if a .budget file is empty. * * @param fileTitle the name of the file you want to check * @return true or false depending on if file is empty. * @throws IOException if an input or output exception occurred. */ - public boolean isEmpty(String fileTitle) throws IOException { - try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + 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); + return br.readLine() == null; + } + } + + + /** + * Method for checking if a .budget file is new (no 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 + */ + public static boolean isNewBudget(String fileTitle) throws IOException { + try (BufferedReader br = new BufferedReader( + new FileReader(path + 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; - } else { - return false; } } + System.out.println("Is 'old' budget - has max amount"); + return false; + } + + public static void writeMaxAmountToFile(String fileDestination, String maxAmount) throws IOException { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(path + + fileDestination + fileType))) { + bw.write("maxAmount=" + maxAmount); + System.out.println("Max amount is..."); + } catch (IOException ex) { + throw new IOException("Error writing to file: " + fileDestination); + } } /** @@ -60,23 +100,19 @@ public class FileHandlingBudget { * @return the GeneralBudget from the file. * @throws IOException if an input or output exception occurred. */ - public GeneralBudget readGeneralBudgetFromFile(String fileTitle) throws IOException { + public static GeneralBudget readGeneralBudgetFromFile(String fileTitle) throws IOException { GeneralBudget generalBudget = null; - int budgetPeriod = 0; double maxAmount = 0; - ArrayList<BudgetItem> budgetItems = new ArrayList<>(); double budgetAmount = 0; ExpenseCategory expenseCategory = null; String budgetDescription = null; - try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + try (BufferedReader br = new BufferedReader(new FileReader(path + fileTitle + fileType))) { String line; String nextLine = br.readLine(); while ((line = nextLine) != null) { nextLine = br.readLine(); - if(line.startsWith(FileHandlingBudget.budgetPeriod)) { - budgetPeriod = Integer.parseInt(line.replace(FileHandlingBudget.budgetPeriod, "")); - } else if (line.startsWith(FileHandlingBudget.maxAmount)) { + if (line.startsWith(FileHandlingBudget.maxAmount)) { maxAmount = Double.parseDouble(line.replace(FileHandlingBudget.maxAmount,"")); } else if (line.startsWith(FileHandlingBudget.budgetAmount)) { budgetAmount = Double.parseDouble(line.replace(FileHandlingBudget.budgetAmount,"")); @@ -93,7 +129,7 @@ public class FileHandlingBudget { } if (line.isEmpty() || (nextLine == null)) { if(generalBudget == null){ - generalBudget = new GeneralBudget(budgetPeriod,maxAmount); + generalBudget = new GeneralBudget(maxAmount); } else{ generalBudget.addToBudget(budgetAmount,budgetDescription,expenseCategory); } 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 new file mode 100644 index 0000000000000000000000000000000000000000..5d0541c29243483c292592c52595a8fbf282eb55 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetArchive.java @@ -0,0 +1,91 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +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 +//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) +//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 +//set all windows unresizable +//Bytte oversikt på dualList til Monthly .... + +//System.out.println(System.getProperty("user.dir") + path); = +//C:\Users\xulr0\IdeaProjects\skoleProsjekter\idatt1002\idatt1002_2023_9src/main/resources/ + +//(System.getProperty("user.dir") + "/" + path) = +//(path) = +//(src/main/resources) +public class FileHandlingBudgetArchive { + private static final String filePath = "src/main/resources/budgets/"; + private static final String fileType = ".archive"; + + public static void writeBudgetRegisterToArchive(BudgetRegister budgetNames) throws IOException { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + "Archive" + 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 { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + + "Archive" + fileType))) { + return br.readLine() == null; + } + } + public static BudgetRegister readBudgetArchive(String fileTitle) throws IOException { + BudgetRegister budgetRegister = null; + String budgetName; + String line; + + try (BufferedReader br = new BufferedReader( + new FileReader(filePath + "Archive" + fileType))) { + + String nextLine = br.readLine(); + while ((line = nextLine) != null) { + System.out.println(line); + nextLine = br.readLine(); + budgetName = line; + + if (budgetRegister == null) { + budgetRegister = new BudgetRegister(); + } + budgetRegister.addBudgetName(budgetName); + } + } + return budgetRegister; + } + + public static void writeSavingsToFile() { + + } + + 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()); + } + + 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 new file mode 100644 index 0000000000000000000000000000000000000000..067abebbd607d34f83fcf324b0daaf1118a9701e --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingSelectedBudget.java @@ -0,0 +1,79 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public class FileHandlingSelectedBudget { + + private static final String filePath = "src/main/resources/budgets/"; + + 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" + + selectedBudgetFileType))) { + return br.readLine(); + } catch (IOException ioException) { + throw new IOException("File: SelectedBudget.current does not exist", ioException); + } + } + + public static void updateSelectedBudget(String budgetName) throws IOException { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + "SelectedBudget" + + selectedBudgetFileType))) { + bw.write(budgetName); + System.out.println("Current file is: " + 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" + + selectedBudgetFileType))) { + bw.write(""); + System.out.println("Current file is: "); + } catch (IOException ex) { + throw new IOException("Error writing to file: " + "SelectedBudget.current"); + } + } + + public static boolean isSelectedBudgetEmpty(String fileTitle) throws IOException { + try (BufferedReader br = new BufferedReader(new FileReader(filePath + + "SelectedBudget" + selectedBudgetFileType))) { + return br.readLine() == null; + } + } + + public static boolean createBudgetDirectory(String budgetId) { + System.out.println("Directory: " + filePath + budgetId); + File f = new File(filePath + budgetId); + return f.mkdir(); + } + + 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(); + } + + 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(); + } + + 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); + budgetFile.createNewFile(); + } +} diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java index 3a51dc780dc47f3c9c7458a5b050aaa638895a40..c93ec12c05e4e238bfd28980ba9f9558b252bf90 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/GeneralBudget.java @@ -3,15 +3,9 @@ package no.ntnu.idatt1002.demo.data.Budget; import java.util.Arrays; import no.ntnu.idatt1002.demo.data.Economics.ExpenseCategory; -import java.sql.Date; -import java.time.Duration; import java.time.LocalDate; import java.time.Month; -import java.time.ZoneId; -import java.time.temporal.ChronoUnit; -import java.time.temporal.Temporal; import java.util.ArrayList; -import java.util.Calendar; import java.util.List; import java.util.Objects; @@ -22,27 +16,50 @@ import java.util.Objects; */ public class GeneralBudget { - private final int budgetPeriod; + /** + * The period the budget is going to last for. + * Is always the amount of days left in the current month. + */ + private final int budgetPeriod = getDaysLeftOfBudgetPeriod(); + /** + * A List of BudgetItems. + */ private final List<BudgetItem> budgetItems; + /** + * The max amount of the budget. + */ private final double maxAmount; + /** + * The savings of budget. + */ + private final Savings savings; + + + public GeneralBudget(List<BudgetItem> budgetItems, double maxAmount, Savings savings) { + if (maxAmount < 0) { + throw new IllegalArgumentException("The max amount of the budget cant be less than zero"); + } else { + this.maxAmount = maxAmount; + this.budgetItems = budgetItems; + this.savings = savings; + } + } + /** * Class constructor. * - * @param budgetPeriod the period the budget is going to last for. * @param budgetItems a List of BudgetItems. * @param maxAmount the max amount of the budget. * */ - public GeneralBudget(int budgetPeriod, List<BudgetItem> budgetItems, double maxAmount) { - if (budgetPeriod <= 0) { - throw new IllegalArgumentException("The period can´t be under zero days"); - } else if (maxAmount < 0) { + public GeneralBudget(List<BudgetItem> budgetItems, double maxAmount) { + if (maxAmount < 0) { throw new IllegalArgumentException("The max amount of the budget cant be less than zero"); } else { - this.budgetPeriod = budgetPeriod; this.maxAmount = maxAmount; this.budgetItems = budgetItems; + this.savings = new Savings(); } } @@ -50,19 +67,15 @@ public class GeneralBudget { * Class constructor that creates an empty * ArrayList for storing BudgetItems * - * @param budgetPeriod the period the budget is going to last for. * @param maxAmount the max amount of the budget. */ - public GeneralBudget(int budgetPeriod, double maxAmount) { - if (budgetPeriod <= 0) { - throw new IllegalArgumentException("The period can´t be under zero days"); - } + public GeneralBudget(double maxAmount) { if (maxAmount < 0) { throw new IllegalArgumentException("The max amount of the budget cant be less than zero"); } else { - this.budgetPeriod = budgetPeriod; this.maxAmount = maxAmount; this.budgetItems = new ArrayList<>(); + this.savings = new Savings(); } } @@ -95,6 +108,15 @@ public class GeneralBudget { return budgetItems; } + /** + * Method for getting Savings + * + * @return savings of Budget. + */ + public Savings getSavings() { + return savings; + } + /** * Method for getting a Specific BudgetItem * from budgetItems @@ -117,7 +139,7 @@ public class GeneralBudget { * @return the amount of days left in the budget period * */ - public long getDaysLeftOfBudgetPeriod() { + public int getDaysLeftOfBudgetPeriod() { Month thisMonth = LocalDate.now().getMonth(); int dayOfTheMonth = LocalDate.now().getDayOfMonth(); @@ -151,7 +173,7 @@ public class GeneralBudget { * @param category A category from ExpenseCategory */ public void addToBudget(double budgetAmount, String description, ExpenseCategory category) { - if ((totalSum() + budgetAmount) > maxAmount) { + if ((totalSumAndSavings() + budgetAmount) > maxAmount) { throw new IllegalArgumentException("Amount to be added goes over the max value of the budget"); } if (!hasBudgetCategory(category)) { @@ -172,6 +194,17 @@ public class GeneralBudget { return budgetItems.stream().anyMatch(budgetItem -> budgetItem.getBudgetCategory().equals(category)); } + /** + * Method that gets the chosen budget categories. Returns the chosen categories in a list. + + * @return A list of the chosen budget categories. + */ + public List<ExpenseCategory> getChosenBudgetCategories() { + return Arrays.stream(ExpenseCategory.values()).toList(). + stream().filter(this::hasBudgetCategory).toList(); + } + + /** * This method checks if there are unused categories in the budget. @@ -217,6 +250,29 @@ public class GeneralBudget { budgetItems.removeIf(item -> item.getBudgetCategory() == category); } + /** + * Method returns totalSum of budgetItems and totalSum of savings. + * + * @return totalSum of budgetItems and totalSum of savings. + */ + public double totalSumAndSavings() { + return totalSum() + savings.getTotalSavings(); + } + + /** + * Assign an amount to savings. + * The amount plus other assigned amounts cannot be more than the maxAmount. + * + * @param amount the amount you want to assign to savings. + * @throws IllegalArgumentException if amount plus totalSumAndSavings is more than maxAmount + */ + public void addToSavings(double amount) { + if((totalSumAndSavings() + amount) > maxAmount) { + throw new IllegalArgumentException("Amount to be added goes over the max value of the budget"); + } + savings.addToSavings(amount); + } + @Override public String toString() { StringBuilder budgetItemsString = new StringBuilder(); @@ -224,9 +280,9 @@ public class GeneralBudget { budgetItemsString.append(budgetItem+"\n\n"); } if(budgetItemsString.isEmpty()) { - return "budgetPeriod="+getBudgetPeriod()+"\nmaxAmount="+getMaxAmount()+"\n\n"; + return "maxAmount="+getMaxAmount()+"\n\n"; } else { - return "budgetPeriod="+getBudgetPeriod()+"\nmaxAmount="+getMaxAmount()+"\n\n"+budgetItemsString; + return "maxAmount="+getMaxAmount()+"\n\n"+budgetItemsString; } } diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/MMBI.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/MMBI.java new file mode 100644 index 0000000000000000000000000000000000000000..291d1651df7edc005f7d6b99bf8def575b3072d0 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/MMBI.java @@ -0,0 +1,30 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import javafx.scene.control.ProgressBar; + +public class MMBI { + private ProgressBar progressBar; + private BudgetItem budgetItem; + + public MMBI(BudgetItem item, ProgressBar bar){ + this.budgetItem = item; + this.progressBar = bar; + + } + + public BudgetItem getBudgetItem(){ + return budgetItem; + } + + public void setBudgetItem(BudgetItem item){ + this.budgetItem = item; + } + public ProgressBar getBar(){ + return progressBar; + } + + public void setProgressBar(ProgressBar bar){ + this.progressBar = bar; + } + +} diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/Savings.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/Savings.java new file mode 100644 index 0000000000000000000000000000000000000000..2bd4d4762f390161139456280fc8933b7b66c9d3 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/Savings.java @@ -0,0 +1,187 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import java.util.ArrayList; +import java.util.List; + +/** + * Savings is a class that has an amount + * that is given to it, which can further can be + * given to different savingsGoals. + */ +public class Savings { + /** + * List of SavingsGoals + */ + private final List<SavingsGoal> savingsGoals; + /** + * An amount not used on any SavingsGoal. + */ + private double amount; + + /** + * Class constructor that sets + * savingsGoals to an empty ArrayList and + * amount to zero. + */ + public Savings() { + this.savingsGoals = new ArrayList<>(); + this.amount = 0; + } + + /** + * Class constructor that sets + * savingsGoals to an empty ArrayList and + * amount to a given double. + * + * @param amount the double you want to assign amount + */ + public Savings(double amount) { + this.savingsGoals = new ArrayList<>(); + this.amount = amount; + } + + /** + * Class constructor that sets + * savingsGoals to a given ArrayList and + * amount to zero. + * + * @param savingsGoals the ArrayList you want to assign savingsGoals + */ + public Savings(ArrayList<SavingsGoal> savingsGoals) { + this.savingsGoals = savingsGoals; + this.amount = 0; + } + + /** + * Class constructor that sets + * savingsGoals to a given ArrayList and + * amount to a given double. + * + * @param savingsGoals the ArrayList you want to assign savingsGoals + * @param amount + */ + public Savings(ArrayList<SavingsGoal> savingsGoals, double amount) { + this.savingsGoals = savingsGoals; + this.amount = amount; + } + + /** + * Get List of SavingsGoals. + * + * @return List of SavingsGoals + */ + public List<SavingsGoal> getSavingsGoals() { + return savingsGoals; + } + + /** + * Get the amount. + * + * @return savings amount + */ + public double getAmount() { + return amount; + } + + /** + * Get the total amount invested into SavingsGoals + * and the amount that is unused. + * + * @return amount invested into SavingsGoals and amount not used. + */ + public double getTotalSavings() { + double totalSavings = 0; + for(SavingsGoal savingsGoal : savingsGoals) { + totalSavings += savingsGoal.getAmountInvested(); + } + totalSavings += getAmount(); + return totalSavings; + } + + /** + * Get a specific SavingsGoal from + * savingsGoals + * + * @param savingsGoal the SavingsGoal you want to get + * @throws IllegalArgumentException if the SavingsGoal is not in the List + * @return the SavingsGoal you wanted to find if it exists + */ + public SavingsGoal getSavingsGoal(SavingsGoal savingsGoal) { + for(SavingsGoal aSavingsGoal : savingsGoals) { + if(savingsGoal == aSavingsGoal) { + return aSavingsGoal; + } + } + throw new IllegalArgumentException("The SavingsGoal is not in the List"); + } + + /** + * Method to check if savingsGoals + * contains a specific SavingsGoal + * + * @param savingsGoal the SavingsGoal you want to check. + * @return boolean depending on if savingsGoals contains the savingsGoal. + */ + public boolean hasSavingsGoal(SavingsGoal savingsGoal) { + return savingsGoals.contains(savingsGoal); + } + + /** + * A List of all SavingsGoal that are achieved. + * A SavingsGoal is achieved if its amount is zero. + * + * @return List of achieved SavingsGoal + */ + public List<SavingsGoal> getAchievedSavingsGoal() { + List<SavingsGoal> achievedSavingsGoals = new ArrayList<>(); + for(SavingsGoal aSavingsGoal : savingsGoals) { + if(aSavingsGoal.isAchieved()) { + achievedSavingsGoals.add(aSavingsGoal); + } + } + return achievedSavingsGoals; + } + + /** + * Method for adding an amount to a + * SavingsGoal. + * + * @param amount the amount you want to add + * @param savingsGoal the SavingsGoal you want to add to + * @throws IllegalArgumentException if the amount is higher than the Savings amount. + * @throws IllegalArgumentException if SavingsGoal is not in savingsGoal. + */ + public void addToSavingsGoal(int amount, SavingsGoal savingsGoal) { + if(amount > this.amount) { + throw new IllegalArgumentException("The amount cannot be higher than the Savings amount"); + } + if(!hasSavingsGoal(savingsGoal)) { + throw new IllegalArgumentException("The SavingsGoal is not in savingsGoals"); + } + getSavingsGoal(savingsGoal).addAmountInvested(amount); + this.amount -= amount; + } + + /** + * Add an amount to Savings + * + * @param amount the amount you want to add. + */ + public void addToSavings(double amount) { + this.amount += amount; + } + + /** + * Add a SavingsGoal to Savings. + * + * @param savingsGoal the SavingsGoal you want to add. + * @throws IllegalArgumentException if the SavingsGoal already exists in the Savings. + */ + public void addSavingsGoal(SavingsGoal savingsGoal) { + if(savingsGoals.contains(savingsGoal)) { + throw new IllegalArgumentException("SavingsGoal already in Savings"); + } else { + savingsGoals.add(savingsGoal); + } + } +} \ No newline at end of file diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/Budget/SavingsGoal.java b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/SavingsGoal.java new file mode 100644 index 0000000000000000000000000000000000000000..ce7fd18e9b14a26f959324211d58daeffe987324 --- /dev/null +++ b/src/main/java/no/ntnu/idatt1002/demo/data/Budget/SavingsGoal.java @@ -0,0 +1,129 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +/** + * SavingsGoal is a specific goal that you are + * saving towards, for example a car or holiday. + */ +public class SavingsGoal { + /** + * A description of what the SavingsGoal is for. + */ + private String description; + /** + * The monetary amount invested into the SavingsGoal + */ + private double amountInvested; + + /** + * The monetary amount needed to achieve the SavingsGoal + */ + private double amountGoal; + + /** + * Boolean to check if the SavingsGoal has been achieved. + * SavingsGoal has been achieved when amount is zero. + */ + private boolean achieved = false; + + /** + * The class constructor for a SavingsGoal. + * + * @param description a String the explains what the SavingsGoal is for. + * @param amountInvested the monetary amount invested into the SavingsGoal. + * @param amountGoal the monetary amount needed to achieve the SavingsGoal. + */ + public SavingsGoal(String description, double amountInvested, double amountGoal) throws IllegalArgumentException{ + this.description = description; + if(amountGoal < 0) { + amountGoal = 0; + } + if(amountInvested < 0) { + amountInvested = 0; + } + this.amountGoal = amountGoal; + this.amountInvested = amountInvested; + achieved = amountInvested >= amountGoal; + + } + + /** + * The class constructor for a SavingsGoal, + * amountInvested is set to zero. + * + * @param description a String the explains what the SavingsGoal is for. + * @param amountGoal the monetary amount needed to achieve the SavingsGoal. + */ + public SavingsGoal(String description, double amountGoal) { + this.description = description; + if(amountGoal < 0) { + amountGoal = 0; + } + this.amountGoal = amountGoal; + this.amountInvested = 0; + } + /** + * Getting the description of the SavingsGoal + * @return the SavingsGoal´s description. + */ + public String getDescription() { + return description; + } + + /** + * Getting the amount needed to achieve the SavingsGoal + * @return the SavingsGoal´s needed amount. + */ + public double getAmountGoal() { + return amountGoal; + } + + /** + * Getting the amount invested into the SavingsGoal. + * @return the SavingsGoal´s amount invested. + */ + public double getAmountInvested() { + return amountInvested; + } + + /** + * Check if the SavingsGoal is achieved. + * + * @return boolean + */ + public boolean isAchieved() { + return achieved; + } + /** + * Setting the description of the SavingsGoal. + * + * @param description the new description you want to use. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Setting the amountGoal of the SavingsGoal. + * + * @param amount the new amount you want to use. + */ + public void setAmountGoal(double amount) throws IllegalArgumentException{ + if(amount < 0) { + this.amountGoal = 0; + } else { + this.amountGoal = amount; + } + achieved = amountInvested >= amountGoal; + + } + + /** + * Adding an amount to the amountInvested of the SavingsGoal. + * + * @param amount the amount you want to add. + */ + public void addAmountInvested(double amount) throws IllegalArgumentException{ + this.amountInvested += amount; + achieved = amountInvested >= amountGoal; + } +} 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 e678543fe5e25634aba1d67c029114c1b5633350..27a470035bb9749c496cb704cf5b4689b8826b80 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 @@ -5,6 +5,8 @@ import java.io.FileWriter; import java.io.IOException; import java.io.*; import java.time.LocalDate; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingBudget; +import no.ntnu.idatt1002.demo.data.Budget.FileHandlingSelectedBudget; /** @@ -14,7 +16,9 @@ import java.time.LocalDate; * @author andreas */ public class FileHandling{ - private static final String filePath = "src/main/resources/Economics/"; + private static final String filePath = "src/main/resources/budgets/Economics/"; + + private static final String path = "src/main/resources/"; private static final String fileType = ".register"; private static final String date = "date="; private static final String description = "description="; @@ -29,8 +33,9 @@ public class FileHandling{ * @param fileTitle the name of the file you want to check * @throws IOException if an input or output exception occurred. */ - public <T extends Item>void writeItemRegisterToFile(final ItemRegister<T> itemRegister, String fileTitle) throws IOException { - try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + fileTitle + fileType))) { + 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))) { if (itemRegister.isEmpty()){ bw.write(""); } else{ @@ -48,13 +53,16 @@ public class FileHandling{ * @return true or false depending on if file is empty. * @throws IOException if an input or output exception occurred. */ - public boolean isEmpty(String fileTitle) throws IOException { - try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + 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))) { + return br.readLine() == null; } } @@ -65,14 +73,15 @@ public class FileHandling{ * @return the IncomeRegister from the file. * @throws IOException if an input or output exception occurred. */ - public IncomeRegister readIncomeRegisterFromFile(String fileTitle) throws IOException { + public static IncomeRegister readIncomeRegisterFromFile(String fileTitle) throws IOException { IncomeRegister incomeRegister = new IncomeRegister(); LocalDate date = null; String description = ""; double amount = 0; boolean reoccuring = false; IncomeCategory incomeCategory = null; - try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + 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) { @@ -112,14 +121,15 @@ public class FileHandling{ * @return the ExpenseRegister from the file. * @throws IOException if an input or output exception occurred */ - public ExpenseRegister readExpenseRegisterFromFile(String fileTitle) throws IOException { + public static ExpenseRegister readExpenseRegisterFromFile(String fileTitle) throws IOException { ExpenseRegister expenseRegister = new ExpenseRegister(); LocalDate date = null; String description = ""; double amount = 0; boolean reoccuring = false; ExpenseCategory expenseCategory = null; - try (BufferedReader br = new BufferedReader(new FileReader(filePath + fileTitle + fileType))) { + 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) { diff --git a/src/main/resources/Economics/Expense.register b/src/main/resources/Economics/Expense.register deleted file mode 100644 index 6435f9469d30071fc836f95e7337b9dd542af9a1..0000000000000000000000000000000000000000 --- a/src/main/resources/Economics/Expense.register +++ /dev/null @@ -1,17 +0,0 @@ -date=2023-03-01 -description=twelve -amount=12.0 -isRecurring=Not recurring -category=CLOTHES - -date=2023-03-26 -amount=200.0 -isRecurring=Not recurring -category=FOOD - -date=2023-04-15 -description=iphone -amount=5000.0 -isRecurring=Not recurring -category=OTHER - diff --git a/src/main/resources/Economics/Income.register b/src/main/resources/Economics/Income.register deleted file mode 100644 index 51f3e3d3818ae28ec3300f8405b47cf4b908714e..0000000000000000000000000000000000000000 --- a/src/main/resources/Economics/Income.register +++ /dev/null @@ -1,11 +0,0 @@ -date=2023-03-24 -description=studie -amount=900.0 -isRecurring=Recurring -category=STUDENT_LOAN - -date=2023-03-25 -amount=100.0 -isRecurring=Not recurring -category=GIFT - diff --git a/src/main/resources/budgets/Archive.archive b/src/main/resources/budgets/Archive.archive new file mode 100644 index 0000000000000000000000000000000000000000..6153ed3d338e91cf74a2d4fbd9c43efd5806fd14 --- /dev/null +++ b/src/main/resources/budgets/Archive.archive @@ -0,0 +1 @@ +APRIL10 diff --git a/src/main/resources/budgets/SelectedBudget.current b/src/main/resources/budgets/SelectedBudget.current new file mode 100644 index 0000000000000000000000000000000000000000..89aaa4c33b69ff7fceed4dfaf0584aecd2bf03e6 --- /dev/null +++ b/src/main/resources/budgets/SelectedBudget.current @@ -0,0 +1 @@ +APRIL10 \ No newline at end of file diff --git a/src/main/resources/Budget/Budget.budget b/src/main/resources/testFiles/budget/Budget.budget similarity index 79% rename from src/main/resources/Budget/Budget.budget rename to src/main/resources/testFiles/budget/Budget.budget index a1737fc130bfe60600356758782f254944a1a8bb..90af344a39271dc60b1f06435ee7b821ffd6d293 100644 --- a/src/main/resources/Budget/Budget.budget +++ b/src/main/resources/testFiles/budget/Budget.budget @@ -1,11 +1,10 @@ -budgetPeriod=31 maxAmount=1000.0 -budgetAmount=500.0 +budgetAmount=100.0 budgetCategory=FOOD -budgetDescription=dd +budgetDescription= -budgetAmount=100.0 +budgetAmount=0.0 budgetCategory=CLOTHES budgetDescription= diff --git a/src/main/resources/Budget/multipleBudgetItem.budget b/src/main/resources/testFiles/budget/multipleBudgetItem.budget similarity index 94% rename from src/main/resources/Budget/multipleBudgetItem.budget rename to src/main/resources/testFiles/budget/multipleBudgetItem.budget index 99d8a34c324f73c0614113790af7db0fb7d74029..e9b47dc3b06a7b0578dad65f0258038547a5cb7e 100644 --- a/src/main/resources/Budget/multipleBudgetItem.budget +++ b/src/main/resources/testFiles/budget/multipleBudgetItem.budget @@ -1,4 +1,3 @@ -budgetPeriod=12 maxAmount=1200.0 budgetAmount=500.0 diff --git a/src/main/resources/Budget/oneBudgetItemTest.budget b/src/main/resources/testFiles/budget/oneBudgetItemTest.budget similarity index 84% rename from src/main/resources/Budget/oneBudgetItemTest.budget rename to src/main/resources/testFiles/budget/oneBudgetItemTest.budget index eaa80cf9eafc900e3419078665bc59ed14bc25a2..38cd0809427987b409e882b9dff300aeb502ab20 100644 --- a/src/main/resources/Budget/oneBudgetItemTest.budget +++ b/src/main/resources/testFiles/budget/oneBudgetItemTest.budget @@ -1,4 +1,3 @@ -budgetPeriod=12 maxAmount=1200.0 budgetAmount=500.0 diff --git a/src/main/resources/testFiles/economics/Expense.register b/src/main/resources/testFiles/economics/Expense.register new file mode 100644 index 0000000000000000000000000000000000000000..0efd78caeea2b8fecc15f91802067ca349d32534 --- /dev/null +++ b/src/main/resources/testFiles/economics/Expense.register @@ -0,0 +1,5 @@ +date=2023-04-18 +amount=5.0 +isRecurring=Not recurring +category=FOOD + diff --git a/src/main/resources/testFiles/economics/Income.register b/src/main/resources/testFiles/economics/Income.register new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/resources/Economics/expenseRegisterTest.register b/src/main/resources/testFiles/economics/expenseRegisterTest.register similarity index 100% rename from src/main/resources/Economics/expenseRegisterTest.register rename to src/main/resources/testFiles/economics/expenseRegisterTest.register diff --git a/src/main/resources/testFiles/economics/incomeRegisterTest.register b/src/main/resources/testFiles/economics/incomeRegisterTest.register new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/resources/view/AddBudget.fxml b/src/main/resources/view/AddBudget.fxml deleted file mode 100644 index e2f1e248b7e200a5a99bce06650ecb46f6f93761..0000000000000000000000000000000000000000 --- a/src/main/resources/view/AddBudget.fxml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.ComboBox?> -<?import javafx.scene.control.Label?> -<?import javafx.scene.control.TextField?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Text?> - -<AnchorPane prefHeight="150.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.AddBudgetController"> - <children> - <GridPane prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> - <columnConstraints> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="10.0" minWidth="0.0" prefWidth="0.0" /> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="180.0" minWidth="10.0" prefWidth="150.0" /> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="180.0" minWidth="10.0" prefWidth="150.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" maxWidth="10.0" minWidth="10.0" prefWidth="0.0" /> - </columnConstraints> - <rowConstraints> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - </rowConstraints> - <children> - <VBox alignment="CENTER" GridPane.columnIndex="1" GridPane.valignment="CENTER"> - <children> - <Label text="Category/Title" /> - <ComboBox fx:id="categoryVariable" maxWidth="150.0" prefWidth="150.0" /> - </children> - </VBox> - <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="2"> - <children> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Amount" /> - <TextField fx:id="amountVariable" maxWidth="150.0" /> - </children> - </VBox> - <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="3"> - <children> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Description" /> - <TextField fx:id="descriptionVariable" /> - </children> - </VBox> - <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="15.0" GridPane.columnIndex="3" GridPane.rowIndex="1"> - <children> - <Button fx:id="cancelButton" mnemonicParsing="false" onAction="#closeButton" text="Cancel" /> - <Button fx:id="okBtn" mnemonicParsing="false" onAction="#pressOkBtn" prefWidth="57.0" text="OK" /> - </children> - </HBox> - </children> - </GridPane> - </children> -</AnchorPane> diff --git a/src/main/resources/view/Budget.fxml b/src/main/resources/view/Budget.fxml deleted file mode 100644 index 9b1f0cf23ba191c8a0b4dc9d0f92d13a64b50b07..0000000000000000000000000000000000000000 --- a/src/main/resources/view/Budget.fxml +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.TableColumn?> -<?import javafx.scene.control.TableView?> -<?import javafx.scene.control.TextArea?> -<?import javafx.scene.image.Image?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.FlowPane?> -<?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?> - -<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.BudgetController"> - <children> - <ImageView fitHeight="468.0" fitWidth="600.0" pickOnBounds="true"> - <image> - <Image url="@../Images/backgroundMini.jpg" /> - </image> - </ImageView> - <GridPane prefHeight="468.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> - <columnConstraints> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - </columnConstraints> - <rowConstraints> - <RowConstraints maxHeight="397.0" minHeight="10.0" prefHeight="61.0" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="397.0" minHeight="10.0" prefHeight="41.0" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="397.0" minHeight="10.0" prefHeight="296.0" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="152.0" minHeight="10.0" prefHeight="79.0" vgrow="SOMETIMES" /> - </rowConstraints> - <children> - <HBox alignment="TOP_CENTER" prefHeight="98.0" prefWidth="600.0" spacing="40.0" GridPane.rowIndex="3"> - <children> - <Button fx:id="addBudget" minHeight="60.0" minWidth="100.0" mnemonicParsing="false" onAction="#handleEditButton" prefWidth="100.0" text="Add" /> - <Button fx:id="editBudget" minHeight="60.0" minWidth="100.0" mnemonicParsing="false" onAction="#handleEditButton" prefWidth="100.0" text="Edit" /> - <Button fx:id="deleteBudget" minHeight="60.0" minWidth="100.0" mnemonicParsing="false" onAction="#handleDeleteBtn" prefWidth="100.0" text="Delete" /> - <Button minHeight="60.0" minWidth="100.0" mnemonicParsing="false" prefWidth="100.0" text="Save/Back" /> - </children> - </HBox> - <FlowPane alignment="CENTER" columnHalignment="CENTER" prefHeight="200.0" prefWidth="200.0" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER"> - <children> - <TableView fx:id="budgetTableView" prefHeight="260.0" prefWidth="540.0"> - <columns> - <TableColumn fx:id="categoryColumn" prefWidth="75.0" text="Category/Title" /> - <TableColumn fx:id="percentageColumn" prefWidth="75.0" text="Percentage" /> - <TableColumn fx:id="amountColumn" prefWidth="75.0" text="Amount" /> - <TableColumn fx:id="descriptionColumn" prefWidth="75.0" text="Description" /> - </columns> - <columnResizePolicy> - <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> - </columnResizePolicy> - </TableView> - </children> - </FlowPane> - <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0"> - <children> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Budget"> - <font> - <Font size="48.0" /> - </font> - </Text> - </children> - </HBox> - <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="1"> - <children> - <TextArea fx:id="monthVariable" prefHeight="20.0" prefWidth="180.0" text="Month" /> - <TextArea fx:id="daysVariable" prefHeight="20.0" prefWidth="180.0" text="Days" /> - <TextArea fx:id="totalBudgetAmount" prefHeight="20.0" prefWidth="180.0" text="Amount" /> - </children> - </HBox> - </children> - </GridPane> - </children> -</AnchorPane> diff --git a/src/main/resources/view/BudgetNew.fxml b/src/main/resources/view/BudgetNew.fxml deleted file mode 100644 index c92fd969abd3faa625d300dd7bc2104fedb61cad..0000000000000000000000000000000000000000 --- a/src/main/resources/view/BudgetNew.fxml +++ /dev/null @@ -1,188 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.Cursor?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.ComboBox?> -<?import javafx.scene.control.TableColumn?> -<?import javafx.scene.control.TableView?> -<?import javafx.scene.image.Image?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.BorderPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.StackPane?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.shape.Rectangle?> -<?import javafx.scene.text.Font?> -<?import javafx.scene.text.Text?> - -<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.BudgetController"> - <children> - <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> - <image> - <Image url="@../Images/backgroundMini.jpg" /> - </image> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - </ImageView> - <BorderPane prefHeight="400.0" prefWidth="600.0"> - <top> - <HBox BorderPane.alignment="CENTER"> - <children> - <Button fx:id="returnBtn" mnemonicParsing="false" onAction="#switchScene" text="Return "> - <opaqueInsets> - <Insets left="100.0" /> - </opaqueInsets> - <HBox.margin> - <Insets left="10.0" top="10.0" /> - </HBox.margin> - </Button> - <Region prefHeight="70.0" prefWidth="141.0" /> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Budget" textAlignment="CENTER" wrappingWidth="174.6796875"> - <HBox.margin> - <Insets /> - </HBox.margin> - <font> - <Font size="48.0" /> - </font> - </Text> - </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> - </HBox> - </top> - <center> - <GridPane BorderPane.alignment="CENTER"> - <BorderPane.margin> - <Insets bottom="40.0" left="40.0" right="40.0" /> - </BorderPane.margin> - <columnConstraints> - <ColumnConstraints hgrow="ALWAYS" maxWidth="485.3333231608073" minWidth="10.0" prefWidth="427.33335367838544" /> - <ColumnConstraints hgrow="ALWAYS" maxWidth="111.33333333333331" minWidth="10.0" prefWidth="92.66664632161456" /> - </columnConstraints> - <rowConstraints> - <RowConstraints maxHeight="65.33334064483643" minHeight="10.0" prefHeight="65.33334064483643" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="214.00004069010413" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="29.999959309895814" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - </rowConstraints> - <children> - <HBox alignment="BOTTOM_LEFT" prefWidth="410.0" spacing="5.0"> - <children> - <Button fx:id="addBudget" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleAddButton" text="Add" textAlignment="CENTER"> - <graphic> - <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/add_image.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="editBudget" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleEditButton" text="Edit" textAlignment="CENTER"> - <graphic> - <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/edit.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="deleteBtn" alignment="TOP_CENTER" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete" textAlignment="CENTER"> - <graphic> - <ImageView fitHeight="19.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/delete.png" /> - </image> - </ImageView> - </graphic> - </Button> - </children> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <padding> - <Insets bottom="5.0" /> - </padding> - </HBox> - <VBox alignment="BOTTOM_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1"> - <children> - <ComboBox fx:id="show" prefWidth="150.0" promptText="Show "> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <VBox.margin> - <Insets bottom="5.0" /> - </VBox.margin> - </ComboBox> - </children> - </VBox> - <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="3"> - <children> - <Button fx:id="incomeBtn" mnemonicParsing="false" onAction="#switchScene" text="Income" /> - <Button fx:id="budgetBtn" disable="true" mnemonicParsing="false" onAction="#switchScene" text="Budget" /> - <Button fx:id="expenseBtn" mnemonicParsing="false" onAction="#switchScene" text="Expenses" /> - <Button fx:id="nextBtn" mnemonicParsing="false" onAction="#switchScene" text="Next"> - <HBox.margin> - <Insets left="170.0" /> - </HBox.margin> - </Button> - </children> - <padding> - <Insets top="10.0" /> - </padding> - </HBox> - <TableView fx:id="budgetTableView" prefHeight="260.0" prefWidth="485.0" GridPane.columnSpan="2" GridPane.rowIndex="1"> - <columns> - <TableColumn fx:id="categoryColumn" prefWidth="75.0" text="Category/Title" /> - <TableColumn fx:id="amountColumn" prefWidth="75.0" text="Amount" /> - <TableColumn fx:id="percentageColumn" prefWidth="75.0" text="Percentage" /> - <TableColumn fx:id="descriptionColumn" prefWidth="75.0" text="Description" /> - </columns> - <columnResizePolicy> - <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> - </columnResizePolicy> - </TableView> - <StackPane GridPane.rowIndex="2"> - <children> - <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="209.0" StackPane.alignment="CENTER_LEFT" /> - <HBox prefHeight="18.0" prefWidth="517.0"> - <children> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Sum: "> - <HBox.margin> - <Insets left="2.0" /> - </HBox.margin> - </Text> - <Region prefHeight="18.0" prefWidth="101.0" /> - <Text fx:id="sum" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" /> - </children> - </HBox> - </children> - </StackPane> - </children> - </GridPane> - </center> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> - <left> - <Region prefHeight="330.0" prefWidth="1.0" BorderPane.alignment="CENTER" /> - </left> - <right> - <Region prefHeight="357.0" prefWidth="0.0" BorderPane.alignment="CENTER" /> - </right> - <bottom> - <Region prefHeight="0.0" prefWidth="600.0" BorderPane.alignment="CENTER" /> - </bottom> - </BorderPane> - </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> -</AnchorPane> diff --git a/src/main/resources/view/BudgetNewest.fxml b/src/main/resources/view/BudgetNewest.fxml index 4999c3a596dddcbf7794d029d43408e6b97985ce..3f679d03dd86c097a26781265092206a4ebebd97 100644 --- a/src/main/resources/view/BudgetNewest.fxml +++ b/src/main/resources/view/BudgetNewest.fxml @@ -51,7 +51,7 @@ <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"> + <Button fx:id="returnToMainMenuBtn" alignment="CENTER" layoutX="-2.0" layoutY="58.0" mnemonicParsing="false" onAction="#switchScene" text="Return to Main Menu"> <font> <Font name="Lucida Console" size="14.0" /> </font> @@ -72,11 +72,11 @@ </BorderPane> <BorderPane prefHeight="64.0" prefWidth="1100.0"> <left> - <HBox prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER"> + <HBox prefHeight="64.0" prefWidth="326.0" spacing="10.0" BorderPane.alignment="CENTER"> <children> - <Button fx:id="addBtn" mnemonicParsing="false" onAction="#handleAddBtn" prefHeight="25.0" prefWidth="60.0"> + <Button fx:id="addBtn" mnemonicParsing="false" onAction="#handleAddBtn" prefHeight="25.0" prefWidth="60.0" text="Add"> <font> - <Font name="Lucida Console" size="12.0" /> + <Font name="Lucida Console" size="14.0" /> </font> <graphic> <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> @@ -86,9 +86,9 @@ </ImageView> </graphic> </Button> - <Button fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="25.0" prefWidth="60.0"> + <Button fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="39.0" prefWidth="91.0" text="Edit"> <font> - <Font name="Lucida Console" size="12.0" /> + <Font name="Lucida Console" size="14.0" /> </font> <graphic> <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> @@ -98,9 +98,9 @@ </ImageView> </graphic> </Button> - <Button fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="25.0" prefWidth="60.0"> + <Button fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="39.0" prefWidth="119.0" text="Delete"> <font> - <Font name="Lucida Console" size="12.0" /> + <Font name="Lucida Console" size="14.0" /> </font> <graphic> <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> @@ -177,6 +177,12 @@ <Insets top="10.0" /> </VBox.margin> </TableView> + <HBox alignment="TOP_RIGHT"> + <children> + <Button fx:id="backBtn" mnemonicParsing="false" text="back" /> + <Button fx:id="continueBtn" mnemonicParsing="false" text="continue" /> + </children> + </HBox> </children> <GridPane.margin> <Insets top="30.0" /> diff --git a/src/main/resources/view/CreateBudget.fxml b/src/main/resources/view/CreateBudget.fxml new file mode 100644 index 0000000000000000000000000000000000000000..6d9dafaa20e5693e3e1c471c8b69d3f9f6ace3b1 --- /dev/null +++ b/src/main/resources/view/CreateBudget.fxml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?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.Pane?> +<?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> +<?import javafx.scene.text.Text?> + +<DialogPane prefHeight="113.0" prefWidth="327.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.CreateBudgetController"> + <content> + <VBox> + <children> + <GridPane> + <columnConstraints> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> + <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> + </columnConstraints> + <rowConstraints> + <RowConstraints /> + <RowConstraints maxHeight="20.0" minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="20.0" minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" /> + </rowConstraints> + <children> + <TextField fx:id="nameField" promptText="Name" GridPane.columnIndex="1" GridPane.rowIndex="1" /> + <Label text="Name: " GridPane.rowIndex="1" /> + </children> + </GridPane> + <Label fx:id="errorMsg" alignment="CENTER_RIGHT" opacity="0.0" prefHeight="315.0" prefWidth="315.0" text="Please fill in the name field" textAlignment="CENTER" textFill="RED" /> + <HBox alignment="CENTER_RIGHT" prefHeight="100.0" prefWidth="200.0" spacing="5.0"> + <children> + <Button fx:id="cancelBtn" mnemonicParsing="false" onAction="#pressCancelBtn" prefWidth="70.0" text="Cancel" /> + <Button fx:id="okBtn" mnemonicParsing="false" onAction="#pressOkBtn" prefWidth="70.0" text="OK" /> + </children> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </HBox> + </children> + </VBox> + </content> + <header> + <Pane prefHeight="40.0"> + <children> + <Text layoutX="12.0" layoutY="25.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Please type the name of your budget"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font></Text> + </children> + </Pane> + </header> +</DialogPane> diff --git a/src/main/resources/view/Income.fxml b/src/main/resources/view/Income.fxml deleted file mode 100644 index 448891dd52fde135d1290f6d96d78f1276e55ecc..0000000000000000000000000000000000000000 --- a/src/main/resources/view/Income.fxml +++ /dev/null @@ -1,257 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?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?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.BorderPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Pane?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> -<?import javafx.scene.text.Text?> - -<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="695.0" fitWidth="1130.0" pickOnBounds="true"> - <image> - <Image url="@../Images/backgroundMini.jpg" /> - </image> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - </ImageView> - <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 name="Lucida Console" size="48.0" /> - </font> - </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> - <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="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/add.png" /> - </image> - </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" /> - </BorderPane.margin> - </HBox> - </left> - <right> - <Pane BorderPane.alignment="CENTER"> - <children> - <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> - </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> - <Pane GridPane.columnIndex="1" GridPane.rowIndex="1"> - <children> - <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> - </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> - <Text layoutY="14.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Expenses" textAlignment="CENTER"> - <font> - <Font name="Lucida Console" size="14.0" /> - </font> - </Text> - </children> - </Pane> - </children> - <padding> - <Insets left="10.0" /> - </padding> - <VBox.margin> - <Insets left="30.0" right="30.0" /> - </VBox.margin> - </GridPane> - </children> - </VBox> - </children> -</AnchorPane> diff --git a/src/main/resources/view/IncomeAndExpenses.fxml b/src/main/resources/view/IncomeAndExpenses.fxml index ace8dac9bd98a83179a74ed731f6620441287a4e..c69b39775cb263add4bf62c2571d77f016ddbae1 100644 --- a/src/main/resources/view/IncomeAndExpenses.fxml +++ b/src/main/resources/view/IncomeAndExpenses.fxml @@ -10,7 +10,6 @@ <?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?> @@ -54,11 +53,12 @@ <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"> + <Button fx:id="returnToMainMenuBtn" alignment="CENTER" layoutX="-2.0" layoutY="58.0" mnemonicParsing="false" onAction="#switchScene" text="Return to Main Menu"> <font> <Font name="Lucida Console" size="14.0" /> </font> </Button> + <Button fx:id="returnBtn" disable="true" layoutX="136.0" layoutY="117.0" mnemonicParsing="false" opacity="0.0" text="Button" /> </children> </Pane> </left> @@ -80,9 +80,9 @@ </BorderPane> <BorderPane prefHeight="64.0" prefWidth="1100.0"> <left> - <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="10.0" BorderPane.alignment="CENTER"> + <HBox alignment="CENTER_LEFT" prefHeight="64.0" prefWidth="261.0" spacing="10.0" BorderPane.alignment="CENTER"> <children> - <MenuButton mnemonicParsing="false" prefHeight="25.0" prefWidth="50.0"> + <MenuButton mnemonicParsing="false" prefHeight="38.0" prefWidth="101.0" text="ADD"> <items> <MenuItem fx:id="addIncome" mnemonicParsing="false" onAction="#handleAddBtn" text="Income" /> <MenuItem fx:id="addExpense" mnemonicParsing="false" onAction="#handleAddBtn" text="Expense" /> @@ -94,8 +94,11 @@ </image> </ImageView> </graphic> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> </MenuButton> - <Button mnemonicParsing="false" text="popup explaining how to edit/delete" /> + <Button mnemonicParsing="false" /> </children> <BorderPane.margin> <Insets left="30.0" /> @@ -103,11 +106,7 @@ </HBox> </left> <right> - <Pane BorderPane.alignment="CENTER"> - <children> - <ProgressBar fx:id="budgetProgress" prefWidth="200.0" progress="0.0" /> - </children> - </Pane> + <Pane BorderPane.alignment="CENTER" /> </right> <opaqueInsets> <Insets /> @@ -118,7 +117,7 @@ <center> <Pane BorderPane.alignment="CENTER"> <children> - <ComboBox fx:id="filter" layoutX="135.0" layoutY="25.0" prefWidth="150.0" promptText="Show"> + <ComboBox fx:id="filter" layoutX="74.0" layoutY="19.0" prefWidth="150.0" promptText="Show"> <opaqueInsets> <Insets /> </opaqueInsets> @@ -209,11 +208,6 @@ </ContextMenu> </contextMenu> </TableView> - <Label fx:id="expSum" text="Sum: "> - <font> - <Font name="Lucida Console" size="12.0" /> - </font> - </Label> </children> </VBox> <Pane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2"> @@ -223,6 +217,11 @@ <Font name="Lucida Console" size="14.0" /> </font> </Text> + <Label fx:id="expSum" layoutX="79.0" layoutY="2.0" text="Sum: "> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Label> </children> </Pane> </children> diff --git a/src/main/resources/view/MainMenu.fxml b/src/main/resources/view/MainMenu.fxml deleted file mode 100644 index a2b96f232db3d473ddd7d56e635705c3270bc70f..0000000000000000000000000000000000000000 --- a/src/main/resources/view/MainMenu.fxml +++ /dev/null @@ -1,164 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.Cursor?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.DatePicker?> -<?import javafx.scene.control.Label?> -<?import javafx.scene.control.ProgressBar?> -<?import javafx.scene.image.Image?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.BorderPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.StackPane?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> -<?import javafx.scene.text.Text?> - -<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.MainMenuController"> - <children> - <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/backgroundMini.jpg" /> - </image> - </ImageView> - <BorderPane prefHeight="400.0" prefWidth="600.0" AnchorPane.topAnchor="0.0"> - <center> - <GridPane prefWidth="574.0" BorderPane.alignment="CENTER"> - <columnConstraints> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - </columnConstraints> - <rowConstraints> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - </rowConstraints> - <children> - <VBox alignment="BOTTOM_RIGHT" GridPane.columnSpan="2"> - <children> - <DatePicker fx:id="date" /> - <VBox alignment="BOTTOM_CENTER" prefHeight="67.0" prefWidth="574.0"> - <children> - <Label fx:id="balanceLbl" text="Balance:" textAlignment="CENTER"> - <font> - <Font name="System Bold" size="24.0" /> - </font> - </Label> - </children> - <padding> - <Insets bottom="-20.0" /> - </padding> - </VBox> - </children> - </VBox> - <StackPane GridPane.columnSpan="2" GridPane.rowIndex="1"> - <children> - <ImageView fx:id="progressMarker" fitHeight="20.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" rotate="-90.0" translateX="-150.0" translateY="25.0"> - <image> - <Image url="@../Images/arrow.png" /> - </image> - </ImageView> - <ProgressBar fx:id="progressbar" prefHeight="40.0" prefWidth="554.0" progress="0.72" translateY="-10.0" /> - <Label fx:id="today" text="Today" textAlignment="CENTER" translateX="-150.0" translateY="-2.0"> - <StackPane.margin> - <Insets left="300.0" /> - </StackPane.margin> - </Label> - </children> - </StackPane> - <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="50.0" GridPane.columnSpan="2" GridPane.rowIndex="2"> - <children> - <Button fx:id="foodButton" contentDisplay="TOP" mnemonicParsing="false" prefHeight="125.0" prefWidth="119.0" text="Food"> - <graphic> - <ImageView fitHeight="63.0" fitWidth="87.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/pizzaslice.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="addExpenseBtn" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="125.0" prefWidth="125.0" text="Add expense"> - <graphic> - <ImageView fitHeight="79.0" fitWidth="87.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/add_image.png" /> - </image> - </ImageView> - </graphic> - </Button> - <Button fx:id="overviewBtn" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="125.0" prefWidth="125.0" text="Overview"> - <graphic> - <ImageView fitHeight="63.0" fitWidth="87.0" pickOnBounds="true"> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - <image> - <Image url="@../Images/overview_stonks.png" /> - </image> - </ImageView> - </graphic> - </Button> - </children> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <padding> - <Insets top="20.0" /> - </padding> - </HBox> - </children> - </GridPane> - </center> - <bottom> - <Region prefHeight="55.0" prefWidth="600.0" BorderPane.alignment="CENTER" /> - </bottom> - <left> - <Region prefHeight="287.0" prefWidth="14.0" BorderPane.alignment="CENTER" /> - </left> - <right> - <Region prefHeight="287.0" prefWidth="12.0" BorderPane.alignment="CENTER" /> - </right> - <top> - <HBox prefHeight="51.0" prefWidth="600.0" BorderPane.alignment="CENTER"> - <children> - <Button mnemonicParsing="false" text="Return "> - <opaqueInsets> - <Insets left="100.0" /> - </opaqueInsets> - <HBox.margin> - <Insets left="10.0" top="10.0" /> - </HBox.margin> - </Button> - <Region prefHeight="70.0" prefWidth="103.0" /> - <Text fx:id="budgetMonth" strokeType="OUTSIDE" strokeWidth="0.0" text="BUDGET MARCH" textAlignment="CENTER"> - <HBox.margin> - <Insets /> - </HBox.margin> - <font> - <Font size="30.0" /> - </font> - </Text> - </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> - </HBox> - </top> - </BorderPane> - </children> -</AnchorPane> diff --git a/src/main/resources/view/MainMenuNew.fxml b/src/main/resources/view/MainMenuNew.fxml index cfce53f6a77a4b563d436b135d0cfcc1b89c4f94..4acfebd9e6cb9bfd0c0fb6f00a6a495fc5cec22a 100644 --- a/src/main/resources/view/MainMenuNew.fxml +++ b/src/main/resources/view/MainMenuNew.fxml @@ -1,12 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> -<?import javafx.geometry.*?> -<?import javafx.scene.control.*?> -<?import javafx.scene.image.*?> -<?import javafx.scene.layout.*?> -<?import javafx.scene.text.*?> +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.DatePicker?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ProgressBar?> +<?import javafx.scene.image.Image?> +<?import javafx.scene.image.ImageView?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.BorderPane?> +<?import javafx.scene.layout.ColumnConstraints?> +<?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.Pane?> +<?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.StackPane?> +<?import javafx.scene.layout.TilePane?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> -<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.MainMenu"> <children> <ImageView fitHeight="719.0" fitWidth="1130.0" layoutY="-3.0" pickOnBounds="true" preserveRatio="true"> <image> @@ -68,7 +80,7 @@ </ProgressBar> <Label fx:id="usageLbl" text="You have used xxx out of xxx this month"> <font> - <Font name="Lucida Console" size="12.0" /> + <Font name="Lucida Console" size="14.0" /> </font> <StackPane.margin> <Insets top="5.0" /> @@ -188,19 +200,7 @@ <Font name="Lucida Console" size="14.0" /> </font> </Button> - <Button fx:id="expenseBtn" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="100.0" prefWidth="150.0" text="View expenses"> - <graphic> - <ImageView fitHeight="75.0" fitWidth="75.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/expense.png" /> - </image> - </ImageView> - </graphic> - <font> - <Font name="Lucida Console" size="14.0" /> - </font> - </Button> - <Button fx:id="incomeBtn" alignment="TOP_CENTER" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="100.0" prefWidth="150.0" text="View income"> + <Button fx:id="incomeBtn" alignment="TOP_CENTER" contentDisplay="TOP" mnemonicParsing="false" onAction="#switchScene" prefHeight="100.0" prefWidth="150.0" text="Income/expenses"> <graphic> <ImageView fitHeight="75.0" fitWidth="75.0" pickOnBounds="true" preserveRatio="true"> <image> diff --git a/src/main/resources/view/Overview.fxml b/src/main/resources/view/Overview.fxml deleted file mode 100644 index 4bc86e4cbfbe4e7c2322369bc1b7ad046db0f865..0000000000000000000000000000000000000000 --- a/src/main/resources/view/Overview.fxml +++ /dev/null @@ -1,130 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?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.ListView?> -<?import javafx.scene.image.Image?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.BorderPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.Region?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Font?> -<?import javafx.scene.text.Text?> - -<AnchorPane xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SceneController"> - <children> - <ImageView fitHeight="400.0" fitWidth="600.0" pickOnBounds="true"> - <image> - <Image url="@../Images/backgroundMini.jpg" /> - </image> - <cursor> - <Cursor fx:constant="DEFAULT" /> - </cursor> - </ImageView> - <BorderPane prefHeight="400.0" prefWidth="593.0"> - <top> - <HBox BorderPane.alignment="CENTER"> - <children> - <Button cancelButton="true" mnemonicParsing="false" onAction="#switchExpenses" 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="Overview" textAlignment="CENTER" translateX="-5.0"> - <HBox.margin> - <Insets /> - </HBox.margin> - <font> - <Font size="48.0" /> - </font> - </Text> - </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> - </HBox> - </top> - <center> - <GridPane BorderPane.alignment="CENTER"> - <BorderPane.margin> - <Insets bottom="40.0" left="40.0" right="40.0" /> - </BorderPane.margin> - <columnConstraints> - <ColumnConstraints hgrow="ALWAYS" maxWidth="485.3333231608073" minWidth="10.0" prefWidth="236.5" /> - <ColumnConstraints hgrow="ALWAYS" maxWidth="253.0" minWidth="10.0" prefWidth="252.0" /> - </columnConstraints> - <rowConstraints> - <RowConstraints maxHeight="65.33334064483643" minHeight="10.0" prefHeight="26.5" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="239.5" vgrow="SOMETIMES" /> - <RowConstraints maxHeight="298.66665744781494" minHeight="10.0" prefHeight="29.999959309895814" vgrow="SOMETIMES" /> - </rowConstraints> - <children> - <HBox alignment="BOTTOM_LEFT" prefWidth="410.0" spacing="5.0"> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <padding> - <Insets bottom="5.0" /> - </padding> - <children> - <ComboBox fx:id="show" prefHeight="26.0" prefWidth="240.0" promptText="Show"> - <opaqueInsets> - <Insets /> - </opaqueInsets> - </ComboBox> - </children> - </HBox> - <VBox alignment="BOTTOM_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1" /> - <HBox prefHeight="100.0" prefWidth="200.0" GridPane.columnSpan="2" GridPane.rowIndex="2"> - <children> - <Button disable="true" mnemonicParsing="false" text="Overview"> - <HBox.margin> - <Insets right="5.0" /> - </HBox.margin></Button> - <Button mnemonicParsing="false" onAction="#switchIncome" text="Income" textFill="#4d1616" /> - <Button mnemonicParsing="false" onAction="#switchExpenses" text="Expenses" /> - <Button disable="true" mnemonicParsing="false" text="Savings" /> - <Button defaultButton="true" mnemonicParsing="false" onAction="#switchMainMenu" text="Next"> - <HBox.margin> - <Insets left="170.0" /> - </HBox.margin></Button> - </children> - <padding> - <Insets top="10.0" /> - </padding> - </HBox> - <PieChart GridPane.columnIndex="1" GridPane.rowIndex="1" /> - <ListView prefHeight="200.0" prefWidth="270.0" GridPane.rowIndex="1" /> - </children> - </GridPane> - </center> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> - <left> - <Region prefHeight="357.0" prefWidth="25.0" BorderPane.alignment="CENTER" /> - </left> - <right> - <Region prefHeight="357.0" prefWidth="0.0" BorderPane.alignment="CENTER" /> - </right> - <bottom> - <Region prefHeight="0.0" prefWidth="600.0" BorderPane.alignment="CENTER" /> - </bottom> - </BorderPane> - </children> - <opaqueInsets> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> - </opaqueInsets> -</AnchorPane> diff --git a/src/main/resources/view/SelectBudget.fxml b/src/main/resources/view/SelectBudget.fxml new file mode 100644 index 0000000000000000000000000000000000000000..4cf1f903677e6bd97d6e77a8f0ef158480239b1c --- /dev/null +++ b/src/main/resources/view/SelectBudget.fxml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.DialogPane?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ListView?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> + +<DialogPane prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SelectBudgetController"> + <content> + <VBox alignment="CENTER" prefWidth="362.0" spacing="5.0"> + <children> + <Label text="Select budget project"> + <font> + <Font name="Lucida Console" size="24.0" /> + </font> + </Label> + <ListView fx:id="budgetListView" prefHeight="200.0" prefWidth="200.0" /> + <Label fx:id="errorMsg" opacity="0.0" text="Please select a budget" textFill="#e60707"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Label> + <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="5.0"> + <children> + <Button mnemonicParsing="false" onAction="#exitWindow" prefWidth="70.0" text="Cancel" /> + <Button fx:id="okBtn" mnemonicParsing="false" onAction="#selectBudget" prefWidth="70.0" text="OK" /> + </children> + </HBox> + <Label text="Click on an entry to select it"> + <font> + <Font name="Lucida Console" size="14.0" /> + </font> + </Label> + </children> + </VBox> + </content> +</DialogPane> diff --git a/src/main/resources/view/SuggestRecipes.fxml b/src/main/resources/view/SuggestRecipes.fxml index cb8ab9438642ad0c190b6fd6de3c0c676e7b8033..54bc207605fad038051b25ee6ca3a6c7a897039e 100644 --- a/src/main/resources/view/SuggestRecipes.fxml +++ b/src/main/resources/view/SuggestRecipes.fxml @@ -1,12 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> -<?import javafx.geometry.*?> -<?import javafx.scene.control.*?> -<?import javafx.scene.image.*?> -<?import javafx.scene.layout.*?> -<?import javafx.scene.text.*?> +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ListView?> +<?import javafx.scene.image.Image?> +<?import javafx.scene.image.ImageView?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.BorderPane?> +<?import javafx.scene.layout.ColumnConstraints?> +<?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.Pane?> +<?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> -<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="695.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SuggestRecipesController"> +<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.SuggestRecipesController"> <children> <ImageView fitHeight="695.0" fitWidth="1130.0" pickOnBounds="true"> <image> @@ -91,7 +100,7 @@ <right> <VBox alignment="CENTER_LEFT" prefHeight="400.0" prefWidth="405.0" BorderPane.alignment="CENTER"> <children> - <Button fx:id="showAllBtn" mnemonicParsing="false" onAction="#switchScene" styleClass="button-style" stylesheets="@../style.css" text="Or show all recipes" textAlignment="CENTER"> + <Button fx:id="showAllBtn" mnemonicParsing="false" onAction="#switchScene" styleClass="button-style" stylesheets="@../style.css" text="Show all recipes" textAlignment="CENTER"> <VBox.margin> <Insets left="80.0" /> </VBox.margin> diff --git a/src/main/resources/view/deleteBudget.fxml b/src/main/resources/view/deleteBudget.fxml deleted file mode 100644 index 21b63909cd168f35dd26b3803d214881afbb3c88..0000000000000000000000000000000000000000 --- a/src/main/resources/view/deleteBudget.fxml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.ComboBox?> -<?import javafx.scene.layout.AnchorPane?> -<?import javafx.scene.layout.ColumnConstraints?> -<?import javafx.scene.layout.GridPane?> -<?import javafx.scene.layout.HBox?> -<?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.layout.VBox?> -<?import javafx.scene.text.Text?> - -<AnchorPane prefHeight="150.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.DeleteBudget"> - <children> - <GridPane layoutX="23.0" layoutY="30.0" prefHeight="150.0" prefWidth="400.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> - <columnConstraints> - <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> - </columnConstraints> - <rowConstraints> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> - </rowConstraints> - <children> - <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0"> - <children> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Delete Budget Item" /> - </children> - </VBox> - <HBox alignment="CENTER" GridPane.rowIndex="1"> - <children> - <ComboBox prefWidth="150.0" /> - </children> - </HBox> - <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="15.0" GridPane.rowIndex="2"> - <children> - <Button mnemonicParsing="false" text="Cancel" /> - <Button mnemonicParsing="false" text="Delete" /> - </children> - </HBox> - </children> - </GridPane> - </children> -</AnchorPane> diff --git a/src/main/resources/view/dualList.fxml b/src/main/resources/view/dualList.fxml index 4b464415c3a8294b45b369c53197c4b9d4b0fc6a..eaf8cb97527a5984b41dc64cac4f4c082227d544 100644 --- a/src/main/resources/view/dualList.fxml +++ b/src/main/resources/view/dualList.fxml @@ -2,8 +2,11 @@ <?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.TableColumn?> @@ -52,12 +55,15 @@ <StackPane> <children> <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="300.0" /> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Income" /> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Fixed income"> + <font> + <Font size="14.0" /> + </font></Text> </children> </StackPane> <StackPane> <children> - <TableView fx:id="expenseTableView" minWidth="300.0" prefHeight="260.0" prefWidth="485.0"> + <TableView fx:id="incomeTableView" minWidth="300.0" prefHeight="260.0" prefWidth="485.0"> <columns> <TableColumn fx:id="inDateCol" prefWidth="75.0" text="Date" /> <TableColumn fx:id="inAmountCol" prefWidth="75.0" text="Amount" /> @@ -68,8 +74,17 @@ <columnResizePolicy> <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> </columnResizePolicy> + <contextMenu> + <ContextMenu> + <items> + <MenuItem fx:id="editIncomeMenu" mnemonicParsing="false" onAction="#handleEditBtn" text="Edit" /> + <MenuItem fx:id="deleteIncomeMenu" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete" /> + </items> + </ContextMenu> + </contextMenu> </TableView> <Rectangle arcHeight="5.0" arcWidth="5.0" disable="true" fill="LIME" height="234.0" opacity="0.1" stroke="#d9cccc" strokeType="INSIDE" translateY="13.0" width="300.0" /> + <PieChart fx:id="incomePieChart" disable="true" opacity="0.0" prefHeight="1.0" prefWidth="1.0" visible="false" /> </children> </StackPane> <StackPane> @@ -77,13 +92,13 @@ <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="300.0" StackPane.alignment="TOP_LEFT" /> <HBox prefHeight="18.0" prefWidth="517.0"> <children> - <Text fx:id="inSum" strokeType="OUTSIDE" strokeWidth="0.0" text="Sum: "> + <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" /> + <Label fx:id="inSum" text="Label" /> </children> </HBox> </children> @@ -95,12 +110,15 @@ <StackPane> <children> <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="300.0" /> - <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Expenses" /> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Fixed expense"> + <font> + <Font size="14.0" /> + </font></Text> </children> </StackPane> <StackPane> <children> - <TableView fx:id="expenseTableView1" minWidth="300.0" prefHeight="260.0" prefWidth="485.0"> + <TableView fx:id="expenseTableView" minWidth="300.0" prefHeight="260.0" prefWidth="485.0"> <columns> <TableColumn fx:id="expDateCol" prefWidth="75.0" text="Date" /> <TableColumn fx:id="expAmountCol" prefWidth="75.0" text="Amount" /> @@ -111,8 +129,17 @@ <columnResizePolicy> <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> </columnResizePolicy> + <contextMenu> + <ContextMenu> + <items> + <MenuItem fx:id="editExpenseMenu" mnemonicParsing="false" onAction="#handleEditBtn" text="Edit" /> + <MenuItem fx:id="deleteExpenseMenu" mnemonicParsing="false" onAction="#handleDeleteBtn" text="Delete" /> + </items> + </ContextMenu> + </contextMenu> </TableView> <Rectangle arcHeight="5.0" arcWidth="5.0" disable="true" fill="RED" height="234.0" opacity="0.1" stroke="RED" strokeType="INSIDE" translateY="13.0" width="300.0" /> + <PieChart fx:id="expensePieChart" disable="true" opacity="0.0" prefHeight="1.0" prefWidth="1.0" visible="false" /> </children> </StackPane> <StackPane> @@ -120,13 +147,13 @@ <Rectangle arcHeight="5.0" arcWidth="5.0" fill="#f8f8f8" height="18.0" stroke="#d9cccc" strokeType="INSIDE" width="300.0" StackPane.alignment="TOP_LEFT" /> <HBox prefHeight="18.0" prefWidth="517.0"> <children> - <Text fx:id="expSum" strokeType="OUTSIDE" strokeWidth="0.0" text="Sum: "> + <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="sum1" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" /> + <Label fx:id="expSum" text="Label" /> </children> </HBox> </children> @@ -137,15 +164,15 @@ </HBox> <HBox alignment="CENTER_LEFT" prefWidth="410.0" spacing="5.0"> <children> - <MenuButton mnemonicParsing="false" text="MenuButton"> + <MenuButton mnemonicParsing="false" prefHeight="42.0" prefWidth="105.0" text="Add"> <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> @@ -158,19 +185,8 @@ <Insets bottom="5.0" /> </padding> </HBox> - <VBox alignment="CENTER_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1"> - <children> - <ComboBox fx:id="filter" prefWidth="150.0" promptText="Show"> - <opaqueInsets> - <Insets /> - </opaqueInsets> - <VBox.margin> - <Insets bottom="5.0" /> - </VBox.margin> - </ComboBox> - </children> - </VBox> - <Button fx:id="returnBtn" mnemonicParsing="false" onAction="#returnToMainMenu" prefWidth="150.0" text="Continue" GridPane.columnIndex="1" GridPane.rowIndex="2"> + <VBox alignment="CENTER_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="5.0" GridPane.columnIndex="1" /> + <Button fx:id="continueBtn" mnemonicParsing="false" onAction="#switchScene" prefWidth="150.0" text="Continue" GridPane.columnIndex="1" GridPane.rowIndex="2"> <GridPane.margin> <Insets bottom="5.0" /> </GridPane.margin> @@ -190,7 +206,7 @@ </HBox.margin> </Text> <Region prefHeight="18.0" prefWidth="100.0" /> - <Text fx:id="sum11" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" /> + <Label fx:id="maxAmount" text="Label" /> </children> <StackPane.margin> <Insets bottom="4.0" /> @@ -202,11 +218,16 @@ </GridPane> </children> </VBox> - <Button layoutX="14.0" layoutY="14.0" mnemonicParsing="false" text="Return" /> - <Text layoutX="197.0" layoutY="60.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Income/Expenses" textAlignment="CENTER"> + <Button fx:id="returnBtn" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onAction="#switchScene" text="Return to start"> + <font> + <Font size="14.0" /> + </font></Button> + <Text layoutX="146.0" layoutY="54.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Income and Expenses" textAlignment="CENTER"> <font> - <Font size="48.0" /> + <Font name="Lucida Console" size="40.0" /> </font> </Text> + <DatePicker fx:id="date" disable="true" layoutX="340.0" layoutY="473.0" visible="false" /> + <Button fx:id="returnToMainMenuBtn" disable="true" layoutX="99.0" layoutY="14.0" mnemonicParsing="false" opacity="0.0" text="Button" /> </children> </AnchorPane> diff --git a/src/main/resources/view/newBudgetBudgert.fxml b/src/main/resources/view/newBudgetBudgert.fxml index 6ecdfb435715aeb506a3d9c4b9afb31d204557a5..7d19693d8871b40fa8b99c572ac73ab357bea158 100644 --- a/src/main/resources/view/newBudgetBudgert.fxml +++ b/src/main/resources/view/newBudgetBudgert.fxml @@ -5,10 +5,8 @@ <?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.MenuItem?> <?import javafx.scene.control.TableColumn?> <?import javafx.scene.control.TableView?> <?import javafx.scene.image.Image?> @@ -17,6 +15,7 @@ <?import javafx.scene.layout.ColumnConstraints?> <?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.Pane?> <?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.VBox?> @@ -85,12 +84,7 @@ </StackPane> <HBox alignment="CENTER_RIGHT" GridPane.columnIndex="1" GridPane.rowIndex="2"> <children> - <Button fx:id="returnBtn1" mnemonicParsing="false" onAction="#returnToMainMenu" prefWidth="100.0" text="Back"> - <font> - <Font size="14.0" /> - </font> - </Button> - <Button fx:id="returnBtn2" mnemonicParsing="false" onAction="#returnToMainMenu" prefWidth="100.0" text="Continue"> + <Button fx:id="continueBtn" mnemonicParsing="false" onAction="#switchScene" prefWidth="100.0" text="Continue"> <font> <Font size="14.0" /> </font> @@ -106,9 +100,9 @@ <RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> </rowConstraints> <children> - <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="10.0"> + <HBox alignment="CENTER_LEFT" prefHeight="42.0" prefWidth="243.0" spacing="10.0"> <children> - <Button fx:id="addBtn" mnemonicParsing="false" onAction="#handleAddBtn" prefHeight="25.0" prefWidth="60.0"> + <Button fx:id="addBtn" mnemonicParsing="false" onAction="#handleAddBtn" prefHeight="28.0" prefWidth="38.0" text="Add"> <font> <Font name="Lucida Console" size="12.0" /> </font> @@ -120,7 +114,7 @@ </ImageView> </graphic> </Button> - <Button fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="25.0" prefWidth="60.0"> + <Button fx:id="editBtn" mnemonicParsing="false" onAction="#handleEditBtn" prefHeight="28.0" prefWidth="86.0" text="Edit"> <font> <Font name="Lucida Console" size="12.0" /> </font> @@ -132,7 +126,7 @@ </ImageView> </graphic> </Button> - <Button fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="25.0" prefWidth="60.0"> + <Button fx:id="deleteBtn" mnemonicParsing="false" onAction="#handleDeleteBtn" prefHeight="28.0" prefWidth="109.0" text="Delete"> <font> <Font name="Lucida Console" size="12.0" /> </font> @@ -146,9 +140,9 @@ </Button> </children> </HBox> - <HBox alignment="CENTER_LEFT" GridPane.columnIndex="1"> + <HBox alignment="CENTER_RIGHT" prefHeight="42.0" prefWidth="106.0" GridPane.columnIndex="1"> <children> - <ComboBox fx:id="filter" prefHeight="20.0" prefWidth="180.0" promptText="Show"> + <ComboBox fx:id="filter" prefHeight="25.0" prefWidth="80.0" promptText="Show"> <opaqueInsets> <Insets /> </opaqueInsets> @@ -175,13 +169,6 @@ <columnResizePolicy> <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> </columnResizePolicy> - <contextMenu> - <ContextMenu> - <items> - <MenuItem mnemonicParsing="false" text="Unspecified Action" /> - </items> - </ContextMenu> - </contextMenu> </TableView> </children> <padding> @@ -200,26 +187,28 @@ <RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> </rowConstraints> <children> - <Button fx:id="returnBtn" alignment="CENTER" mnemonicParsing="false" onAction="#returnToMainMenu" text="Return to Main Menu"> - <font> - <Font size="14.0" /> - </font> - </Button> <Label fx:id="title" text="Budget Setup" textAlignment="CENTER" GridPane.columnIndex="1"> <font> <Font size="36.0" /> </font> </Label> - <StackPane GridPane.columnIndex="2"> + <Pane GridPane.columnIndex="2"> <children> - <DatePicker fx:id="date" prefWidth="175.0" /> - <Label fx:id="daysLeftLbl" text="Days left: 31"> + <StackPane /> + <Label fx:id="daysLeftLbl" layoutX="33.0" layoutY="62.0" text="Days left: 31"> <font> <Font name="Lucida Console" size="14.0" /> </font> </Label> + <DatePicker fx:id="date" layoutX="3.0" layoutY="32.0" prefWidth="175.0" /> </children> - </StackPane> + </Pane> + <Button fx:id="returnToMainMenuBtn" disable="true" mnemonicParsing="false" onAction="#switchScene" opacity="0.0" text="Button" /> + <Button fx:id="backBtn" mnemonicParsing="false" onAction="#switchScene" prefWidth="100.0" text="Go back"> + <font> + <Font size="14.0" /> + </font> + </Button> </children> </GridPane> </children> diff --git a/src/main/resources/view/underProgress.fxml b/src/main/resources/view/underProgress.fxml deleted file mode 100644 index ec5bf55f00cae55d1dbf4094ecaf9e0365e2aab3..0000000000000000000000000000000000000000 --- a/src/main/resources/view/underProgress.fxml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<?import javafx.geometry.Insets?> -<?import javafx.scene.control.Button?> -<?import javafx.scene.control.TextField?> -<?import javafx.scene.image.Image?> -<?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.AnchorPane?> - - -<AnchorPane prefHeight="172.0" prefWidth="340.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.SceneController"> - <children> - <ImageView fitHeight="310.0" fitWidth="476.0" layoutX="-5.0" pickOnBounds="true" preserveRatio="true"> - <image> - <Image url="@../Images/underProgress.png" /> - </image> - </ImageView> - <Button layoutX="195.0" layoutY="178.0" mnemonicParsing="false" onAction="#closeButton" text="Understood" /> - <TextField layoutX="41.0" layoutY="112.0" prefHeight="26.0" prefWidth="390.0" text="Sorry, but this part of the app is still under construction."> - <opaqueInsets> - <Insets /> - </opaqueInsets> - </TextField> - <TextField alignment="CENTER" layoutX="41.0" layoutY="65.0" prefHeight="26.0" prefWidth="390.0" text="Alert!"> - <opaqueInsets> - <Insets /> - </opaqueInsets> - </TextField> - <TextField layoutX="41.0" layoutY="138.0" prefHeight="26.0" prefWidth="390.0" text="Thank you for your patience."> - <opaqueInsets> - <Insets /> - </opaqueInsets> - </TextField> - </children> -</AnchorPane> diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetTest.java index 21e78490615680cfe43af5e716ca18acd6bdd1f9..f2e9189a9a1578d199308f234be857d8fccf7b24 100644 --- a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetTest.java +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/FileHandlingBudgetTest.java @@ -20,14 +20,12 @@ class FileHandlingBudgetTest { BudgetItem foodItem; BudgetItem bookItem; BudgetItem clothesItem; - FileHandlingBudget fileHandlingBudget = new FileHandlingBudget(); - @Nested @DisplayName("FileHandling budget with one BudgetItem does not throw exception") class fileHandlingBudgetWithOneBudgetItemDoesNotThrowException{ - GeneralBudget generalBudget = new GeneralBudget(12, 1200); - String fileTitle = "oneBudgetItemTest"; + GeneralBudget generalBudget = new GeneralBudget(1200); + String fileTitle = "testFiles/budget/oneBudgetItemTest"; @BeforeEach void createGeneralBudget(){ @@ -37,21 +35,21 @@ class FileHandlingBudgetTest { @Test @DisplayName("Writing to file does not throw exception") void writeGeneralBudgetToFileDoesNotThrowException() throws IOException { - assertDoesNotThrow(() -> fileHandlingBudget.writeGeneralBudgetToFile(fileTitle,generalBudget)); + assertDoesNotThrow(() -> FileHandlingBudget.writeGeneralBudgetToFile(fileTitle,generalBudget)); } @Test @DisplayName("Reading from file gives correct budget back") void readingGeneralBudgetFromFileDoesNotThrowException()throws IOException{ - assertEquals(generalBudget,fileHandlingBudget.readGeneralBudgetFromFile(fileTitle)); + assertEquals(generalBudget,FileHandlingBudget.readGeneralBudgetFromFile(fileTitle)); } } @Nested @DisplayName("FileHandling budget with multiple BudgetItems does not throw exception") class FileHandlingBudgetWithMultipleBudgetItemsDoesNotThrowException{ - GeneralBudget generalBudget = new GeneralBudget(12, 1200); - String fileTitle = "multipleBudgetItem"; + GeneralBudget generalBudget = new GeneralBudget(1200); + String fileTitle = "testFiles/budget/multipleBudgetItem"; @BeforeEach void createGeneralBudget(){ foodItem = new BudgetItem(500, "description", ExpenseCategory.FOOD); @@ -64,14 +62,13 @@ class FileHandlingBudgetTest { @Test @DisplayName("Writing to file does not throw exception") void writeGeneralBudgetToFileDoesNotThrowException() throws IOException { - assertDoesNotThrow(()->fileHandlingBudget.writeGeneralBudgetToFile(fileTitle,generalBudget)); + assertDoesNotThrow(()->FileHandlingBudget.writeGeneralBudgetToFile(fileTitle,generalBudget)); } @Test @DisplayName("Reading from file gives correct budget back") void readingGeneralBudgetFromFileDoesNotThrowException()throws IOException{ - assertEquals(generalBudget,fileHandlingBudget.readGeneralBudgetFromFile(fileTitle)); + assertEquals(generalBudget,FileHandlingBudget.readGeneralBudgetFromFile(fileTitle)); } } - } 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 e13fadab307e970a357391f1c93a3b2b317e1518..22467b8e22578de2fdc8a79f42ca1fb0dc2b795e 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 @@ -11,27 +11,19 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.*; class GeneralBudgetTest { - @Test - @DisplayName("Constructor throws exception when the periodAmount is under zero") - void constructor_throws_exception_when_periodAmount_under_zero(){ - List<BudgetItem> list = new ArrayList<>(); - - assertThrows(IllegalArgumentException.class, () -> new GeneralBudget(-1, list, 1200)); - } - @Test @DisplayName("Constructor throws exception when maxAmount is under zero") void constructor_throws_exception_when_maxAmount_under_zero(){ List<BudgetItem> list = new ArrayList<>(); - assertThrows(IllegalArgumentException.class, () -> new GeneralBudget(10, list, -12)); + assertThrows(IllegalArgumentException.class, () -> new GeneralBudget(list, -12)); } @Test @DisplayName("AddToBudget throws when totalSum is higher than maxAmount ") void add_to_budget_throws_when_totalSum_is_over_maxAmount(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem foodItem = new BudgetItem(1300, "Food", ExpenseCategory.FOOD); assertThrows(IllegalArgumentException.class, () -> budget1.addToBudgetBudgetItem(foodItem)); @@ -41,7 +33,7 @@ class GeneralBudgetTest { @DisplayName("addToBudget throws when a budget with same category already exists") void add_to_budget_throws_when_a_budget_with_same_category_already_exists(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem foodItem = new BudgetItem(500, "Food", ExpenseCategory.FOOD); budget1.addToBudgetBudgetItem(foodItem); BudgetItem alsoFoodItem = new BudgetItem(200, "Food", ExpenseCategory.FOOD); @@ -53,7 +45,7 @@ class GeneralBudgetTest { @DisplayName("Adds a budget to generalBudget") void add_budget_to_generalBudget(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem foodItem = new BudgetItem(500, "Food", ExpenseCategory.FOOD); budget1.addToBudgetBudgetItem(foodItem); @@ -64,7 +56,7 @@ class GeneralBudgetTest { @DisplayName("Checks if the list contains a item with a given category") void checks_if_the_list_contains_an_item_with_this_category_true(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem foodItem = new BudgetItem(500, "Food", ExpenseCategory.FOOD); budget1.addToBudgetBudgetItem(foodItem); @@ -75,7 +67,7 @@ class GeneralBudgetTest { @DisplayName("checks that the list does not contain an item with the given category") void checks_if_the_list_contains_an_item_with_this_category_false(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem bookItem = new BudgetItem(500, "Books", ExpenseCategory.BOOKS); budget1.addToBudgetBudgetItem(bookItem); @@ -86,7 +78,7 @@ class GeneralBudgetTest { @DisplayName("Checks that the getTotalSum gives the correct number") void get_total_sum_of_all_budgetItems_in_the_budget(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem bookItem = new BudgetItem(500, "Books", ExpenseCategory.BOOKS); BudgetItem foodItem = new BudgetItem(300, "Food", ExpenseCategory.FOOD); budget1.addToBudgetBudgetItem(bookItem); @@ -99,7 +91,7 @@ class GeneralBudgetTest { @DisplayName("Checks that an item gets deleted from the budget") void delete_from_budget(){ List<BudgetItem> list = new ArrayList<>(); - GeneralBudget budget1 = new GeneralBudget(12, list, 1200); + GeneralBudget budget1 = new GeneralBudget(list, 1200); BudgetItem bookItem = new BudgetItem(500, "Books", ExpenseCategory.BOOKS); budget1.addToBudgetBudgetItem(bookItem); budget1.deleteItemFromBudget(ExpenseCategory.BOOKS); @@ -115,7 +107,7 @@ class GeneralBudgetTest { @BeforeEach void setUp() { list = new ArrayList<>(); - budget = new GeneralBudget(12, list, 1200); + budget = new GeneralBudget(list, 1200); budget.addToBudget(10, "Books", ExpenseCategory.BOOKS); } @@ -130,6 +122,12 @@ class GeneralBudgetTest { } + @Test + void addToSavingsThrowsExceptionWhenItShould() { + GeneralBudget generalBudget = new GeneralBudget(1000); + assertThrows(IllegalArgumentException.class, () -> generalBudget.addToSavings(1500)); + } + /* @Test @DisplayName("Gets the number of days left in the month. 17 has to be changed to the actual number of days left in the month.") diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/SavingsGoalTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/SavingsGoalTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1429a517c94fe7a491c4ae5d3449ee628a05d9b1 --- /dev/null +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/SavingsGoalTest.java @@ -0,0 +1,80 @@ +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 java.time.LocalDate; +import java.time.Month; + +import static org.junit.jupiter.api.Assertions.*; + +public class SavingsGoalTest { + + @Test + void constructorSetsAmountToZeroIfAmountInvestedIsNegative() { + SavingsGoal savingsGoal = new SavingsGoal("",-50,0); + assertEquals(0, savingsGoal.getAmountInvested()); + } + + @Test + void constructorSetsAmountToZeroIfAmountGoalIsNegative() { + SavingsGoal savingsGoal = new SavingsGoal("",0,-50); + assertEquals(0, savingsGoal.getAmountGoal()); + } + + @Test + void setAmountGoalWillSetToZeroIfItGetsANegativeValue() { + SavingsGoal savingsGoal = new SavingsGoal("",50); + savingsGoal.setAmountGoal(-50); + assertEquals(0, savingsGoal.getAmountGoal()); + } + + @Nested + class testIfSavingsGoalIsAchievedWhenItsSupposedTo{ + SavingsGoal savingsGoalNotAchieved; + SavingsGoal savingsGoalAchieved; + @BeforeEach + void createSavingsGoals() { + savingsGoalNotAchieved = new SavingsGoal("", 50, 100); + savingsGoalAchieved = new SavingsGoal("", 100, 50); + } + + + @Test + void savingsGoalIsAchievedWhenItsSupposedTo() { + assertTrue(savingsGoalAchieved.isAchieved()); + } + + @Test + void savingsGoalIsNotAchievedWhenItsSupposedTo() { + assertFalse(savingsGoalNotAchieved.isAchieved()); + } + + @Test + void addAmountInvestedSoItsHigherThanAmountGoalWillMakeItAchieved() { + savingsGoalNotAchieved.addAmountInvested(100); + assertTrue(savingsGoalNotAchieved.isAchieved()); + } + + @Test + void setAmountGoalLowerThanAmountInvestedWillMakeItAchieved() { + savingsGoalNotAchieved.setAmountGoal(25); + assertTrue(savingsGoalNotAchieved.isAchieved()); + } + + @Test + void addAmountInvestedSoItsLowerThanAmountGoalWillMakeItNotAchieved() { + savingsGoalAchieved.addAmountInvested(-75); + assertFalse(savingsGoalAchieved.isAchieved()); + } + + @Test + void setAmountGoalHigherThanAmountInvestedWillMakeItNotAchieved() { + savingsGoalAchieved.setAmountGoal(150); + assertFalse(savingsGoalAchieved.isAchieved()); + } + + } +} diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Budget/SavingsTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/SavingsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..76b03cfb02c9ec03fced072c5845c4667648b55a --- /dev/null +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Budget/SavingsTest.java @@ -0,0 +1,50 @@ +package no.ntnu.idatt1002.demo.data.Budget; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +public class SavingsTest { + SavingsGoal savingsGoal1; + SavingsGoal savingsGoal2; + SavingsGoal savingsGoal3; + Savings savings; + @BeforeEach + void addSavingsGoalToSavings() { + savingsGoal1 = new SavingsGoal("", 50, 20); + savingsGoal2 = new SavingsGoal("", 75, 50); + savingsGoal3 = new SavingsGoal("", 20, 100); + + savings = new Savings(100); + savings.addSavingsGoal(savingsGoal1); + savings.addSavingsGoal(savingsGoal2); + savings.addSavingsGoal(savingsGoal3); + } + @Test + void getTotalSavingsGivesExpectedAmount() { + assertEquals(245, savings.getTotalSavings()); + } + + @Test + void getAchievedSavingsGoalGivesExpected() { + List<SavingsGoal> savingsGoalsAchieved = new ArrayList<>(); + savingsGoalsAchieved.add(savingsGoal1); + savingsGoalsAchieved.add(savingsGoal2); + + assertEquals(savingsGoalsAchieved, savings.getAchievedSavingsGoal()); + } + + @Test + void addToSavingsGoalThrowsExceptionWhenTryingToAddMoreThanIsAvailable() { + assertThrows(IllegalArgumentException.class, () -> savings.addToSavingsGoal(1000, savingsGoal1)); + } + + @Test + void addToSavingsGoalThrowsExceptionWhenTryingToAddToASavingGoalThatIsNotAddedToSavings() { + assertThrows(IllegalArgumentException.class, () -> savings.addToSavingsGoal(0, new SavingsGoal("not exist",50))); + } +} + diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/Economics/FileHandlingTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/Economics/FileHandlingTest.java index 70dce32b8ffa47b20831c2108f00e576dc3035d2..b591ebb193846e5145b1903a7c3c7f4bad54bef6 100644 --- a/src/test/java/no/ntnu/idatt1002/demo/data/Economics/FileHandlingTest.java +++ b/src/test/java/no/ntnu/idatt1002/demo/data/Economics/FileHandlingTest.java @@ -9,7 +9,6 @@ import java.time.Month; import static org.junit.jupiter.api.Assertions.*; class FileHandlingTest { - FileHandling fileHandling = new FileHandling(); ExpenseRegister expenseRegister = new ExpenseRegister(); IncomeRegister incomeRegister = new IncomeRegister(); @@ -19,8 +18,8 @@ class FileHandlingTest { @Test @DisplayName("isEmpty returns true if a file is empty") void isEmptyReturnsTrueIfAFileIsEmpty() throws IOException { - fileHandling.writeItemRegisterToFile(incomeRegister, "incomeRegisterTest"); - assertTrue(fileHandling.isEmpty("incomeRegisterTest")); + FileHandling.writeItemRegisterToFile(incomeRegister, "/testFiles/economics/incomeRegisterTest"); + assertTrue(FileHandling.isEmpty("/testFiles/economics/incomeRegisterTest")); } @Test @@ -28,14 +27,14 @@ class FileHandlingTest { void isEmptyReturnsFalseIfFileIsNotEmpty() throws IOException { Income income1 = new Income("description", 59.9f, false, IncomeCategory.GIFT, LocalDate.of(2023, Month.MARCH, 3)); incomeRegister.addItem(income1); - fileHandling.writeItemRegisterToFile(incomeRegister, "incomeRegisterTest"); - assertFalse(fileHandling.isEmpty("incomeRegisterTest")); + FileHandling.writeItemRegisterToFile(incomeRegister, "/testFiles/economics/incomeRegisterTest"); + assertFalse(FileHandling.isEmpty("/testFiles/economics/incomeRegisterTest")); } } @Nested @DisplayName("FileHandling IncomeRegister to file") class fileHandlingIncomeRegisterToFile{ - String fileTitle = "incomeRegisterTest"; + String fileTitle = "/testFiles/economics/incomeRegisterTest"; @Nested @DisplayName("FileHandling incomeRegister with income that has description") class fileHandlingIncomeRegisterWithIncomeThatHasDescription{ @@ -47,13 +46,13 @@ class FileHandlingTest { @Test @DisplayName("Writing to file does not throw exception") void writingToFileDoesNotThrowException() { - assertDoesNotThrow(()->fileHandling.writeItemRegisterToFile(incomeRegister, fileTitle)); + assertDoesNotThrow(()->FileHandling.writeItemRegisterToFile(incomeRegister, fileTitle)); } @Test @DisplayName("Reading from file gives correct incomeRegister back") void readingFromFileGivesCorrectIncomeRegisterBack() throws IOException { - assertEquals(incomeRegister.toString(), fileHandling.readIncomeRegisterFromFile(fileTitle).toString()); + assertEquals(incomeRegister.toString(), FileHandling.readIncomeRegisterFromFile(fileTitle).toString()); } } @Nested @@ -67,13 +66,13 @@ class FileHandlingTest { @Test @DisplayName("Writing to file does not throw exception") void writingToFileDoesNotThrowException() { - assertDoesNotThrow(()->fileHandling.writeItemRegisterToFile(incomeRegister, fileTitle)); + assertDoesNotThrow(()->FileHandling.writeItemRegisterToFile(incomeRegister, fileTitle)); } @Test @DisplayName("Reading from file gives correct incomeRegister back") void readingFromFileGivesCorrectIncomeRegisterBack() throws IOException { - assertEquals(incomeRegister.toString(), fileHandling.readIncomeRegisterFromFile(fileTitle).toString()); + assertEquals(incomeRegister.toString(), FileHandling.readIncomeRegisterFromFile(fileTitle).toString()); } } @Nested @@ -91,20 +90,20 @@ class FileHandlingTest { @Test @DisplayName("Writing to file does not throw exception") void writingToFileDoesNotThrowException() { - assertDoesNotThrow(()->fileHandling.writeItemRegisterToFile(incomeRegister, fileTitle)); + assertDoesNotThrow(()->FileHandling.writeItemRegisterToFile(incomeRegister, fileTitle)); } @Test @DisplayName("Reading from file gives correct incomeRegister back") void readingFromFileGivesCorrectIncomeRegisterBack() throws IOException { - assertEquals(incomeRegister.toString(), fileHandling.readIncomeRegisterFromFile(fileTitle).toString()); + assertEquals(incomeRegister.toString(), FileHandling.readIncomeRegisterFromFile(fileTitle).toString()); } } } @Nested @DisplayName("FileHandling ExpenseRegister to file") class fileHandlingExpenseRegisterToFile{ - String fileTitle = "expenseRegisterTest"; + String fileTitle = "/testFiles/economics/expenseRegisterTest"; @Nested @DisplayName("FileHandling ExpenseRegister with Expense that has description") class fileHandlingExpenseRegisterWithExpenseThatHasDescription{ @@ -116,13 +115,13 @@ class FileHandlingTest { @Test @DisplayName("Writing to file does not throw exception") void writingToFileDoesNotThrowException() { - assertDoesNotThrow(()->fileHandling.writeItemRegisterToFile(expenseRegister, fileTitle)); + assertDoesNotThrow(()->FileHandling.writeItemRegisterToFile(expenseRegister, fileTitle)); } @Test @DisplayName("Reading from file gives correct expenseRegister back") void readingFromFileGivesCorrectIncomeRegisterBack() throws IOException { - assertEquals(expenseRegister.toString(), fileHandling.readExpenseRegisterFromFile(fileTitle).toString()); + assertEquals(expenseRegister.toString(), FileHandling.readExpenseRegisterFromFile(fileTitle).toString()); } } @Nested @@ -136,13 +135,13 @@ class FileHandlingTest { @Test @DisplayName("Writing to file does not throw exception") void writingToFileDoesNotThrowException() { - assertDoesNotThrow(()->fileHandling.writeItemRegisterToFile(expenseRegister, fileTitle)); + assertDoesNotThrow(()->FileHandling.writeItemRegisterToFile(expenseRegister, fileTitle)); } @Test @DisplayName("Reading from file gives correct expenseRegister back") void readingFromFileGivesCorrectIncomeRegisterBack() throws IOException { - assertEquals(expenseRegister.toString(), fileHandling.readExpenseRegisterFromFile(fileTitle).toString()); + assertEquals(expenseRegister.toString(), FileHandling.readExpenseRegisterFromFile(fileTitle).toString()); } } @Nested @@ -161,14 +160,14 @@ class FileHandlingTest { @Test @DisplayName("Writing to file does not throw exception") void writingToFileDoesNotThrowException() { - assertDoesNotThrow(()->fileHandling.writeItemRegisterToFile(expenseRegister, fileTitle)); + assertDoesNotThrow(()->FileHandling.writeItemRegisterToFile(expenseRegister, fileTitle)); } @Test @DisplayName("Reading from file gives correct expenseRegister back") void readingFromFileGivesCorrectIncomeRegisterBack() throws IOException { - assertEquals(expenseRegister.toString(), fileHandling.readExpenseRegisterFromFile(fileTitle).toString()); + assertEquals(expenseRegister.toString(), FileHandling.readExpenseRegisterFromFile(fileTitle).toString()); } } } -} \ No newline at end of file +}