From 05e5e1aeea4441143f6d11b807100125d239878a Mon Sep 17 00:00:00 2001 From: Tbusk Date: Sun, 18 Jun 2023 05:54:35 -0400 Subject: [PATCH 001/123] Adding user account creation feature User is populated with getters and setters for username and password. EWalletApp CreateUser works for user creation. To add users, the username must not be taken and the password must be complex. --- src/EWalletApp.java | 112 +++++++++++++++++++++++++++++++++++++++- src/User.java | 47 ++++++++++++++++- src/UserCredentials.csv | 1 + 3 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/UserCredentials.csv diff --git a/src/EWalletApp.java b/src/EWalletApp.java index d6106ce..f722ef9 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -1,8 +1,118 @@ +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class EWalletApp { //this is the app class, has the GUI and create one object of your expense calculator class. The expense calculator class is the implementation of the Expenser interface private ArrayList AllData; - public void CreateUser(String username, String password) {} + + /** + * Method responsible for creating a user account. It adds username and password to a UserCredentials.csv file. + * @param username user's desired username + * @param password user's desired password + */ + public void CreateUser(String username, String password) { + + if (checkForRepeatUsernames(username) == false && isComplexPassword(password)) { // If there are no repeat usernames and password is valid, a new account will be created and stored. + User user = new User(username, password); + AllData.add(user); + + try { // Writes username and password to file in csv format + FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); + PrintWriter printWriter = new PrintWriter(fileOutputStream); + printWriter.append(username); + printWriter.append(","); + printWriter.append(password); + printWriter.append(",\n"); + printWriter.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Method that checks to see if a username exists in UserCredentials.csv + * @param username user's desired username as String + * @return if username is found, returns true. Otherwise, it will return false. + */ + public boolean checkForRepeatUsernames(String username) { + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + Path path = Paths.get("src/UserCredentials.csv"); + Long lines = Files.lines(path).count(); // Counts lines in UserCredentials.csv + String textAtLine = ""; + String readUsername = ""; + if(lines < 1) { // Checks if file is empty + System.out.println("There is no data in file."); + } else { + for (int i = 0; i < lines; i++) { // Goes line by line throughout the file + textAtLine = scnr.nextLine(); + readUsername = ""; + for (int j = 0; j < textAtLine.length(); j++) { // Collects characters until a comma is reached + if (textAtLine.charAt(j) != ',') { + readUsername += textAtLine.charAt(j); + } else { + break; + } + } + if (username.equals(readUsername)) { // Checks if username at line is equal to the user's desired username + + System.out.println("Username already exists."); + return true; + + } + } + } + + } catch (FileNotFoundException e) { + + System.out.println("The file UserCredentials.csv was not found."); + + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + public boolean isComplexPassword(String password) { + + try { + + /* Regex Breakdown + * Passwords must be 8 - 20 characters consisting of at least one digit, symbol, uppercase, lowercase, and it contains no whitespaces. + * ^ - start of String + * $ - end of String + * (?=.*[0-9]) - looks through entire string for at least one occurence of 0-9. + * (?=.*[a-z]) - looks through entire string for at least one occurence of a-z. + * (?=.*[A-Z]) - looks through entire string for at least one occurence of A-Z. + * (?=.*[!@#$%^&+=] - looks through entire string for at least one occurence of !,@,#,$,%,^,&,+, or =. + * {8-20} - minimum of 8 characters, max of 20. + */ + String passwordRegEx = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=\\S+$).{8,20}$"; + Pattern pattern = Pattern.compile(passwordRegEx); + Matcher matcher = pattern.matcher(password); + if(!matcher.find()) { + System.out.println("Password is not valid."); + } else { + System.out.println("Password is valid."); + return true; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } } diff --git a/src/User.java b/src/User.java index 8327a21..8f281b0 100644 --- a/src/User.java +++ b/src/User.java @@ -1,5 +1,8 @@ import java.util.ArrayList; +/** + * A class for creating user objects, which contains currency rates, income, expenses, balance, and monthly savings + */ public class User { private ArrayList currencyRates; private ArrayList Income; // user income sources that user can record or view or search by type or month @@ -11,5 +14,47 @@ public class User { // possible monthly savings, calculated using monthly income (most recent) assuming the data we have is for one year, and monthly and biweekly expenses, here you can assume yearly expenses that are recorded have already been paid. double monthlysavings; //should add constructor(s) - User(String username,String password){} + + /** + * When creating a User object, the user needs to provide a username and password. + * @param username user's desired username as String + * @param password user's desired password as String + */ + User(String username, String password){ + this.username = username; + this.pwd = password; + } + + /** + * Method responsible for getting user's username + * @return user's username as String + */ + protected String getUsername() { + return this.username; + } + + /** + * Method responsible for getting user's password + * @return user's password as String + */ + protected String getPwd() { + return this.pwd; + } + + /** + * Method responsible for updating the user's username + * @param username user's desired username + */ + protected void setUsername(String username) { + this.username = username; + } + + /** + * Method responsible for updating the user's password + * @param password user's desired password + */ + protected void setPwd(String password) { + this.pwd = password; + } + } diff --git a/src/UserCredentials.csv b/src/UserCredentials.csv new file mode 100644 index 0000000..eb92047 --- /dev/null +++ b/src/UserCredentials.csv @@ -0,0 +1 @@ +admin, Password!123, From 0e306eb717ed41ad2650d0c55188fef50ade01b5 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Thu, 22 Jun 2023 21:17:41 -0400 Subject: [PATCH 002/123] Made new class and added 2 methods to it --- src/ExpenserMain.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/ExpenserMain.java diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java new file mode 100644 index 0000000..08fac97 --- /dev/null +++ b/src/ExpenserMain.java @@ -0,0 +1,14 @@ + +public abstract class ExpenserMain implements Expenser { + + @Override + public void addExpense (Expense Ex) { + + } + + @Override + public void addMonthlyIncome (Wage W) { + + } + +} From 0201409dafc50e0ec9a366d2237a97e7473f434e Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Thu, 22 Jun 2023 21:21:30 -0400 Subject: [PATCH 003/123] Added comments to methods --- src/ExpenserMain.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 08fac97..da52ed9 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,11 +1,13 @@ public abstract class ExpenserMain implements Expenser { + // Add Expense feature @Override public void addExpense (Expense Ex) { } + // Add Monthly Income feature @Override public void addMonthlyIncome (Wage W) { From b968354932e0a1b63989d2fa3a40456a88bbc61f Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Fri, 23 Jun 2023 12:20:18 -0400 Subject: [PATCH 004/123] Creating GUI for main application GUI is setup using CardLayout with a menubar to nav between features with ease, similar to how it is done in JavaFX with scene switching. Each of the feature panels needs to be built still. --- src/EWalletApp.java | 362 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index f722ef9..97c29c2 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -115,4 +115,366 @@ public boolean isComplexPassword(String password) { return false; } + public static void main(String[] args) { + + } + } + +class appFrame extends JFrame { + + JMenuBar navMenuBar; + JMenu navMenu; + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav; + + appFrame(){ + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // this.setPreferredSize(new Dimension(800,600)); + this.setTitle("EWallet Application"); + + + homePanel hPanel = new homePanel(); + addItemPanel addItmPanel = new addItemPanel(); + importPanel impPanel = new importPanel(); + estimatePanel estPanel = new estimatePanel(); + incomeRepPanel incRepPanel = new incomeRepPanel(); + expenseRepPanel expRepPanel = new expenseRepPanel(); + detailedRepPanel detRepPanel = new detailedRepPanel(); + getContentPane().add(hPanel); + navMenuBar = new JMenuBar(); + navMenu = new JMenu("

Menu"); + homeNav = new JMenuItem("

Home"); + homeNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(hPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + addItemNav = new JMenuItem("

Add Item"); + addItemNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(addItmPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + importNav = new JMenuItem("

Import Tool"); + importNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mouseClicked(e); + getContentPane().removeAll(); + revalidate(); + repaint(); + getContentPane().add(impPanel); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + estimateNav = new JMenuItem("

Estimate Tool"); + estimateNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(estPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + incomeReportNav = new JMenuItem("

Income Report"); + incomeReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(incRepPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + expenseReportNav = new JMenuItem("

Expense Report"); + expenseReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(expRepPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + detailedReportNav = new JMenuItem("

Detailed Report"); + detailedReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(detRepPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + navMenu.setFont(new Font(null, Font.PLAIN, 24)); + homeNav.setFont(new Font(null, Font.PLAIN, 20)); + addItemNav.setFont(new Font(null, Font.PLAIN, 20)); + importNav.setFont(new Font(null, Font.PLAIN, 20)); + estimateNav.setFont(new Font(null, Font.PLAIN, 20)); + incomeReportNav.setFont(new Font(null, Font.PLAIN, 20)); + expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); + detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); + + navMenu.add(homeNav); + navMenu.add(addItemNav); + navMenu.add(importNav); + navMenu.add(estimateNav); + navMenu.add(incomeReportNav); + navMenu.add(expenseReportNav); + navMenu.add(detailedReportNav); + navMenuBar.add(navMenu); + + this.setJMenuBar(navMenuBar); + this.setLayout(new CardLayout()); + this.pack(); + this.setVisible(true); + } +} + +class homePanel extends JPanel { + + JLabel summaryTxt; + JLabel totalIncomeLbl, totalIncomeAmtLbl; + JLabel totalExpensesLbl, totalExpensesAmtLbl; + JLabel totalSavingsLbl, totalSavingsAmtLbl; + GridBagConstraints gbConst; + homePanel() { + + summaryTxt = new JLabel("User Summary"); + totalIncomeLbl = new JLabel("Total Income: "); + totalIncomeAmtLbl = new JLabel("$0.00"); + totalExpensesLbl = new JLabel("Total Expenses: "); + totalExpensesAmtLbl = new JLabel("$0.00"); + totalSavingsLbl = new JLabel("Total Savings: "); + totalSavingsAmtLbl = new JLabel("$0.00"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,20,20,20); + summaryTxt.setFont(new Font(null, Font.PLAIN, 32)); + this.add(summaryTxt, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(20,40,20,5); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 25)); + this.add(totalIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(20,10,20,40); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 25)); + this.add(totalIncomeAmtLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,40,20,5); + totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 25)); + this.add(totalExpensesLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,10,20,40); + totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 25)); + this.add(totalExpensesAmtLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,40,40,5); + totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 25)); + this.add(totalSavingsLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,10,40,40); + totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 25)); + this.add(totalSavingsAmtLbl, gbConst); + } +} + +class addItemPanel extends JPanel { + GridBagConstraints gbConst; + JLabel addItemLbl; + JLabel nameLbl, amountLbl, monthLbl, frequencyLbl; + JTextField nameField, amountField, monthField, frequencyField; + addItemPanel() { + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + addItemLbl = new JLabel("Add Item"); + nameLbl = new JLabel("Name"); + amountLbl = new JLabel("Amount"); + monthLbl = new JLabel("Month"); + frequencyLbl = new JLabel("Frequency"); + + nameField = new JTextField(); + nameField.setPreferredSize(new Dimension(180, 40)); + amountField = new JTextField(); + amountField.setPreferredSize(new Dimension(180, 40)); + monthField = new JTextField(); + monthField.setPreferredSize(new Dimension(180, 40)); + frequencyField = new JTextField(); + frequencyField.setPreferredSize(new Dimension(180, 40)); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(0,20,20,20); + addItemLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(addItemLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,20,5); + nameLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(nameLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,10,20,20); + nameField.setFont(new Font(null, Font.PLAIN, 24)); + this.add(nameField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,20,5); + amountLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(amountLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,20,20); + amountField.setFont(new Font(null, Font.PLAIN, 24)); + this.add(amountField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,20,5); + amountLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(amountLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,20,20); + amountField.setFont(new Font(null, Font.PLAIN, 24)); + this.add(amountField, gbConst); + } +} + +class importPanel extends JPanel { + JLabel testLbl; + importPanel() { + testLbl = new JLabel("Test Import Nav"); + this.add(testLbl); + } +} + +class estimatePanel extends JPanel { + JLabel testLbl; + estimatePanel() { + testLbl = new JLabel("Test Estimate Nav"); + this.add(testLbl); + } +} + +class incomeRepPanel extends JPanel { + JLabel testLbl; + incomeRepPanel() { + testLbl = new JLabel("Test Income Report Nav"); + this.add(testLbl); + } +} + +class expenseRepPanel extends JPanel { + JLabel testLbl; + expenseRepPanel() { + testLbl = new JLabel("Test Expense Report Nav"); + this.add(testLbl); + } +} + +class detailedRepPanel extends JPanel { + JLabel testLbl; + detailedRepPanel() { + testLbl = new JLabel("Test Detailed Report Nav"); + this.add(testLbl); + } +} \ No newline at end of file From 2be93fbde87383f18c6798a1ccf9010db6742f50 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sat, 24 Jun 2023 03:04:15 -0400 Subject: [PATCH 005/123] Adding pages for add item and import item Panels have been created for adding items and importing items. Estimates and reports UI still has to designed. --- src/EWalletApp.java | 277 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 234 insertions(+), 43 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 97c29c2..a44da87 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -129,7 +129,7 @@ class appFrame extends JFrame { appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - // this.setPreferredSize(new Dimension(800,600)); + this.setPreferredSize(new Dimension(500,650)); this.setTitle("EWallet Application"); @@ -367,83 +367,274 @@ class homePanel extends JPanel { } } -class addItemPanel extends JPanel { +class addItemPanel extends JTabbedPane { GridBagConstraints gbConst; - JLabel addItemLbl; - JLabel nameLbl, amountLbl, monthLbl, frequencyLbl; - JTextField nameField, amountField, monthField, frequencyField; + JPanel incomePane, expensePane; + JLabel addIncomeItemLbl, addExpenseItemLbl; + JLabel nameIncomeLbl, amountIncomeLbl, monthExpenseLbl; + JLabel nameExpenseLbl, amountExpenseLbl, frequencyIncomeLbl; + JTextField nameIncField, amountIncField, frequencyIncField; + JTextField nameExpField, amountExpField, monthExpField; + JButton addIncomeButton, addExpenseButton; addItemPanel() { - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); + incomePane = new JPanel(); + expensePane = new JPanel(); + + addIncomeButton = new JButton("Add"); + addExpenseButton = new JButton("Add"); - addItemLbl = new JLabel("Add Item"); - nameLbl = new JLabel("Name"); - amountLbl = new JLabel("Amount"); - monthLbl = new JLabel("Month"); - frequencyLbl = new JLabel("Frequency"); - - nameField = new JTextField(); - nameField.setPreferredSize(new Dimension(180, 40)); - amountField = new JTextField(); - amountField.setPreferredSize(new Dimension(180, 40)); - monthField = new JTextField(); - monthField.setPreferredSize(new Dimension(180, 40)); - frequencyField = new JTextField(); - frequencyField.setPreferredSize(new Dimension(180, 40)); + gbConst = new GridBagConstraints(); + incomePane.setLayout(new GridBagLayout()); + expensePane.setLayout(new GridBagLayout()); + + addIncomeItemLbl = new JLabel("Add Item"); + nameIncomeLbl = new JLabel("Name"); + amountIncomeLbl = new JLabel("Amount"); + monthExpenseLbl = new JLabel("Month"); + + addExpenseItemLbl = new JLabel("Add Item"); + nameExpenseLbl = new JLabel("Name"); + amountExpenseLbl = new JLabel("Amount"); + frequencyIncomeLbl = new JLabel("Frequency"); + + nameIncField = new JTextField(); + nameIncField.setPreferredSize(new Dimension(180, 40)); + amountIncField = new JTextField(); + amountIncField.setPreferredSize(new Dimension(180, 40)); + frequencyIncField = new JTextField(); + frequencyIncField.setPreferredSize(new Dimension(180, 40)); + + nameExpField = new JTextField(); + nameExpField.setPreferredSize(new Dimension(180, 40)); + amountExpField = new JTextField(); + amountExpField.setPreferredSize(new Dimension(180, 40)); + monthExpField = new JTextField(); + monthExpField.setPreferredSize(new Dimension(180, 40)); gbConst.gridx = 0; gbConst.gridy = 0; gbConst.gridwidth = 2; gbConst.insets = new Insets(0,20,20,20); - addItemLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(addItemLbl, gbConst); + addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(addIncomeItemLbl, gbConst); gbConst.gridx = 0; gbConst.gridy = 1; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,5); - nameLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(nameLbl, gbConst); + gbConst.insets = new Insets(10,20,20,15); + nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(nameIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,20,20); - nameField.setFont(new Font(null, Font.PLAIN, 24)); - this.add(nameField, gbConst); + gbConst.insets = new Insets(10,10,20,30); + nameIncField.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(nameIncField, gbConst); gbConst.gridx = 0; gbConst.gridy = 2; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,5); - amountLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(amountLbl, gbConst); + gbConst.insets = new Insets(10,20,20,15); + amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(amountIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,20,20); - amountField.setFont(new Font(null, Font.PLAIN, 24)); - this.add(amountField, gbConst); + gbConst.insets = new Insets(10,10,20,30); + amountIncField.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(amountIncField, gbConst); gbConst.gridx = 0; gbConst.gridy = 3; gbConst.gridwidth = 1; gbConst.insets = new Insets(10,20,20,5); - amountLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(amountLbl, gbConst); + frequencyIncomeLbl.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(frequencyIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,20,30); + frequencyIncField.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(frequencyIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,10,20,30); + addIncomeButton.setFont(new Font(null, Font.PLAIN, 24)); + incomePane.add(addIncomeButton, gbConst); + + addIncomeButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == addIncomeButton) { + System.out.println("Add Income Button Clicked."); + nameIncField.setText(""); + frequencyIncField.setText(""); + amountIncField.setText(""); + } + } + }); + + this.add("Add Income", incomePane); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.insets = new Insets(0,20,20,20); + addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(addExpenseItemLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,20,25); + nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(nameExpenseLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,10,20,30); + nameExpField.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(nameExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,20,25); + amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(amountExpenseLbl, gbConst); gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,20,30); + amountExpField.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(amountExpField, gbConst); + + gbConst.gridx = 0; gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,20,20); - amountField.setFont(new Font(null, Font.PLAIN, 24)); - this.add(amountField, gbConst); + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,20,25); + monthExpenseLbl.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(monthExpenseLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,20,30); + monthExpField.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(monthExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,10,20,30); + addExpenseButton.setFont(new Font(null, Font.PLAIN, 24)); + expensePane.add(addExpenseButton, gbConst); + + addExpenseButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == addExpenseButton) { + System.out.println("Add Expense Button Clicked."); + nameExpField.setText(""); + monthExpField.setText(""); + amountExpField.setText(""); + } + } + }); + + this.add("Add Expense", expensePane); + this.setFont(new Font(null, Font.PLAIN, 20)); } } class importPanel extends JPanel { - JLabel testLbl; + + GridBagConstraints gbConst; + JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; + JButton selectFileButton, importButton; + JFileChooser fileChooser; + String typesOfImports[]; + JComboBox options; + File userFile; importPanel() { - testLbl = new JLabel("Test Import Nav"); - this.add(testLbl); + + this.setLayout(new GridBagLayout()); + gbConst = new GridBagConstraints(); + typesOfImports = new String[] {"Income","Expense"}; + options = new JComboBox<>(typesOfImports); + options.setSelectedIndex(0); + + importLbl = new JLabel("Import From File"); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,30,20,30); + importLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(importLbl, gbConst); + + selectFileButton = new JButton("File"); + selectFileButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == selectFileButton) { + int userDecision = fileChooser.showOpenDialog(null); + if(userDecision == JFileChooser.APPROVE_OPTION) { + userFile = fileChooser.getSelectedFile(); + System.out.println("The user selected: " + userFile.getAbsolutePath()); + } else if (userDecision == JFileChooser.CANCEL_OPTION) { + System.out.println("The user canceled the operation."); + } + } + } + }); + + selectFileLbl = new JLabel("Select File"); + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(30,30,20,0); + selectFileLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectFileLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(30,0,20,30); + selectFileButton.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectFileButton, gbConst); + + selectTypeLbl = new JLabel("Select Type"); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(30,30,20,0); + selectTypeLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectTypeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(30,0,20,30); + options.setFont(new Font(null, Font.PLAIN, 24)); + this.add(options, gbConst); + + descriptionLbl = new JLabel("Note: Only CSV files are supported.

Once you select a file, click the import button."); + gbConst.gridwidth = 2; + gbConst.gridheight = 2; + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(30,30,30,30); + descriptionLbl.setFont(new Font(null, Font.PLAIN, 20)); + this.add(descriptionLbl, gbConst); + + importButton = new JButton("Import"); + gbConst.gridheight = 1; + gbConst.gridx = 0; + gbConst.gridy = 5; + gbConst.insets = new Insets(30,0,30,30); + importButton.setFont(new Font(null, Font.PLAIN, 24)); + this.add(importButton, gbConst); + + fileChooser = new JFileChooser(); + + } } From 7c56162108448ec738c98343751526c04524d206 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sat, 24 Jun 2023 04:16:01 -0400 Subject: [PATCH 006/123] Updating UI of home and add item page The size and spacing of the UI is modified. --- src/EWalletApp.java | 108 ++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index a44da87..3279ffe 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -1,3 +1,9 @@ +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; @@ -116,7 +122,7 @@ public boolean isComplexPassword(String password) { } public static void main(String[] args) { - + appFrame app = new appFrame(); } } @@ -129,7 +135,7 @@ class appFrame extends JFrame { appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setPreferredSize(new Dimension(500,650)); + this.setPreferredSize(new Dimension(600,700)); this.setTitle("EWallet Application"); @@ -324,45 +330,45 @@ class homePanel extends JPanel { gbConst.gridx = 0; gbConst.gridy = 0; gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,20,20,20); - summaryTxt.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.insets = new Insets(20,20,60,20); + summaryTxt.setFont(new Font(null, Font.PLAIN, 44)); this.add(summaryTxt, gbConst); gbConst.gridx = 0; gbConst.gridy = 1; gbConst.gridwidth = 1; gbConst.insets = new Insets(20,40,20,5); - totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 25)); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(totalIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 1; gbConst.insets = new Insets(20,10,20,40); - totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 25)); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(totalIncomeAmtLbl, gbConst); gbConst.gridx = 0; gbConst.gridy = 2; gbConst.insets = new Insets(20,40,20,5); - totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 25)); + totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(totalExpensesLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 2; gbConst.insets = new Insets(20,10,20,40); - totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 25)); + totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(totalExpensesAmtLbl, gbConst); gbConst.gridx = 0; gbConst.gridy = 3; gbConst.insets = new Insets(20,40,40,5); - totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 25)); + totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(totalSavingsLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 3; gbConst.insets = new Insets(20,10,40,40); - totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 25)); + totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(totalSavingsAmtLbl, gbConst); } } @@ -395,73 +401,74 @@ class addItemPanel extends JTabbedPane { addExpenseItemLbl = new JLabel("Add Item"); nameExpenseLbl = new JLabel("Name"); amountExpenseLbl = new JLabel("Amount"); - frequencyIncomeLbl = new JLabel("Frequency"); + frequencyIncomeLbl = new JLabel("Freq."); nameIncField = new JTextField(); - nameIncField.setPreferredSize(new Dimension(180, 40)); + nameIncField.setPreferredSize(new Dimension(280, 50)); amountIncField = new JTextField(); - amountIncField.setPreferredSize(new Dimension(180, 40)); + amountIncField.setPreferredSize(new Dimension(280, 50)); frequencyIncField = new JTextField(); - frequencyIncField.setPreferredSize(new Dimension(180, 40)); + frequencyIncField.setPreferredSize(new Dimension(280, 50)); nameExpField = new JTextField(); - nameExpField.setPreferredSize(new Dimension(180, 40)); + nameExpField.setPreferredSize(new Dimension(280, 50)); amountExpField = new JTextField(); - amountExpField.setPreferredSize(new Dimension(180, 40)); + amountExpField.setPreferredSize(new Dimension(280, 50)); monthExpField = new JTextField(); - monthExpField.setPreferredSize(new Dimension(180, 40)); + monthExpField.setPreferredSize(new Dimension(280, 50)); gbConst.gridx = 0; gbConst.gridy = 0; gbConst.gridwidth = 2; - gbConst.insets = new Insets(0,20,20,20); - addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.insets = new Insets(0,20,60,30); + addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 44)); incomePane.add(addIncomeItemLbl, gbConst); gbConst.gridx = 0; gbConst.gridy = 1; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,15); - nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,20,30,30); + nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); incomePane.add(nameIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,20,30); - nameIncField.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,10,30,30); + nameIncField.setFont(new Font(null, Font.PLAIN, 28)); incomePane.add(nameIncField, gbConst); gbConst.gridx = 0; gbConst.gridy = 2; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,15); - amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,20,30,30); + amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); incomePane.add(amountIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,20,30); - amountIncField.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,10,30,30); + amountIncField.setFont(new Font(null, Font.PLAIN, 28)); incomePane.add(amountIncField, gbConst); gbConst.gridx = 0; gbConst.gridy = 3; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,5); - frequencyIncomeLbl.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,20,30,30); + frequencyIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); incomePane.add(frequencyIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,20,30); - frequencyIncField.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,10,30,30); + frequencyIncField.setFont(new Font(null, Font.PLAIN, 28)); incomePane.add(frequencyIncField, gbConst); gbConst.gridx = 0; gbConst.gridy = 4; gbConst.gridwidth = 2; - gbConst.insets = new Insets(10,10,20,30); - addIncomeButton.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(20,30,30,30); + addIncomeButton.setFont(new Font(null, Font.PLAIN, 28)); + addIncomeButton.setPreferredSize(new Dimension(150,60)); incomePane.add(addIncomeButton, gbConst); addIncomeButton.addActionListener(new ActionListener() { @@ -480,54 +487,55 @@ public void actionPerformed(ActionEvent e) { gbConst.gridx = 0; gbConst.gridy = 0; - gbConst.insets = new Insets(0,20,20,20); - addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.insets = new Insets(0,20,60,30); + addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 44)); expensePane.add(addExpenseItemLbl, gbConst); gbConst.gridx = 0; gbConst.gridy = 1; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,25); - nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,20,30,30); + nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); expensePane.add(nameExpenseLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,20,30); - nameExpField.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,10,30,30); + nameExpField.setFont(new Font(null, Font.PLAIN, 28)); expensePane.add(nameExpField, gbConst); gbConst.gridx = 0; gbConst.gridy = 2; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,25); - amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,20,30,30); + amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); expensePane.add(amountExpenseLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,20,30); - amountExpField.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,10,30,30); + amountExpField.setFont(new Font(null, Font.PLAIN, 28)); expensePane.add(amountExpField, gbConst); gbConst.gridx = 0; gbConst.gridy = 3; gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,20,25); - monthExpenseLbl.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,20,30,30); + monthExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); expensePane.add(monthExpenseLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,20,30); - monthExpField.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(10,10,30,30); + monthExpField.setFont(new Font(null, Font.PLAIN, 28)); expensePane.add(monthExpField, gbConst); gbConst.gridx = 0; gbConst.gridy = 4; gbConst.gridwidth = 2; - gbConst.insets = new Insets(10,10,20,30); - addExpenseButton.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.insets = new Insets(20,30,30,30); + addExpenseButton.setFont(new Font(null, Font.PLAIN, 28)); + addExpenseButton.setPreferredSize(new Dimension(150,60)); expensePane.add(addExpenseButton, gbConst); addExpenseButton.addActionListener(new ActionListener() { @@ -543,7 +551,7 @@ public void actionPerformed(ActionEvent e) { }); this.add("Add Expense", expensePane); - this.setFont(new Font(null, Font.PLAIN, 20)); + this.setFont(new Font(null, Font.PLAIN, 24)); } } From 748259d439da0ae9f0e013d8cc138e45defcd75f Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sat, 24 Jun 2023 05:23:49 -0400 Subject: [PATCH 007/123] Updating UI of estimate page Adding basic UI to estimate page --- src/EWalletApp.java | 82 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 3279ffe..c1cb198 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -647,10 +647,86 @@ public void actionPerformed(ActionEvent e) { } class estimatePanel extends JPanel { - JLabel testLbl; + GridBagConstraints gbConst; + JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; + JTextField nameField, priceField; + JButton estimateButton; estimatePanel() { - testLbl = new JLabel("Test Estimate Nav"); - this.add(testLbl); + this.setLayout(new GridBagLayout()); + gbConst = new GridBagConstraints(); + + estimateTitleLbl = new JLabel("Estimate Tool"); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,20,30,30); + estimateTitleLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(estimateTitleLbl, gbConst); + + estimateLbl = new JLabel("Estimate:"); + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,0,30,0); + estimateLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(estimateLbl, gbConst); + + estimateAmtLbl = new JLabel("120 days"); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,0,30,0); + estimateAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(estimateAmtLbl, gbConst); + + nameLbl = new JLabel("Item Name"); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,20,30,30); + nameLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(nameLbl, gbConst); + + nameField = new JTextField(); + nameField.setPreferredSize(new Dimension(280, 50)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + nameField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(nameField, gbConst); + + priceLbl = new JLabel("Item Price"); + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,20,30,30); + priceLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(priceLbl, gbConst); + + priceField = new JTextField(); + priceField.setPreferredSize(new Dimension(280, 50)); + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + priceField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(priceField, gbConst); + + estimateButton = new JButton("Get Estimate"); + estimateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == estimateButton) { + System.out.println("Get Estimate Button Clicked."); + nameField.setText(""); + priceField.setText(""); + } + } + }); + estimateButton.setPreferredSize(new Dimension(220, 60)); + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(30,30,30,30); + estimateButton.setFont(new Font(null, Font.PLAIN, 28)); + this.add(estimateButton, gbConst); + } } From 827a63efa5396bbbea00cddd7faff1a058caea85 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Sat, 24 Jun 2023 13:20:41 -0400 Subject: [PATCH 008/123] Made ExpenserMain not abstract --- src/ExpenserMain.java | 68 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index da52ed9..f1825f4 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,5 +1,5 @@ -public abstract class ExpenserMain implements Expenser { +public class ExpenserMain implements Expenser { // Add Expense feature @Override @@ -13,4 +13,70 @@ public void addMonthlyIncome (Wage W) { } + @Override + public void PrintFullreport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintExpensereport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintIncomereport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintIncomereportbyTpe() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintExpensebyType() { + // TODO Auto-generated method stub + + } + + @Override + public void exportReport(String reportTitle) { + // TODO Auto-generated method stub + + } + + @Override + public Currency convertForeignCurrency(Currency C, double amount) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean loadExpenseFile(String filePath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean loadIncomeFile(String filePath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public int whenCanIBuy(String itemname, double price) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void updateMonthlySavings() { + // TODO Auto-generated method stub + + } + } From 13694c2725f7bb754b3ac6037493a3e51fed992d Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Sat, 24 Jun 2023 14:14:22 -0400 Subject: [PATCH 009/123] Added Expense feature --- src/EWalletApp.java | 6 ++++++ src/Expense.java | 27 ++++++++++++++++++++++++++- src/ExpenserMain.java | 5 +++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index f722ef9..4ee3f9f 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -114,5 +114,11 @@ public boolean isComplexPassword(String password) { } return false; } + + public void Expenses() { + ExpenserMain isExpense = new ExpenserMain(); + + isExpense.addExpense(null); + } } diff --git a/src/Expense.java b/src/Expense.java index c386160..020afe9 100644 --- a/src/Expense.java +++ b/src/Expense.java @@ -1,7 +1,32 @@ +import java.util.Scanner; public class Expense { + Scanner scnr = new Scanner(System.in); String source; double amount; int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly - //should add contructor(s) + + public String addSource() { + System.out.println("Enter the Source of the expense."); + source = scnr.nextLine(); + + return source; + } + + public Double addAmount() { + System.out.println("Enter the amount of the expense."); + amount = scnr.nextDouble(); + + return amount; + } + + public int addFrequency() { + System.out.println("Enter the yearly frequency of the expense (1 for 1 time or once a year," + + " 12 for monthly or or 24 for biweekly)."); + yearlyfrequency = scnr.nextInt(); + + return yearlyfrequency; + } + + } diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index f1825f4..54bfd5f 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -4,6 +4,11 @@ public class ExpenserMain implements Expenser { // Add Expense feature @Override public void addExpense (Expense Ex) { + Expense Exp = new Expense(); + + Exp.addSource(); + Exp.addAmount(); + Exp.addFrequency(); } From 7b868dda7e3612a236ac21c4fc12583fdb40f71e Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 04:34:22 -0400 Subject: [PATCH 010/123] Updated UI of reports and implemented some functionality Income reports, expense reports, and detailed reports is populated when items are added. Item adding will work once User, Wage, and Expense are updated on main branch. Completed requirements of those on my end for testing. Home page is updated when items are added as well. --- src/EWalletApp.java | 336 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 294 insertions(+), 42 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index c1cb198..128f58c 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -1,4 +1,6 @@ import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -123,22 +125,24 @@ public boolean isComplexPassword(String password) { public static void main(String[] args) { appFrame app = new appFrame(); + } } class appFrame extends JFrame { + static User user; // temporary - until login is set up. JMenuBar navMenuBar; JMenu navMenu; JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav; appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setPreferredSize(new Dimension(600,700)); + this.setMinimumSize(new Dimension(600,700)); this.setTitle("EWallet Application"); - + user = new User("Kevin", "Abc!1234"); homePanel hPanel = new homePanel(); addItemPanel addItmPanel = new addItemPanel(); importPanel impPanel = new importPanel(); @@ -310,10 +314,8 @@ public void mouseReleased(MouseEvent e) { class homePanel extends JPanel { - JLabel summaryTxt; - JLabel totalIncomeLbl, totalIncomeAmtLbl; - JLabel totalExpensesLbl, totalExpensesAmtLbl; - JLabel totalSavingsLbl, totalSavingsAmtLbl; + JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; + static JLabel totalExpensesAmtLbl, totalSavingsAmtLbl, totalIncomeAmtLbl; GridBagConstraints gbConst; homePanel() { @@ -374,13 +376,17 @@ class homePanel extends JPanel { } class addItemPanel extends JTabbedPane { + + int yearlyFrequency; + double amount; + String month, source; GridBagConstraints gbConst; JPanel incomePane, expensePane; JLabel addIncomeItemLbl, addExpenseItemLbl; - JLabel nameIncomeLbl, amountIncomeLbl, monthExpenseLbl; - JLabel nameExpenseLbl, amountExpenseLbl, frequencyIncomeLbl; - JTextField nameIncField, amountIncField, frequencyIncField; - JTextField nameExpField, amountExpField, monthExpField; + JLabel nameIncomeLbl, amountIncomeLbl, monthIncomeLbl; + JLabel nameExpenseLbl, amountExpenseLbl, frequencyExpLbl; + JTextField nameIncField, amountIncField, frequencyExpField; + JTextField nameExpField, amountExpField, monthIncField; JButton addIncomeButton, addExpenseButton; addItemPanel() { incomePane = new JPanel(); @@ -396,26 +402,26 @@ class addItemPanel extends JTabbedPane { addIncomeItemLbl = new JLabel("Add Item"); nameIncomeLbl = new JLabel("Name"); amountIncomeLbl = new JLabel("Amount"); - monthExpenseLbl = new JLabel("Month"); + monthIncomeLbl = new JLabel("Month"); addExpenseItemLbl = new JLabel("Add Item"); nameExpenseLbl = new JLabel("Name"); amountExpenseLbl = new JLabel("Amount"); - frequencyIncomeLbl = new JLabel("Freq."); + frequencyExpLbl = new JLabel("Freq."); nameIncField = new JTextField(); nameIncField.setPreferredSize(new Dimension(280, 50)); amountIncField = new JTextField(); amountIncField.setPreferredSize(new Dimension(280, 50)); - frequencyIncField = new JTextField(); - frequencyIncField.setPreferredSize(new Dimension(280, 50)); + frequencyExpField = new JTextField(); + frequencyExpField.setPreferredSize(new Dimension(280, 50)); nameExpField = new JTextField(); nameExpField.setPreferredSize(new Dimension(280, 50)); amountExpField = new JTextField(); amountExpField.setPreferredSize(new Dimension(280, 50)); - monthExpField = new JTextField(); - monthExpField.setPreferredSize(new Dimension(280, 50)); + monthIncField = new JTextField(); + monthIncField.setPreferredSize(new Dimension(280, 50)); gbConst.gridx = 0; gbConst.gridy = 0; @@ -454,14 +460,14 @@ class addItemPanel extends JTabbedPane { gbConst.gridy = 3; gbConst.gridwidth = 1; gbConst.insets = new Insets(10,20,30,30); - frequencyIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(frequencyIncomeLbl, gbConst); + monthIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(monthIncomeLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 3; gbConst.insets = new Insets(10,10,30,30); - frequencyIncField.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(frequencyIncField, gbConst); + monthIncField.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(monthIncField, gbConst); gbConst.gridx = 0; gbConst.gridy = 4; @@ -475,10 +481,55 @@ class addItemPanel extends JTabbedPane { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == addIncomeButton) { - System.out.println("Add Income Button Clicked."); - nameIncField.setText(""); - frequencyIncField.setText(""); - amountIncField.setText(""); + if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0 & monthIncField.getText().length() > 0) { + try { + amount = Double.parseDouble(amountIncField.getText()); + } catch (NumberFormatException n) { + System.out.println(n.getMessage()); + amount = 0.00f; + } + source = nameIncField.getText(); + month = monthIncField.getText(); + Wage w = new Wage(source, amount, month); + appFrame.user.addMonthlyIncome(w); + nameIncField.setText(""); + monthIncField.setText(""); + amountIncField.setText(""); + + // Update Home Income + appFrame.user.setBalance(appFrame.user.getBalance() + w.getAmount()); + homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",appFrame.user.getBalance())); + + // update table + incomeRepPanel.model.addRow(new Object[]{}); + int i = 0; + for(Wage wage : appFrame.user.getIncome()) { + incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); + incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); + ++i; + } + + // update detailed table + int j = 0; + detailedRepPanel.model.addRow(new Object[]{}); + for(Wage wge : appFrame.user.getIncome()) { + detailedRepPanel.detailedTable.setValueAt("Income", j, 0); + detailedRepPanel.detailedTable.setValueAt(wge.getSource(), j, 1); + detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wge.getAmount()), j, 2); + detailedRepPanel.detailedTable.setValueAt(wge.getMonth(), j, 3); + ++j; + } + + for(Expense Ex : appFrame.user.getSpending()) { + detailedRepPanel.detailedTable.setValueAt("Expense", j, 0); + detailedRepPanel.detailedTable.setValueAt(Ex.getSource(), j, 1); + detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Ex.getAmount()), j, 2); + detailedRepPanel.detailedTable.setValueAt(Ex.getYearlyfrequency(), j, 3); + ++j; + } + } + } } }); @@ -521,14 +572,14 @@ public void actionPerformed(ActionEvent e) { gbConst.gridy = 3; gbConst.gridwidth = 1; gbConst.insets = new Insets(10,20,30,30); - monthExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(monthExpenseLbl, gbConst); + frequencyExpLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(frequencyExpLbl, gbConst); gbConst.gridx = 1; gbConst.gridy = 3; gbConst.insets = new Insets(10,10,30,30); - monthExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(monthExpField, gbConst); + frequencyExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(frequencyExpField, gbConst); gbConst.gridx = 0; gbConst.gridy = 4; @@ -542,10 +593,55 @@ public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == addExpenseButton) { - System.out.println("Add Expense Button Clicked."); - nameExpField.setText(""); - monthExpField.setText(""); - amountExpField.setText(""); + if(nameExpField.getText().length() > 0 && amountExpField.getText().length() > 0 & frequencyExpField.getText().length() > 0) { + try { + amount = Double.parseDouble(amountExpField.getText()); + yearlyFrequency = Integer.parseInt(frequencyExpField.getText()); + + } catch (NumberFormatException n) { + System.out.println(n.getMessage()); + amount = 0.00f; + } + source = nameExpField.getText(); + Expense Ex = new Expense(source, amount, yearlyFrequency); + appFrame.user.addExpense(Ex); + + // update expense table and expenses on home + appFrame.user.setExpenses(0.00f); + expenseRepPanel.model.addRow(new Object[]{}); + int i = 0; + for(Expense Exp : appFrame.user.getSpending()) { + appFrame.user.setExpenses(appFrame.user.getExpenses() + Exp.amount); + expenseRepPanel.spendingTable.setValueAt(Exp.getSource(), i, 0); + expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 1); + expenseRepPanel.spendingTable.setValueAt(Exp.getYearlyfrequency(), i, 2); + ++i; + } + homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",appFrame.user.getExpenses())); + + // update detailed table + i = 0; + detailedRepPanel.model.addRow(new Object[]{}); + for(Expense Exp : appFrame.user.getSpending()) { + detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); + detailedRepPanel.detailedTable.setValueAt(Exp.getSource(), i, 1); + detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 2); + detailedRepPanel.detailedTable.setValueAt(Exp.getYearlyfrequency(), i, 3); + ++i; + } + + for(Wage wage : appFrame.user.getIncome()) { + detailedRepPanel.detailedTable.setValueAt("Income", i, 0); + detailedRepPanel.detailedTable.setValueAt(wage.getSource(), i, 1); + detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); + detailedRepPanel.detailedTable.setValueAt(wage.getMonth(), i, 3); + ++i; + } + + nameExpField.setText(""); + frequencyExpField.setText(""); + amountExpField.setText(""); + } } } }); @@ -671,7 +767,7 @@ class estimatePanel extends JPanel { estimateLbl.setFont(new Font(null, Font.PLAIN, 32)); this.add(estimateLbl, gbConst); - estimateAmtLbl = new JLabel("120 days"); + estimateAmtLbl = new JLabel("0 days"); gbConst.gridx = 1; gbConst.gridy = 1; gbConst.insets = new Insets(10,0,30,0); @@ -731,25 +827,181 @@ public void actionPerformed(ActionEvent e) { } class incomeRepPanel extends JPanel { - JLabel testLbl; + static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + static JScrollPane jScrollPane; + static int arraySize; + ArrayList Income; + Object[][] tableVals; + String[] columnHeadings; + static JTable incomeTable; + JLabel incomeText; + JButton exportReport; incomeRepPanel() { - testLbl = new JLabel("Test Income Report Nav"); - this.add(testLbl); + + this.setLayout(new BorderLayout()); + incomeText = new JLabel("Income Report"); + incomeText.setFont(new Font(null, Font.PLAIN, 40)); + incomeText.setHorizontalAlignment(JLabel.CENTER); + this.add(incomeText, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Source","Amount", "Month"}; + Income = appFrame.user.getIncome(); + tableVals = new Object[Income.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); + incomeTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { + return false; + } + }; + jScrollPane = new JScrollPane(incomeTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < incomeTable.getColumnCount(); i++) { + incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + incomeTable.setDefaultRenderer(String.class, centerRenderer); + incomeTable.setFont(new Font(null, Font.PLAIN, 24)); + incomeTable.setRowHeight(45); + incomeTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + incomeTable.getTableHeader().setReorderingAllowed(false); + incomeTable.setFocusable(true); + incomeTable.setRowSelectionAllowed(true); + incomeTable.setCellSelectionEnabled(true); + incomeTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + incomeTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + } } class expenseRepPanel extends JPanel { - JLabel testLbl; + static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + static JScrollPane jScrollPane; + static int arraySize; + ArrayList Spending; + Object[][] tableVals; + String[] columnHeadings; + static JTable spendingTable; + JLabel expenseText; + JButton exportReport; expenseRepPanel() { - testLbl = new JLabel("Test Expense Report Nav"); - this.add(testLbl); + this.setLayout(new BorderLayout()); + expenseText = new JLabel("Expense Report"); + expenseText.setFont(new Font(null, Font.PLAIN, 40)); + expenseText.setHorizontalAlignment(JLabel.CENTER); + this.add(expenseText, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Source","Amount", "Frequency"}; + Spending = appFrame.user.getSpending(); + tableVals = new Object[Spending.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); + spendingTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { + return false; + } + }; + jScrollPane = new JScrollPane(spendingTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < spendingTable.getColumnCount(); i++) { + spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + spendingTable.setDefaultRenderer(String.class, centerRenderer); + spendingTable.setFont(new Font(null, Font.PLAIN, 24)); + spendingTable.setRowHeight(45); + spendingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + spendingTable.getTableHeader().setReorderingAllowed(false); + spendingTable.setFocusable(true); + spendingTable.setRowSelectionAllowed(true); + spendingTable.setCellSelectionEnabled(true); + spendingTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + spendingTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + } } class detailedRepPanel extends JPanel { - JLabel testLbl; + static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + static JScrollPane jScrollPane; + static int arraySize; + ArrayList Spending; + ArrayList Income; + Object[][] tableVals; + String[] columnHeadings; + static JTable detailedTable; + JLabel detaileReportTxt; + JButton exportReport; detailedRepPanel() { - testLbl = new JLabel("Test Detailed Report Nav"); - this.add(testLbl); + + this.setLayout(new BorderLayout()); + detaileReportTxt = new JLabel("Detailed Report"); + detaileReportTxt.setFont(new Font(null, Font.PLAIN, 40)); + detaileReportTxt.setHorizontalAlignment(JLabel.CENTER); + this.add(detaileReportTxt, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Type","Source","Amount", "Frequency"}; + Spending = appFrame.user.getSpending(); + Income = appFrame.user.getIncome(); + tableVals = new Object[Spending.size()+Income.size()][4]; + model = new DefaultTableModel(tableVals, columnHeadings); + detailedTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { + return false; + } + }; + jScrollPane = new JScrollPane(detailedTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < detailedTable.getColumnCount(); i++) { + detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + detailedTable.setDefaultRenderer(String.class, centerRenderer); + detailedTable.setFont(new Font(null, Font.PLAIN, 24)); + detailedTable.setRowHeight(45); + detailedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + detailedTable.getTableHeader().setReorderingAllowed(false); + detailedTable.setFocusable(true); + detailedTable.setRowSelectionAllowed(true); + detailedTable.setCellSelectionEnabled(true); + detailedTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + detailedTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); } } \ No newline at end of file From e879f97802deb8dcb1751597787d69ac257ad027 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 10:43:17 -0400 Subject: [PATCH 011/123] Changed month input for income from field to combobox On the Add Income page, previously there was a JTextField accepting input for months with no restrictions. Now there is a JComboBox with dates in a specific format. --- src/EWalletApp.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 128f58c..288ce5c 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -386,12 +386,19 @@ class addItemPanel extends JTabbedPane { JLabel nameIncomeLbl, amountIncomeLbl, monthIncomeLbl; JLabel nameExpenseLbl, amountExpenseLbl, frequencyExpLbl; JTextField nameIncField, amountIncField, frequencyExpField; - JTextField nameExpField, amountExpField, monthIncField; + JTextField nameExpField, amountExpField; JButton addIncomeButton, addExpenseButton; + JComboBox monthComboBox; + String[] months; addItemPanel() { + months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; incomePane = new JPanel(); expensePane = new JPanel(); + monthComboBox = new JComboBox<>(months); + monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); + monthComboBox.setSelectedIndex(0); + addIncomeButton = new JButton("Add"); addExpenseButton = new JButton("Add"); @@ -420,8 +427,7 @@ class addItemPanel extends JTabbedPane { nameExpField.setPreferredSize(new Dimension(280, 50)); amountExpField = new JTextField(); amountExpField.setPreferredSize(new Dimension(280, 50)); - monthIncField = new JTextField(); - monthIncField.setPreferredSize(new Dimension(280, 50)); + monthComboBox.setPreferredSize(new Dimension(280, 50)); gbConst.gridx = 0; gbConst.gridy = 0; @@ -466,8 +472,8 @@ class addItemPanel extends JTabbedPane { gbConst.gridx = 1; gbConst.gridy = 3; gbConst.insets = new Insets(10,10,30,30); - monthIncField.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(monthIncField, gbConst); + monthComboBox.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(monthComboBox, gbConst); gbConst.gridx = 0; gbConst.gridy = 4; @@ -481,7 +487,7 @@ class addItemPanel extends JTabbedPane { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == addIncomeButton) { - if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0 & monthIncField.getText().length() > 0) { + if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0) { try { amount = Double.parseDouble(amountIncField.getText()); } catch (NumberFormatException n) { @@ -489,11 +495,11 @@ public void actionPerformed(ActionEvent e) { amount = 0.00f; } source = nameIncField.getText(); - month = monthIncField.getText(); + month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); Wage w = new Wage(source, amount, month); appFrame.user.addMonthlyIncome(w); nameIncField.setText(""); - monthIncField.setText(""); + monthComboBox.setSelectedItem(0); amountIncField.setText(""); // Update Home Income From 64f8ad277ecd45cecef1c0f20c36de947330fab5 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 11:41:17 -0400 Subject: [PATCH 012/123] Adding comments to file and making slight improvements Adding comments to file to give insight into the workings of this file as well as making slight modifications to various things the IDE recommends fixing. --- src/EWalletApp.java | 161 ++++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 52 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 288ce5c..f70a4d2 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -26,7 +26,7 @@ public class EWalletApp { */ public void CreateUser(String username, String password) { - if (checkForRepeatUsernames(username) == false && isComplexPassword(password)) { // If there are no repeat usernames and password is valid, a new account will be created and stored. + if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { // If there are no repeat usernames and password is valid, a new account will be created and stored. User user = new User(username, password); AllData.add(user); @@ -41,8 +41,6 @@ public void CreateUser(String username, String password) { } catch (FileNotFoundException e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); } } } @@ -58,9 +56,9 @@ public boolean checkForRepeatUsernames(String username) { Scanner scnr = new Scanner(fileInputStream); Path path = Paths.get("src/UserCredentials.csv"); - Long lines = Files.lines(path).count(); // Counts lines in UserCredentials.csv - String textAtLine = ""; - String readUsername = ""; + long lines = Files.lines(path).count(); // Counts lines in UserCredentials.csv + String textAtLine; + String readUsername; if(lines < 1) { // Checks if file is empty System.out.println("There is no data in file."); } else { @@ -130,19 +128,23 @@ public static void main(String[] args) { } +/** + * appFrame is a class that makes up ewallet's GUI frame. It contains a JMenu with options to navigate + * between the different features of the app by utilizing a CardLayout while clearing and setting a panel when navigating between the pages. + */ class appFrame extends JFrame { static User user; // temporary - until login is set up. JMenuBar navMenuBar; JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav; + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav; // different pages appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setMinimumSize(new Dimension(600,700)); this.setTitle("EWallet Application"); - user = new User("Kevin", "Abc!1234"); + user = new User("Kevin", "Abc!1234"); // temporary solution until login is set up homePanel hPanel = new homePanel(); addItemPanel addItmPanel = new addItemPanel(); importPanel impPanel = new importPanel(); @@ -150,11 +152,12 @@ class appFrame extends JFrame { incomeRepPanel incRepPanel = new incomeRepPanel(); expenseRepPanel expRepPanel = new expenseRepPanel(); detailedRepPanel detRepPanel = new detailedRepPanel(); - getContentPane().add(hPanel); + getContentPane().add(hPanel); // setting default page navMenuBar = new JMenuBar(); - navMenu = new JMenu("

Menu"); - homeNav = new JMenuItem("

Home"); + navMenu = new JMenu("

Menu"); // Menu + homeNav = new JMenuItem("

Home"); // Home Page homeNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -172,8 +175,9 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - addItemNav = new JMenuItem("

Add Item"); + addItemNav = new JMenuItem("

Add Item"); // Add Items Page addItemNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -192,8 +196,9 @@ public void mouseReleased(MouseEvent e) { } }); - importNav = new JMenuItem("

Import Tool"); + importNav = new JMenuItem("

Import Tool"); // Import Page importNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { super.mouseClicked(e); @@ -210,8 +215,9 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - estimateNav = new JMenuItem("

Estimate Tool"); + estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page estimateNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -229,8 +235,9 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - incomeReportNav = new JMenuItem("

Income Report"); + incomeReportNav = new JMenuItem("

Income Report"); // Income Report Page incomeReportNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -248,8 +255,9 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - expenseReportNav = new JMenuItem("

Expense Report"); + expenseReportNav = new JMenuItem("

Expense Report"); // Expense Report Page expenseReportNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -267,8 +275,9 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - detailedReportNav = new JMenuItem("

Detailed Report"); + detailedReportNav = new JMenuItem("

Detailed Report"); // Detailed Report Page detailedReportNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -287,6 +296,7 @@ public void mouseReleased(MouseEvent e) { } }); + // Updating font size of menu and menu items navMenu.setFont(new Font(null, Font.PLAIN, 24)); homeNav.setFont(new Font(null, Font.PLAIN, 20)); addItemNav.setFont(new Font(null, Font.PLAIN, 20)); @@ -296,6 +306,7 @@ public void mouseReleased(MouseEvent e) { expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); + // Adding items to the navigation menu navMenu.add(homeNav); navMenu.add(addItemNav); navMenu.add(importNav); @@ -312,6 +323,10 @@ public void mouseReleased(MouseEvent e) { } } +/** + * homePanel is a class that makes up ewallet's GUI home page. It contains basic total information like total income, + * total expenses, and savings. + */ class homePanel extends JPanel { JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; @@ -375,6 +390,10 @@ class homePanel extends JPanel { } } +/** + * addItemPanel is a class that makes up ewallet's Add Item page. It contains the ability for user to add either an income + * or an expense. Adding items will update the home page as well as the reports pages. + */ class addItemPanel extends JTabbedPane { int yearlyFrequency; @@ -397,12 +416,12 @@ class addItemPanel extends JTabbedPane { monthComboBox = new JComboBox<>(months); monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); - monthComboBox.setSelectedIndex(0); + monthComboBox.setSelectedIndex(0); // setting January as default selection addIncomeButton = new JButton("Add"); addExpenseButton = new JButton("Add"); - gbConst = new GridBagConstraints(); + gbConst = new GridBagConstraints(); // defining layout managers incomePane.setLayout(new GridBagLayout()); expensePane.setLayout(new GridBagLayout()); @@ -483,6 +502,11 @@ class addItemPanel extends JTabbedPane { addIncomeButton.setPreferredSize(new Dimension(150,60)); incomePane.add(addIncomeButton, gbConst); + /* + * When the add income button is pressed, if there is text in the name and amount field, + * the data will be retrieved and put into a wage variable as well as updating both the home table, the item report table + * and the detailed report table. + */ addIncomeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -497,7 +521,7 @@ public void actionPerformed(ActionEvent e) { source = nameIncField.getText(); month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); Wage w = new Wage(source, amount, month); - appFrame.user.addMonthlyIncome(w); + appFrame.user.addMonthlyIncome(w); // adding it to the user's wage arraylist nameIncField.setText(""); monthComboBox.setSelectedItem(0); amountIncField.setText(""); @@ -506,8 +530,8 @@ public void actionPerformed(ActionEvent e) { appFrame.user.setBalance(appFrame.user.getBalance() + w.getAmount()); homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",appFrame.user.getBalance())); - // update table - incomeRepPanel.model.addRow(new Object[]{}); + // update income table + incomeRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table int i = 0; for(Wage wage : appFrame.user.getIncome()) { incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); @@ -516,9 +540,9 @@ public void actionPerformed(ActionEvent e) { ++i; } - // update detailed table + // update detailed table by filling it in with wage and expense data int j = 0; - detailedRepPanel.model.addRow(new Object[]{}); + detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table for(Wage wge : appFrame.user.getIncome()) { detailedRepPanel.detailedTable.setValueAt("Income", j, 0); detailedRepPanel.detailedTable.setValueAt(wge.getSource(), j, 1); @@ -595,6 +619,12 @@ public void actionPerformed(ActionEvent e) { addExpenseButton.setPreferredSize(new Dimension(150,60)); expensePane.add(addExpenseButton, gbConst); + + /* + * When the add expense button is pressed, if there is text in the name, amount, and frequency field, + * the data will be retrieved and put into an expense variable as well as updating both the home table, the expense report table + * and the detailed report table. + */ addExpenseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -609,12 +639,12 @@ public void actionPerformed(ActionEvent e) { amount = 0.00f; } source = nameExpField.getText(); - Expense Ex = new Expense(source, amount, yearlyFrequency); - appFrame.user.addExpense(Ex); + Expense Ex = new Expense(source, amount, yearlyFrequency); // new expense object + appFrame.user.addExpense(Ex); // adding it to the user's spending arraylist // update expense table and expenses on home appFrame.user.setExpenses(0.00f); - expenseRepPanel.model.addRow(new Object[]{}); + expenseRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table int i = 0; for(Expense Exp : appFrame.user.getSpending()) { appFrame.user.setExpenses(appFrame.user.getExpenses() + Exp.amount); @@ -625,9 +655,9 @@ public void actionPerformed(ActionEvent e) { } homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",appFrame.user.getExpenses())); - // update detailed table + // update detailed table by filling it in with wage and expense data i = 0; - detailedRepPanel.model.addRow(new Object[]{}); + detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table for(Expense Exp : appFrame.user.getSpending()) { detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); detailedRepPanel.detailedTable.setValueAt(Exp.getSource(), i, 1); @@ -644,6 +674,7 @@ public void actionPerformed(ActionEvent e) { ++i; } + // Clearing fields nameExpField.setText(""); frequencyExpField.setText(""); amountExpField.setText(""); @@ -657,22 +688,28 @@ public void actionPerformed(ActionEvent e) { } } +/** + * importPanel is a class that makes up ewallet's import page. It contains the ability for the user to import data from a csv file. + * This will be completed in Sprint 2. + */ class importPanel extends JPanel { GridBagConstraints gbConst; JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; JButton selectFileButton, importButton; JFileChooser fileChooser; - String typesOfImports[]; + String[] typesOfImports; JComboBox options; File userFile; importPanel() { + fileChooser = new JFileChooser(); + this.setLayout(new GridBagLayout()); gbConst = new GridBagConstraints(); typesOfImports = new String[] {"Income","Expense"}; - options = new JComboBox<>(typesOfImports); - options.setSelectedIndex(0); + options = new JComboBox<>(typesOfImports); // combo box for selecting which type to input to + options.setSelectedIndex(0); // sets Income as initial selection importLbl = new JLabel("Import From File"); gbConst.gridx = 0; @@ -685,13 +722,13 @@ class importPanel extends JPanel { selectFileButton = new JButton("File"); selectFileButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent e) { // File chooser component if (e.getSource() == selectFileButton) { - int userDecision = fileChooser.showOpenDialog(null); - if(userDecision == JFileChooser.APPROVE_OPTION) { + int userDecision = fileChooser.showOpenDialog(null); // opens file chooser window + if(userDecision == JFileChooser.APPROVE_OPTION) { // if file is selected userFile = fileChooser.getSelectedFile(); System.out.println("The user selected: " + userFile.getAbsolutePath()); - } else if (userDecision == JFileChooser.CANCEL_OPTION) { + } else if (userDecision == JFileChooser.CANCEL_OPTION) { // if user backs out System.out.println("The user canceled the operation."); } } @@ -742,12 +779,13 @@ public void actionPerformed(ActionEvent e) { importButton.setFont(new Font(null, Font.PLAIN, 24)); this.add(importButton, gbConst); - fileChooser = new JFileChooser(); - - } } +/** + * estimatePanel is a class that makes up ewallet's estimate page. It contains the ability for the user to estimate how long it + * will take for a user to save up for an item based on stored income and expense information. + */ class estimatePanel extends JPanel { GridBagConstraints gbConst; JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; @@ -812,6 +850,7 @@ class estimatePanel extends JPanel { estimateButton = new JButton("Get Estimate"); estimateButton.addActionListener(new ActionListener() { + // Will retrieve estimate information. Scheduled for Sprint 2. @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == estimateButton) { @@ -832,13 +871,16 @@ public void actionPerformed(ActionEvent e) { } } +/** + * incomeRepPanel is a class that makes up ewallet's income report page. It shows basic income report information like all + * income information and will contain the ability to filter data by month or type. + */ class incomeRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; static JScrollPane jScrollPane; - static int arraySize; ArrayList Income; - Object[][] tableVals; + Object[][] tableVals; // table values String[] columnHeadings; static JTable incomeTable; JLabel incomeText; @@ -852,21 +894,23 @@ class incomeRepPanel extends JPanel { this.add(incomeText, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Month"}; - Income = appFrame.user.getIncome(); - tableVals = new Object[Income.size()][3]; - model = new DefaultTableModel(tableVals, columnHeadings); + Income = appFrame.user.getIncome(); // retrieving income data + tableVals = new Object[Income.size()][3]; // creating table with 3 columns and as many rows as there are data in Income arraylist + model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model incomeTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { + public boolean isCellEditable(int row, int column) { // restricting cell editing return false; } }; jScrollPane = new JScrollPane(incomeTable); + // Centering items in table cells centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); for (int i = 0; i < incomeTable.getColumnCount(); i++) { incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); } incomeTable.setDefaultRenderer(String.class, centerRenderer); + incomeTable.setFont(new Font(null, Font.PLAIN, 24)); incomeTable.setRowHeight(45); incomeTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); @@ -883,6 +927,7 @@ public boolean isCellEditable(int row, int column) { exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); + // Creating centered button in bottom part of border layout JPanel lowerPanel = new JPanel(); lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); lowerPanel.add(exportReport, BorderLayout.CENTER); @@ -892,11 +937,14 @@ public boolean isCellEditable(int row, int column) { } } +/** + * expenseRepPanel is a class that makes up ewallet's expense report page. It shows basic expense report information like all + * expense information and will contain the ability to filter data by month or type. + */ class expenseRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; static JScrollPane jScrollPane; - static int arraySize; ArrayList Spending; Object[][] tableVals; String[] columnHeadings; @@ -912,20 +960,22 @@ class expenseRepPanel extends JPanel { centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Frequency"}; Spending = appFrame.user.getSpending(); - tableVals = new Object[Spending.size()][3]; - model = new DefaultTableModel(tableVals, columnHeadings); + tableVals = new Object[Spending.size()][3]; // creating table with 3 columns and as many rows as there are data in Spending arraylist + model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model spendingTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { + public boolean isCellEditable(int row, int column) { // restricting cell editing return false; } }; jScrollPane = new JScrollPane(spendingTable); + // Centering items in table cells centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); for (int i = 0; i < spendingTable.getColumnCount(); i++) { spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); } spendingTable.setDefaultRenderer(String.class, centerRenderer); + spendingTable.setFont(new Font(null, Font.PLAIN, 24)); spendingTable.setRowHeight(45); spendingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); @@ -942,6 +992,7 @@ public boolean isCellEditable(int row, int column) { exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); + // Creating centered button in bottom part of border layout JPanel lowerPanel = new JPanel(); lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); lowerPanel.add(exportReport, BorderLayout.CENTER); @@ -951,11 +1002,14 @@ public boolean isCellEditable(int row, int column) { } } +/** + * detailedRepPanel is a class that makes up ewallet's detailed report page. It shows basic income and expense report information like all + * expense and income information and will contain the ability to filter data by month or type. + */ class detailedRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; static JScrollPane jScrollPane; - static int arraySize; ArrayList Spending; ArrayList Income; Object[][] tableVals; @@ -975,19 +1029,21 @@ class detailedRepPanel extends JPanel { Spending = appFrame.user.getSpending(); Income = appFrame.user.getIncome(); tableVals = new Object[Spending.size()+Income.size()][4]; - model = new DefaultTableModel(tableVals, columnHeadings); + model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model detailedTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { + public boolean isCellEditable(int row, int column) { // restricting cell editing return false; } }; jScrollPane = new JScrollPane(detailedTable); + // Centering items in table cells centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); for (int i = 0; i < detailedTable.getColumnCount(); i++) { detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); } detailedTable.setDefaultRenderer(String.class, centerRenderer); + detailedTable.setFont(new Font(null, Font.PLAIN, 24)); detailedTable.setRowHeight(45); detailedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); @@ -1004,6 +1060,7 @@ public boolean isCellEditable(int row, int column) { exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); + // Creating centered button in bottom part of border layout JPanel lowerPanel = new JPanel(); lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); lowerPanel.add(exportReport, BorderLayout.CENTER); From 5a7d565fea7c3048254784ea3029745f52c5e953 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 12:38:05 -0400 Subject: [PATCH 013/123] Refactoring methods to make use of ExpenserMain Methods that weren't using ExpenserMain that should are now using ExpenserMain. --- src/EWalletApp.java | 59 ++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index f70a4d2..2c174bc 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -135,6 +135,7 @@ public static void main(String[] args) { class appFrame extends JFrame { static User user; // temporary - until login is set up. + ExpenserMain expenserMain; JMenuBar navMenuBar; JMenu navMenu; JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav; // different pages @@ -145,6 +146,9 @@ class appFrame extends JFrame { this.setTitle("EWallet Application"); user = new User("Kevin", "Abc!1234"); // temporary solution until login is set up + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + homePanel hPanel = new homePanel(); addItemPanel addItmPanel = new addItemPanel(); importPanel impPanel = new importPanel(); @@ -396,6 +400,7 @@ class homePanel extends JPanel { */ class addItemPanel extends JTabbedPane { + ExpenserMain expenserMain; int yearlyFrequency; double amount; String month, source; @@ -410,6 +415,10 @@ class addItemPanel extends JTabbedPane { JComboBox monthComboBox; String[] months; addItemPanel() { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; incomePane = new JPanel(); expensePane = new JPanel(); @@ -521,19 +530,21 @@ public void actionPerformed(ActionEvent e) { source = nameIncField.getText(); month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); Wage w = new Wage(source, amount, month); - appFrame.user.addMonthlyIncome(w); // adding it to the user's wage arraylist + expenserMain.userAtHand.addMonthlyIncome(w); // adding it to the user's wage arraylist nameIncField.setText(""); monthComboBox.setSelectedItem(0); amountIncField.setText(""); // Update Home Income - appFrame.user.setBalance(appFrame.user.getBalance() + w.getAmount()); - homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",appFrame.user.getBalance())); + expenserMain.userAtHand.setBalance(expenserMain.userAtHand.getBalance() + w.getAmount()); + expenserMain.updateMonthlySavings(); + homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",expenserMain.userAtHand.getBalance())); + homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", expenserMain.userAtHand.getMonthlySavings())); // update income table incomeRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table int i = 0; - for(Wage wage : appFrame.user.getIncome()) { + for(Wage wage : expenserMain.userAtHand.getIncome()) { incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); @@ -543,7 +554,7 @@ public void actionPerformed(ActionEvent e) { // update detailed table by filling it in with wage and expense data int j = 0; detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table - for(Wage wge : appFrame.user.getIncome()) { + for(Wage wge : expenserMain.userAtHand.getIncome()) { detailedRepPanel.detailedTable.setValueAt("Income", j, 0); detailedRepPanel.detailedTable.setValueAt(wge.getSource(), j, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wge.getAmount()), j, 2); @@ -551,7 +562,7 @@ public void actionPerformed(ActionEvent e) { ++j; } - for(Expense Ex : appFrame.user.getSpending()) { + for(Expense Ex : expenserMain.userAtHand.getSpending()) { detailedRepPanel.detailedTable.setValueAt("Expense", j, 0); detailedRepPanel.detailedTable.setValueAt(Ex.getSource(), j, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Ex.getAmount()), j, 2); @@ -640,25 +651,27 @@ public void actionPerformed(ActionEvent e) { } source = nameExpField.getText(); Expense Ex = new Expense(source, amount, yearlyFrequency); // new expense object - appFrame.user.addExpense(Ex); // adding it to the user's spending arraylist + expenserMain.userAtHand.addExpense(Ex); // adding it to the user's spending arraylist // update expense table and expenses on home - appFrame.user.setExpenses(0.00f); + expenserMain.userAtHand.setExpenses(0.00f); expenseRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table int i = 0; - for(Expense Exp : appFrame.user.getSpending()) { - appFrame.user.setExpenses(appFrame.user.getExpenses() + Exp.amount); + for(Expense Exp : expenserMain.userAtHand.getSpending()) { + expenserMain.userAtHand.setExpenses(expenserMain.userAtHand.getExpenses() + Exp.amount); expenseRepPanel.spendingTable.setValueAt(Exp.getSource(), i, 0); expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 1); expenseRepPanel.spendingTable.setValueAt(Exp.getYearlyfrequency(), i, 2); ++i; } - homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",appFrame.user.getExpenses())); + expenserMain.updateMonthlySavings(); + homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",expenserMain.userAtHand.getExpenses())); + homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", expenserMain.userAtHand.getMonthlySavings())); // update detailed table by filling it in with wage and expense data i = 0; detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table - for(Expense Exp : appFrame.user.getSpending()) { + for(Expense Exp : expenserMain.userAtHand.getSpending()) { detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); detailedRepPanel.detailedTable.setValueAt(Exp.getSource(), i, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 2); @@ -666,7 +679,7 @@ public void actionPerformed(ActionEvent e) { ++i; } - for(Wage wage : appFrame.user.getIncome()) { + for(Wage wage : expenserMain.userAtHand.getIncome()) { detailedRepPanel.detailedTable.setValueAt("Income", i, 0); detailedRepPanel.detailedTable.setValueAt(wage.getSource(), i, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); @@ -885,8 +898,12 @@ class incomeRepPanel extends JPanel { static JTable incomeTable; JLabel incomeText; JButton exportReport; + ExpenserMain expenserMain; incomeRepPanel() { + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + this.setLayout(new BorderLayout()); incomeText = new JLabel("Income Report"); incomeText.setFont(new Font(null, Font.PLAIN, 40)); @@ -894,7 +911,7 @@ class incomeRepPanel extends JPanel { this.add(incomeText, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Month"}; - Income = appFrame.user.getIncome(); // retrieving income data + Income = expenserMain.userAtHand.getIncome(); // retrieving income data tableVals = new Object[Income.size()][3]; // creating table with 3 columns and as many rows as there are data in Income arraylist model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model incomeTable = new JTable(model) { @@ -951,7 +968,11 @@ class expenseRepPanel extends JPanel { static JTable spendingTable; JLabel expenseText; JButton exportReport; + ExpenserMain expenserMain; expenseRepPanel() { + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + this.setLayout(new BorderLayout()); expenseText = new JLabel("Expense Report"); expenseText.setFont(new Font(null, Font.PLAIN, 40)); @@ -959,7 +980,7 @@ class expenseRepPanel extends JPanel { this.add(expenseText, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Frequency"}; - Spending = appFrame.user.getSpending(); + Spending = expenserMain.userAtHand.getSpending(); tableVals = new Object[Spending.size()][3]; // creating table with 3 columns and as many rows as there are data in Spending arraylist model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model spendingTable = new JTable(model) { @@ -1017,8 +1038,12 @@ class detailedRepPanel extends JPanel { static JTable detailedTable; JLabel detaileReportTxt; JButton exportReport; + ExpenserMain expenserMain; detailedRepPanel() { + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + this.setLayout(new BorderLayout()); detaileReportTxt = new JLabel("Detailed Report"); detaileReportTxt.setFont(new Font(null, Font.PLAIN, 40)); @@ -1026,8 +1051,8 @@ class detailedRepPanel extends JPanel { this.add(detaileReportTxt, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Type","Source","Amount", "Frequency"}; - Spending = appFrame.user.getSpending(); - Income = appFrame.user.getIncome(); + Spending = expenserMain.userAtHand.getSpending(); + Income = expenserMain.userAtHand.getIncome(); tableVals = new Object[Spending.size()+Income.size()][4]; model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model detailedTable = new JTable(model) { From f6af47994df61d27219a98b74caf1870263acb22 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 12:42:50 -0400 Subject: [PATCH 014/123] Adding methods useful for getting and setting information Initializing the arraylists, adding expense variable, and adding various methods useful for updating variables and getting data used throughout the app. --- src/User.java | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/User.java b/src/User.java index 8f281b0..8272955 100644 --- a/src/User.java +++ b/src/User.java @@ -5,14 +5,15 @@ */ public class User { private ArrayList currencyRates; - private ArrayList Income; // user income sources that user can record or view or search by type or month - private ArrayList Spending; //user's expenses + private ArrayList Income = new ArrayList<>(); // user income sources that user can record or view or search by type or month + private ArrayList Spending = new ArrayList<>(); //user's expenses String username; String pwd; //current total income - total double balance; // possible monthly savings, calculated using monthly income (most recent) assuming the data we have is for one year, and monthly and biweekly expenses, here you can assume yearly expenses that are recorded have already been paid. - double monthlysavings; + double monthlysavings; + double expenses; //should add constructor(s) /** @@ -57,4 +58,44 @@ protected void setPwd(String password) { this.pwd = password; } + protected void addMonthlyIncome(Wage W) { + Income.add(W); + } + + protected void addExpense(Expense Ex) { + Spending.add(Ex); + } + + protected ArrayList getIncome() { + return this.Income; + } + + protected ArrayList getSpending() { + return this.Spending; + } + + protected void setBalance(double balance) { + this.balance = balance; + } + + protected double getBalance(){ + return this.balance; + } + + protected void setExpenses(double expenses) { + this.expenses = expenses; + } + + protected double getExpenses() { + return this.expenses; + } + + protected double getMonthlySavings() { + return this.monthlysavings; + } + + protected void setMonthlySavings(double monthlySavings) { + this.monthlysavings = monthlySavings; + } } + From df01125d8d92d36e660e178530d952e780515e8a Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 12:55:06 -0400 Subject: [PATCH 015/123] Adding Javadoc comments Adding Javadoc comments to User.java. Forgot to do it in last push. --- src/User.java | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/User.java b/src/User.java index 8272955..bfa8f11 100644 --- a/src/User.java +++ b/src/User.java @@ -58,42 +58,82 @@ protected void setPwd(String password) { this.pwd = password; } + /** + * Method responsible for adding a monthly income to the Income ArrayList + * @param W Wage object + */ protected void addMonthlyIncome(Wage W) { Income.add(W); } + /** + * Method responsible for adding an expense object to Spending ArrayList + * @param Ex Expense object + */ protected void addExpense(Expense Ex) { Spending.add(Ex); } + /** + * Method responsible for making the ArrayList Income accessible to classes that have access to a user object. + * @return ArrayList of Wage objects. + */ protected ArrayList getIncome() { return this.Income; } + /** + * Method responsible for making the ArrayList Spending accessible to classes that have access to a user object. + * @return ArrayList of Expense objects + */ protected ArrayList getSpending() { return this.Spending; } + /** + * Method responsible for updating balance (income) of user + * @param balance updated income of user as double + */ protected void setBalance(double balance) { this.balance = balance; } + /** + * Method responsible for getting balance of user + * @return current income of user as a double + */ protected double getBalance(){ return this.balance; } + /** + * Method responsible for updating expenses of user + * @param expenses expenses of user as double. + */ protected void setExpenses(double expenses) { this.expenses = expenses; } + /** + * Method responsible for getting expenses of user + * @return expenses of user as double + */ protected double getExpenses() { return this.expenses; } + /** + * Method responsible for getting savings of user + * @return monthly savings of user as double + */ protected double getMonthlySavings() { return this.monthlysavings; } + /** + * Method responsible for updating monthly savings of user + * @param monthlySavings new value of monthly savings of user + */ protected void setMonthlySavings(double monthlySavings) { this.monthlysavings = monthlySavings; } From 545a273710f3052b958456df531a84645ec10464 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Sun, 25 Jun 2023 14:27:04 -0400 Subject: [PATCH 016/123] Fixed the Expense feature --- src/EWalletApp.java | 5 ----- src/Expense.java | 50 ++++++++++++++++++++++++++++--------------- src/ExpenserMain.java | 9 ++++---- src/User.java | 8 +++++++ src/Wage.java | 36 ++++++++++++++++++++++++++++++- 5 files changed, 80 insertions(+), 28 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 4ee3f9f..7b1f1db 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -115,10 +115,5 @@ public boolean isComplexPassword(String password) { return false; } - public void Expenses() { - ExpenserMain isExpense = new ExpenserMain(); - - isExpense.addExpense(null); - } } diff --git a/src/Expense.java b/src/Expense.java index 020afe9..1c4155f 100644 --- a/src/Expense.java +++ b/src/Expense.java @@ -1,32 +1,48 @@ import java.util.Scanner; +/** + * A class for calculating the user's expenses + */ public class Expense { Scanner scnr = new Scanner(System.in); String source; double amount; int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly - public String addSource() { - System.out.println("Enter the Source of the expense."); - source = scnr.nextLine(); - - return source; + /** + * Accepts the parameter values as inputs and updating the object's values + * @param source user's source of expense + * @param amount user's amount of expense + * @param yearlyfrequency user's frequency of expense + */ + Expense(String source, double amount, int yearlyfrequency) { + this.source = source; + this.amount = amount; + this.yearlyfrequency = yearlyfrequency; } - public Double addAmount() { - System.out.println("Enter the amount of the expense."); - amount = scnr.nextDouble(); - - return amount; + /** + * Method responsible for getting the source of the expense + * @param source user's source of the expense + */ + public void getSource(String source) { + this.source = source; } - public int addFrequency() { - System.out.println("Enter the yearly frequency of the expense (1 for 1 time or once a year," - + " 12 for monthly or or 24 for biweekly)."); - yearlyfrequency = scnr.nextInt(); - - return yearlyfrequency; + /** + * Method responsible for getting the amount of the expense + * @param amount user's amount of expense + */ + public void getAmount(Double amount) { + this.amount = amount; + } + + /** + * Method responsible for getting the frequency of the expense + * @param yearlyfrequency user's frequency of expense + */ + public void getFrequency(int yearlyfrequency) { + this.yearlyfrequency = yearlyfrequency; } - } diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 54bfd5f..b049518 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,15 +1,14 @@ + + public class ExpenserMain implements Expenser { + public User userAtHand = null; // Add Expense feature @Override public void addExpense (Expense Ex) { - Expense Exp = new Expense(); - - Exp.addSource(); - Exp.addAmount(); - Exp.addFrequency(); + } // Add Monthly Income feature diff --git a/src/User.java b/src/User.java index 8f281b0..0713f6c 100644 --- a/src/User.java +++ b/src/User.java @@ -56,5 +56,13 @@ protected void setUsername(String username) { protected void setPwd(String password) { this.pwd = password; } + + /** + * Method responsible for adding expense to the arraylist + * @param Ex user's calculated expense + */ + protected void addExpense(Expense Ex) { + Spending.add(Ex); + } } diff --git a/src/Wage.java b/src/Wage.java index 777f173..a859817 100644 --- a/src/Wage.java +++ b/src/Wage.java @@ -4,5 +4,39 @@ public class Wage { double amount; String Month; - //should add contructor(s) + /** + * Accepts the parameter values as inputs and updating the object's values + * @param source user's source of wage + * @param amount user's amount of wage + * @param Month user's month in which they receive the wage + */ + Wage(String source, double amount, String Month) { + this.source = source; + this.amount = amount; + this.Month = Month; + } + + /** + * Method responsible for getting the wage's source + * @param source user's source of the wage + */ + public void getSource(String source) { + this.source = source; + } + + /** + * Method responsible for getting the wage's amount + * @param amount user's amount of the wage + */ + public void getAmount(double amount) { + this.amount = amount; + } + + /** + * Method responsible for getting the month in which the wage was received + * @param Month the month in which the user received the wage + */ + public void getMonth(String Month) { + this.Month = Month; + } } From 218e6174b4cdb468d246d8cfef85353ce1e96e37 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Sun, 25 Jun 2023 14:49:25 -0400 Subject: [PATCH 017/123] Updated methods to return values --- src/Expense.java | 14 ++++++-------- src/ExpenserMain.java | 1 - src/Wage.java | 12 ++++++------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/Expense.java b/src/Expense.java index 1c4155f..078eb59 100644 --- a/src/Expense.java +++ b/src/Expense.java @@ -1,10 +1,8 @@ -import java.util.Scanner; /** * A class for calculating the user's expenses */ public class Expense { - Scanner scnr = new Scanner(System.in); String source; double amount; int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly @@ -25,24 +23,24 @@ public class Expense { * Method responsible for getting the source of the expense * @param source user's source of the expense */ - public void getSource(String source) { - this.source = source; + public String getSource(String source) { + return this.source; } /** * Method responsible for getting the amount of the expense * @param amount user's amount of expense */ - public void getAmount(Double amount) { - this.amount = amount; + public double getAmount(Double amount) { + return this.amount; } /** * Method responsible for getting the frequency of the expense * @param yearlyfrequency user's frequency of expense */ - public void getFrequency(int yearlyfrequency) { - this.yearlyfrequency = yearlyfrequency; + public int getFrequency(int yearlyfrequency) { + return this.yearlyfrequency; } } diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index b049518..9e6c2bf 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -8,7 +8,6 @@ public class ExpenserMain implements Expenser { @Override public void addExpense (Expense Ex) { - } // Add Monthly Income feature diff --git a/src/Wage.java b/src/Wage.java index a859817..701abee 100644 --- a/src/Wage.java +++ b/src/Wage.java @@ -20,23 +20,23 @@ public class Wage { * Method responsible for getting the wage's source * @param source user's source of the wage */ - public void getSource(String source) { - this.source = source; + public String getSource(String source) { + return this.source; } /** * Method responsible for getting the wage's amount * @param amount user's amount of the wage */ - public void getAmount(double amount) { - this.amount = amount; + public double getAmount(double amount) { + return this.amount; } /** * Method responsible for getting the month in which the wage was received * @param Month the month in which the user received the wage */ - public void getMonth(String Month) { - this.Month = Month; + public String getMonth(String Month) { + return this.Month; } } From f33037377f9405e9b46f6d5f2792a19b44704877 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Sun, 25 Jun 2023 14:53:15 -0400 Subject: [PATCH 018/123] Updated parameters --- src/Expense.java | 6 +++--- src/Wage.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Expense.java b/src/Expense.java index 078eb59..426f914 100644 --- a/src/Expense.java +++ b/src/Expense.java @@ -23,7 +23,7 @@ public class Expense { * Method responsible for getting the source of the expense * @param source user's source of the expense */ - public String getSource(String source) { + public String getSource() { return this.source; } @@ -31,7 +31,7 @@ public String getSource(String source) { * Method responsible for getting the amount of the expense * @param amount user's amount of expense */ - public double getAmount(Double amount) { + public double getAmount() { return this.amount; } @@ -39,7 +39,7 @@ public double getAmount(Double amount) { * Method responsible for getting the frequency of the expense * @param yearlyfrequency user's frequency of expense */ - public int getFrequency(int yearlyfrequency) { + public int getFrequency() { return this.yearlyfrequency; } diff --git a/src/Wage.java b/src/Wage.java index 701abee..4039b89 100644 --- a/src/Wage.java +++ b/src/Wage.java @@ -20,7 +20,7 @@ public class Wage { * Method responsible for getting the wage's source * @param source user's source of the wage */ - public String getSource(String source) { + public String getSource() { return this.source; } @@ -28,7 +28,7 @@ public String getSource(String source) { * Method responsible for getting the wage's amount * @param amount user's amount of the wage */ - public double getAmount(double amount) { + public double getAmount() { return this.amount; } @@ -36,7 +36,7 @@ public double getAmount(double amount) { * Method responsible for getting the month in which the wage was received * @param Month the month in which the user received the wage */ - public String getMonth(String Month) { + public String getMonth() { return this.Month; } } From ad355a9f99fe92b9b28df74627a6c8912c574841 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 25 Jun 2023 15:09:27 -0400 Subject: [PATCH 019/123] Updating ExpenserMain with methods Filling out addExpense, addMonthlyIncome, and updateMonthlySavings --- src/ExpenserMain.java | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/ExpenserMain.java diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java new file mode 100644 index 0000000..9efbf38 --- /dev/null +++ b/src/ExpenserMain.java @@ -0,0 +1,83 @@ + +public class ExpenserMain implements Expenser { + + public User userAtHand = null; + // Add Expense feature + @Override + public void addExpense (Expense Ex) { + userAtHand.addExpense(Ex); + } + + // Add Monthly Income feature + @Override + public void addMonthlyIncome (Wage W) { + userAtHand.addMonthlyIncome(W); + } + + @Override + public void PrintFullreport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintExpensereport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintIncomereport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintIncomereportbyTpe() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintExpensebyType() { + // TODO Auto-generated method stub + + } + + @Override + public void exportReport(String reportTitle) { + // TODO Auto-generated method stub + + } + + @Override + public Currency convertForeignCurrency(Currency C, double amount) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean loadExpenseFile(String filePath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean loadIncomeFile(String filePath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public int whenCanIBuy(String itemname, double price) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void updateMonthlySavings() { + // TODO Auto-generated method stub + userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); + } + +} \ No newline at end of file From 153146c84f52cf89c6dfaa507fe165ac105dfda7 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 02:13:48 -0400 Subject: [PATCH 020/123] Fixing merge conflict Replaced ExpenserMain.java file with one from master. --- src/ExpenserMain.java | 162 +++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 9efbf38..9e6c2bf 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,83 +1,85 @@ -public class ExpenserMain implements Expenser { - - public User userAtHand = null; - // Add Expense feature - @Override - public void addExpense (Expense Ex) { - userAtHand.addExpense(Ex); - } - - // Add Monthly Income feature - @Override - public void addMonthlyIncome (Wage W) { - userAtHand.addMonthlyIncome(W); - } - - @Override - public void PrintFullreport() { - // TODO Auto-generated method stub - - } - - @Override - public void PrintExpensereport() { - // TODO Auto-generated method stub - - } - - @Override - public void PrintIncomereport() { - // TODO Auto-generated method stub - - } - - @Override - public void PrintIncomereportbyTpe() { - // TODO Auto-generated method stub - } - @Override - public void PrintExpensebyType() { - // TODO Auto-generated method stub - - } - - @Override - public void exportReport(String reportTitle) { - // TODO Auto-generated method stub - - } - - @Override - public Currency convertForeignCurrency(Currency C, double amount) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean loadExpenseFile(String filePath) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean loadIncomeFile(String filePath) { - // TODO Auto-generated method stub - return false; - } - - @Override - public int whenCanIBuy(String itemname, double price) { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void updateMonthlySavings() { - // TODO Auto-generated method stub - userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); - } - -} \ No newline at end of file +public class ExpenserMain implements Expenser { + public User userAtHand = null; + + // Add Expense feature + @Override + public void addExpense (Expense Ex) { + + } + + // Add Monthly Income feature + @Override + public void addMonthlyIncome (Wage W) { + + } + + @Override + public void PrintFullreport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintExpensereport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintIncomereport() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintIncomereportbyTpe() { + // TODO Auto-generated method stub + + } + + @Override + public void PrintExpensebyType() { + // TODO Auto-generated method stub + + } + + @Override + public void exportReport(String reportTitle) { + // TODO Auto-generated method stub + + } + + @Override + public Currency convertForeignCurrency(Currency C, double amount) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean loadExpenseFile(String filePath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean loadIncomeFile(String filePath) { + // TODO Auto-generated method stub + return false; + } + + @Override + public int whenCanIBuy(String itemname, double price) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void updateMonthlySavings() { + // TODO Auto-generated method stub + + } + +} From bbaaa51423ba223539cf8680ba741cbed817f62a Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 02:21:12 -0400 Subject: [PATCH 021/123] Reapplying User methods to ExpenserMain addExpense, addMonthlyIncome, and updateMonthlySavings methods update --- src/ExpenserMain.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 9e6c2bf..5882916 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -7,79 +7,68 @@ public class ExpenserMain implements Expenser { // Add Expense feature @Override public void addExpense (Expense Ex) { - + userAtHand.addExpense(Ex); } // Add Monthly Income feature @Override public void addMonthlyIncome (Wage W) { - + userAtHand.addMonthlyIncome(W); } @Override public void PrintFullreport() { - // TODO Auto-generated method stub } @Override public void PrintExpensereport() { - // TODO Auto-generated method stub } @Override public void PrintIncomereport() { - // TODO Auto-generated method stub } @Override public void PrintIncomereportbyTpe() { - // TODO Auto-generated method stub - + } @Override public void PrintExpensebyType() { - // TODO Auto-generated method stub } @Override public void exportReport(String reportTitle) { - // TODO Auto-generated method stub } @Override public Currency convertForeignCurrency(Currency C, double amount) { - // TODO Auto-generated method stub return null; } @Override public boolean loadExpenseFile(String filePath) { - // TODO Auto-generated method stub return false; } @Override public boolean loadIncomeFile(String filePath) { - // TODO Auto-generated method stub return false; } @Override public int whenCanIBuy(String itemname, double price) { - // TODO Auto-generated method stub return 0; } @Override public void updateMonthlySavings() { - // TODO Auto-generated method stub - + userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); } } From 049849024cc9f4adad62f736e3f43eedcf3673bb Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 02:24:34 -0400 Subject: [PATCH 022/123] Updating Spacing Correcting spacing in file --- src/ExpenserMain.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 5882916..4ca3eec 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,6 +1,3 @@ - - - public class ExpenserMain implements Expenser { public User userAtHand = null; From e367b254fc8f54facc9190d1085aee793d49a09e Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 02:29:32 -0400 Subject: [PATCH 023/123] Refixing merge conflict Merge is requiring file to be the exact same as in master --- src/ExpenserMain.java | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 4ca3eec..6d9cb18 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,71 +1,85 @@ + + + public class ExpenserMain implements Expenser { public User userAtHand = null; - + // Add Expense feature @Override public void addExpense (Expense Ex) { - userAtHand.addExpense(Ex); + } - + // Add Monthly Income feature - @Override + @Override public void addMonthlyIncome (Wage W) { - userAtHand.addMonthlyIncome(W); + } @Override public void PrintFullreport() { - + // TODO Auto-generated method stub + } @Override public void PrintExpensereport() { - + // TODO Auto-generated method stub + } @Override public void PrintIncomereport() { - + // TODO Auto-generated method stub + } @Override public void PrintIncomereportbyTpe() { + // TODO Auto-generated method stub } @Override public void PrintExpensebyType() { - + // TODO Auto-generated method stub + } @Override public void exportReport(String reportTitle) { - + // TODO Auto-generated method stub + } @Override public Currency convertForeignCurrency(Currency C, double amount) { + // TODO Auto-generated method stub return null; } @Override public boolean loadExpenseFile(String filePath) { + // TODO Auto-generated method stub return false; } @Override public boolean loadIncomeFile(String filePath) { + // TODO Auto-generated method stub return false; } @Override public int whenCanIBuy(String itemname, double price) { + // TODO Auto-generated method stub return 0; } @Override public void updateMonthlySavings() { - userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); + // TODO Auto-generated method stub + } } From 229c13c24d1ec390e32cf3caf2c43581e0928bd9 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 02:54:06 -0400 Subject: [PATCH 024/123] Adding back data to ExpenserMain Readding data to ExpenserMain and going to fix on GitHub --- src/ExpenserMain.java | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 6d9cb18..c368ab5 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,85 +1,71 @@ - - - public class ExpenserMain implements Expenser { public User userAtHand = null; // Add Expense feature @Override public void addExpense (Expense Ex) { - + userAtHand.addExpense(Ex); } // Add Monthly Income feature @Override public void addMonthlyIncome (Wage W) { - + userAtHand.addMonthlyIncome(W); } @Override public void PrintFullreport() { - // TODO Auto-generated method stub } @Override public void PrintExpensereport() { - // TODO Auto-generated method stub } @Override public void PrintIncomereport() { - // TODO Auto-generated method stub } @Override public void PrintIncomereportbyTpe() { - // TODO Auto-generated method stub } @Override public void PrintExpensebyType() { - // TODO Auto-generated method stub } @Override public void exportReport(String reportTitle) { - // TODO Auto-generated method stub } @Override public Currency convertForeignCurrency(Currency C, double amount) { - // TODO Auto-generated method stub return null; } @Override public boolean loadExpenseFile(String filePath) { - // TODO Auto-generated method stub return false; } @Override public boolean loadIncomeFile(String filePath) { - // TODO Auto-generated method stub return false; } @Override public int whenCanIBuy(String itemname, double price) { - // TODO Auto-generated method stub return 0; } @Override public void updateMonthlySavings() { - // TODO Auto-generated method stub - + userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); } } From 0a851eb1ce7018caf7e229649561979d0331d8c5 Mon Sep 17 00:00:00 2001 From: Trevor Busk <114008066+Tbusk@users.noreply.github.com> Date: Mon, 26 Jun 2023 03:25:00 -0400 Subject: [PATCH 025/123] Fixing method name conflicts in EWalletAPp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Names switched from test to repo versions.  Updated methods used from yearlyFrequency() to frequency(). --- src/EWalletApp.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 0f8cb53..6a53af4 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -567,7 +567,7 @@ public void actionPerformed(ActionEvent e) { detailedRepPanel.detailedTable.setValueAt("Expense", j, 0); detailedRepPanel.detailedTable.setValueAt(Ex.getSource(), j, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Ex.getAmount()), j, 2); - detailedRepPanel.detailedTable.setValueAt(Ex.getYearlyfrequency(), j, 3); + detailedRepPanel.detailedTable.setValueAt(Ex.getFrequency(), j, 3); ++j; } } @@ -662,7 +662,7 @@ public void actionPerformed(ActionEvent e) { expenserMain.userAtHand.setExpenses(expenserMain.userAtHand.getExpenses() + Exp.amount); expenseRepPanel.spendingTable.setValueAt(Exp.getSource(), i, 0); expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 1); - expenseRepPanel.spendingTable.setValueAt(Exp.getYearlyfrequency(), i, 2); + expenseRepPanel.spendingTable.setValueAt(Exp.getFrequency(), i, 2); ++i; } expenserMain.updateMonthlySavings(); @@ -676,7 +676,7 @@ public void actionPerformed(ActionEvent e) { detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); detailedRepPanel.detailedTable.setValueAt(Exp.getSource(), i, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 2); - detailedRepPanel.detailedTable.setValueAt(Exp.getYearlyfrequency(), i, 3); + detailedRepPanel.detailedTable.setValueAt(Exp.getFrequency(), i, 3); ++i; } @@ -1093,4 +1093,4 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); this.add(lowerPanel, BorderLayout.SOUTH); } -} \ No newline at end of file +} From 10526cff8c7a3e3f6f8063a04bc36438aa29cb5a Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 03:34:11 -0400 Subject: [PATCH 026/123] Fixing method name conflicts in EWalletApp and User Minor tweaks --- src/EWalletApp.java | 2 +- src/User.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 6a53af4..c6cced2 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -652,7 +652,7 @@ public void actionPerformed(ActionEvent e) { } source = nameExpField.getText(); Expense Ex = new Expense(source, amount, yearlyFrequency); // new expense object - expenserMain.userAtHand.addExpense(Ex); // adding it to the user's spending arraylist + expenserMain.addExpense(Ex); // adding it to the user's spending arraylist // update expense table and expenses on home expenserMain.userAtHand.setExpenses(0.00f); diff --git a/src/User.java b/src/User.java index 676241f..a4baca1 100644 --- a/src/User.java +++ b/src/User.java @@ -78,9 +78,6 @@ protected void addMonthlyIncome(Wage W) { * Method responsible for adding an expense object to Spending ArrayList * @param Ex Expense object */ - protected void addExpense(Expense Ex) { - Spending.add(Ex); - } /** * Method responsible for making the ArrayList Income accessible to classes that have access to a user object. From 8301ee898076f5b09355e3bb6cafc2f3365158b2 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 26 Jun 2023 11:29:59 -0400 Subject: [PATCH 027/123] Feature: Export to CSV + Income and Export Report Filtering Big update: adding export to csv feature, filtering of income report and expense report, as well as income and expense related information for completing user stories. --- src/EWalletApp.java | 370 ++++++++++++++++++++++++++++++++++++++++-- src/ExpenserMain.java | 108 +++++++++++- 2 files changed, 462 insertions(+), 16 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index c6cced2..7798f5f 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -16,7 +16,7 @@ import java.util.regex.Pattern; public class EWalletApp { - //this is the app class, has the GUI and create one object of your expense calculator class. The expense calculator class is the implementation of the Expenser interface + //this is the app class, has the GUI and create one object of your expense calculator class. The expense calculator class is the implementation of the Expenser interface private ArrayList AllData; /** @@ -120,7 +120,7 @@ public boolean isComplexPassword(String password) { } return false; } - + public static void main(String[] args) { appFrame app = new appFrame(); @@ -143,7 +143,7 @@ class appFrame extends JFrame { appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setMinimumSize(new Dimension(600,700)); + this.setMinimumSize(new Dimension(900,700)); this.setTitle("EWallet Application"); user = new User("Kevin", "Abc!1234"); // temporary solution until login is set up @@ -536,6 +536,25 @@ public void actionPerformed(ActionEvent e) { monthComboBox.setSelectedItem(0); amountIncField.setText(""); + // Update panel totals + incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",incomeRepPanel.getIncome(expenserMain.userAtHand.getIncome()))); + + // Update JComboBoxes if + if(incomeRepPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { + if (incomeRepPanel.typeSelector.getItemAt(i).equals(w.getSource())) { + contains = true; + } + } + if (!contains) { + incomeRepPanel.typeSelector.addItem(w.getSource()); + } + } else { + incomeRepPanel.typeSelector.addItem(w.getSource()); + } + + // Update Home Income expenserMain.userAtHand.setBalance(expenserMain.userAtHand.getBalance() + w.getAmount()); expenserMain.updateMonthlySavings(); @@ -554,6 +573,7 @@ public void actionPerformed(ActionEvent e) { // update detailed table by filling it in with wage and expense data int j = 0; + incomeRepPanel.model.setNumRows(expenserMain.userAtHand.getIncome().size()); detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table for(Wage wge : expenserMain.userAtHand.getIncome()) { detailedRepPanel.detailedTable.setValueAt("Income", j, 0); @@ -570,6 +590,7 @@ public void actionPerformed(ActionEvent e) { detailedRepPanel.detailedTable.setValueAt(Ex.getFrequency(), j, 3); ++j; } + } } @@ -654,6 +675,24 @@ public void actionPerformed(ActionEvent e) { Expense Ex = new Expense(source, amount, yearlyFrequency); // new expense object expenserMain.addExpense(Ex); // adding it to the user's spending arraylist + expenseRepPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",expenseRepPanel.getExpense(expenserMain.userAtHand.getSpending()))); + + // Update JComboBoxes + if(expenseRepPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { + if (expenseRepPanel.typeSelector.getItemAt(i).equals(Ex.getSource())) { + contains = true; + } + } + if (!contains) { + expenseRepPanel.typeSelector.addItem(Ex.getSource()); + } + } else { + expenseRepPanel.typeSelector.addItem(Ex.getSource()); + } + + // update expense table and expenses on home expenserMain.userAtHand.setExpenses(0.00f); expenseRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table @@ -887,32 +926,131 @@ public void actionPerformed(ActionEvent e) { /** * incomeRepPanel is a class that makes up ewallet's income report page. It shows basic income report information like all - * income information and will contain the ability to filter data by month or type. + * income information and contains the ability to filter data by month or source. */ class incomeRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; static JScrollPane jScrollPane; - ArrayList Income; + static ArrayList Income; + static ArrayList filteredIncomeList = new ArrayList<>(); Object[][] tableVals; // table values String[] columnHeadings; static JTable incomeTable; - JLabel incomeText; - JButton exportReport; + JLabel incomeText, filterTxt; + JLabel totalIncomeLbl, totalFilteredIncomeLbl; + static JLabel totalIncomeAmtLbl, totalFilteredIncomeAmtLbl; + JButton exportReport, applyFilter; ExpenserMain expenserMain; + GridBagConstraints gbConst; + JPanel upperPanel; + JComboBox monthSelector; + static JComboBox typeSelector; + String[] months; incomeRepPanel() { expenserMain = new ExpenserMain(); expenserMain.userAtHand = appFrame.user; + incomeRepPanel.Income = expenserMain.userAtHand.getIncome(); // retrieving income data this.setLayout(new BorderLayout()); + incomeText = new JLabel("Income Report"); incomeText.setFont(new Font(null, Font.PLAIN, 40)); incomeText.setHorizontalAlignment(JLabel.CENTER); - this.add(incomeText, BorderLayout.PAGE_START); + + gbConst = new GridBagConstraints(); + upperPanel = new JPanel(); + upperPanel.setLayout(new GridBagLayout()); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 4; + gbConst.insets = new Insets(20,0,20,0); + upperPanel.add(incomeText, gbConst); + + totalIncomeLbl = new JLabel("Total Income"); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridwidth = 1; + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(totalIncomeLbl,gbConst); + + totalIncomeAmtLbl = new JLabel("0.00"); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalIncomeAmtLbl,gbConst); + + totalFilteredIncomeLbl = new JLabel("Income (Filtered)"); + totalFilteredIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 2; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalFilteredIncomeLbl,gbConst); + + totalFilteredIncomeAmtLbl = new JLabel("0.00"); + totalFilteredIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 3; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,20); + upperPanel.add(totalFilteredIncomeAmtLbl,gbConst); + + filterTxt = new JLabel("Apply a filter"); + filterTxt.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(filterTxt,gbConst); + + months = new String[]{"","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + monthSelector = new JComboBox<>(months); + monthSelector.setPreferredSize(new Dimension(200,50)); + monthSelector.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(monthSelector,gbConst); + + incomeRepPanel.typeSelector = new JComboBox<>(getSources(Income).toArray()); + typeSelector.setFont(new Font(null, Font.PLAIN, 24)); + typeSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 2; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(typeSelector,gbConst); + + applyFilter = new JButton("Filter"); + applyFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == applyFilter) { + filteredIncomeList = filterIncomes(Income,(String)typeSelector.getItemAt(typeSelector.getSelectedIndex()),(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + incomeRepPanel.model.setNumRows(filteredIncomeList.size()); + int i = 0; + double incomeSum = 0.00f; + for(Wage wage : filteredIncomeList) { + incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); + incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); + ++i; + incomeSum += wage.getAmount(); + } + totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); + } + } + }); + applyFilter.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 3; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(applyFilter,gbConst); + + this.add(upperPanel, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Month"}; - Income = expenserMain.userAtHand.getIncome(); // retrieving income data tableVals = new Object[Income.size()][3]; // creating table with 3 columns and as many rows as there are data in Income arraylist model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model incomeTable = new JTable(model) { @@ -942,6 +1080,12 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { // exports report to csv + expenserMain.exportReport("Income Report"); + } + }); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -953,6 +1097,49 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(lowerPanel, BorderLayout.SOUTH); } + + /** + * Method responsible for obtaining sources for the combobox selector + * @param wage Wage ArrayList + * @return ArrayList of Strings of sources + */ + private ArrayList getSources(ArrayList wage) { + ArrayList sources = new ArrayList<>(); + for(Wage w : wage) { + sources.add(w.getSource()); + } + return sources; + } + + /** + * Method responsible for obtaining total income information for filtered data + * @param wage Filtered ArrayList for income + * @return Total Filtered Income + */ + static double getIncome(ArrayList wage) { + double sum = 0.00f; + for(Wage w : wage) { + sum += w.getAmount(); + } + return sum; + } + + /** + * Method responsible for producing a filtered income ArrayList based on user's desired filters like source and month + * @param wage Base Income ArrayList + * @param source Source as String + * @param month Month as String + * @return Filtered ArrayList + */ + static ArrayList filterIncomes(ArrayList wage, String source, String month) { + ArrayList filteredWages = new ArrayList<>(); + for(Wage w : wage) { + if(w.getSource().equals(source) && (w.getMonth().equals(month) || month.equals("")) ) { + filteredWages.add(w); + } + } + return filteredWages; + } } /** @@ -963,25 +1150,126 @@ class expenseRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; static JScrollPane jScrollPane; - ArrayList Spending; + static ArrayList Spending; + static ArrayList filteredSpending = new ArrayList<>(); Object[][] tableVals; String[] columnHeadings; static JTable spendingTable; JLabel expenseText; - JButton exportReport; + JLabel totalExpenseLbl, totalFilteredExpenseLbl, filterTxt ; + static JLabel totalExpenseAmtLbl, totalFilteredExpenseAmtLbl; + JButton exportReport, applyFilter; ExpenserMain expenserMain; + GridBagConstraints gbConst; + JPanel upperPanel; + JComboBox monthSelector; + static JComboBox typeSelector; + String[] frequency; + expenseRepPanel() { expenserMain = new ExpenserMain(); expenserMain.userAtHand = appFrame.user; + expenseRepPanel.Spending = expenserMain.userAtHand.getSpending(); this.setLayout(new BorderLayout()); + + expenseText = new JLabel("Expense Report"); expenseText.setFont(new Font(null, Font.PLAIN, 40)); expenseText.setHorizontalAlignment(JLabel.CENTER); - this.add(expenseText, BorderLayout.PAGE_START); + + gbConst = new GridBagConstraints(); + upperPanel = new JPanel(); + upperPanel.setLayout(new GridBagLayout()); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 4; + gbConst.insets = new Insets(20,0,20,0); + upperPanel.add(expenseText, gbConst); + + totalExpenseLbl = new JLabel("Total Expense"); + totalExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridwidth = 1; + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(totalExpenseLbl,gbConst); + + totalExpenseAmtLbl = new JLabel("0.00"); + totalExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalExpenseAmtLbl,gbConst); + + totalFilteredExpenseLbl = new JLabel("Expenses (Filtered)"); + totalFilteredExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 2; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalFilteredExpenseLbl,gbConst); + + totalFilteredExpenseAmtLbl = new JLabel("0.00"); + totalFilteredExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 3; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,20); + upperPanel.add(totalFilteredExpenseAmtLbl,gbConst); + + filterTxt = new JLabel("Apply a filter"); + filterTxt.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(filterTxt,gbConst); + + frequency = new String[]{"1", "12","24"}; + monthSelector = new JComboBox<>(frequency); + monthSelector.setFont(new Font(null, Font.PLAIN, 24)); + monthSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(monthSelector,gbConst); + + expenseRepPanel.typeSelector = new JComboBox<>(getSources(Spending).toArray()); + typeSelector.setFont(new Font(null, Font.PLAIN, 24)); + typeSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 2; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(typeSelector,gbConst); + + applyFilter = new JButton("Filter"); + applyFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { // Filters table results based on user selected categories like month and type. Repopulates table and summary information + if(e.getSource() == applyFilter) { + filteredSpending = filterExpenses(Spending,(String)typeSelector.getItemAt(typeSelector.getSelectedIndex()),(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + expenseRepPanel.model.setNumRows(filteredSpending.size()); + int i = 0; + double expenseSum = 0.00f; + for(Expense exp : filteredSpending) { + expenseRepPanel.spendingTable.setValueAt(exp.getSource(), i, 0); + expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); + expenseRepPanel.spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); + ++i; + expenseSum += exp.getAmount(); + } + totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); + } + } + }); + applyFilter.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 3; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(applyFilter,gbConst); + + this.add(upperPanel, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Frequency"}; - Spending = expenserMain.userAtHand.getSpending(); tableVals = new Object[Spending.size()][3]; // creating table with 3 columns and as many rows as there are data in Spending arraylist model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model spendingTable = new JTable(model) { @@ -1011,6 +1299,14 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { // Exports report to csv file + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == exportReport) { + expenserMain.exportReport("Expense Report"); + } + } + }); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -1022,6 +1318,43 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(lowerPanel, BorderLayout.SOUTH); } + private ArrayList getSources(ArrayList Ex) { + ArrayList sources = new ArrayList<>(); + for(Expense ex : Ex) { + sources.add(ex.getSource()); + } + return sources; + } + + /** + * Method responsible for getting filtered data's total expenses + * @param Ex ArrayList of Expense + * @return Sum of Expenses + */ + static double getExpense(ArrayList Ex) { + double sum = 0.00f; + for(Expense ex : Ex) { + sum += ex.getAmount(); + } + return sum; + } + + /** + * Method responsible for filtering data in table based on user's desired filters of source and frequency. + * @param exp Base Expense ArrayList + * @param source Source as String + * @param freq Frequency as String + * @return New ArrayList of filtered data + */ + static ArrayList filterExpenses(ArrayList exp, String source, String freq) { + ArrayList filteredExpenses = new ArrayList<>(); + for(Expense ex : exp) { + if(ex.getSource().equals(source) && (String.valueOf(ex.getFrequency()).equals(freq)) ) { + filteredExpenses.add(ex); + } + } + return filteredExpenses; + } } /** @@ -1051,7 +1384,7 @@ class detailedRepPanel extends JPanel { detaileReportTxt.setHorizontalAlignment(JLabel.CENTER); this.add(detaileReportTxt, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Type","Source","Amount", "Frequency"}; + columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; Spending = expenserMain.userAtHand.getSpending(); Income = expenserMain.userAtHand.getIncome(); tableVals = new Object[Spending.size()+Income.size()][4]; @@ -1082,7 +1415,13 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); - exportReport = new JButton("Export to CSV"); + exportReport = new JButton("Export to CSV"); // exports report to csv file + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + expenserMain.exportReport("Detailed Report"); + } + }); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -1093,4 +1432,5 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); this.add(lowerPanel, BorderLayout.SOUTH); } + } diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index c368ab5..1490cea 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,3 +1,10 @@ +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + public class ExpenserMain implements Expenser { public User userAtHand = null; @@ -38,9 +45,108 @@ public void PrintExpensebyType() { } + /** + * Method responsible for exporting reports using the export report button on the various report pages on the GUI + * @param reportTitle title of report as String + */ @Override public void exportReport(String reportTitle) { - + try { + // Creates new csv file with specified title + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); + String filePath = "src/"; + String fileName = reportTitle + dateTimeFormatter.format(LocalDateTime.now()); // title + time & date + String fileType = "csv"; + File reportFile = new File(filePath + fileName + "." + fileType); + FileOutputStream fileStream = new FileOutputStream(reportFile,true); + PrintWriter printWriter = new PrintWriter(fileStream); + + reportFile.createNewFile(); // creates file + + if (reportTitle.startsWith("Expense Report")) { // If title starts with Expense Report, the following will be written to file + printWriter.append("Total Income"); + printWriter.append(","); + printWriter.append("" + userAtHand.getBalance()); + printWriter.append("\n"); + printWriter.append("Total Expense"); + printWriter.append(","); + printWriter.append("" + userAtHand.getExpenses()); + printWriter.append("\n"); + printWriter.append("Filtered Expense"); + printWriter.append(","); + printWriter.append("" + expenseRepPanel.totalFilteredExpenseAmtLbl.getText()); + printWriter.append("\n"); + printWriter.append("Total Savings"); + printWriter.append(","); + printWriter.append("" + userAtHand.getMonthlySavings()); + printWriter.append("\n"); + printWriter.append("Source,Amount,Frequency\n"); + + for (Expense exp : expenseRepPanel.filteredSpending) { + printWriter.append("" + exp.getSource() + ","); + printWriter.append("" + exp.getAmount() + ","); + printWriter.append("" + exp.getFrequency() + "\n"); + } + } else if (reportTitle.startsWith("Income Report")) { // If title starts with Income Report, the following will be written to file + printWriter.append("Total Income"); + printWriter.append(","); + printWriter.append("" + userAtHand.getBalance()); + printWriter.append("\n"); + printWriter.append("Total Expense"); + printWriter.append(","); + printWriter.append("" + userAtHand.getExpenses()); + printWriter.append("\n"); + printWriter.append("Filtered Income"); + printWriter.append(","); + printWriter.append("" + incomeRepPanel.totalFilteredIncomeAmtLbl.getText()); + printWriter.append("\n"); + printWriter.append("Total Savings"); + printWriter.append(","); + printWriter.append("" + userAtHand.getMonthlySavings()); + printWriter.append("\n"); + printWriter.append("Source,Amount,Frequency\n"); + + for (Wage wage : incomeRepPanel.filteredIncomeList) { + printWriter.append("" + wage.getSource() + ","); + printWriter.append("" + wage.getAmount() + ","); + printWriter.append("" + wage.getMonth() + "\n"); + } + } else if (reportTitle.startsWith("Detailed Report")) { // If title starts with Detailed Report, the following will be written to file + printWriter.append("Total Income"); + printWriter.append(","); + printWriter.append("" + userAtHand.getBalance()); + printWriter.append("\n"); + printWriter.append("Total Expense"); + printWriter.append(","); + printWriter.append("" + userAtHand.getExpenses()); + printWriter.append("\n"); + printWriter.append("Total Savings"); + printWriter.append(","); + printWriter.append("" + userAtHand.getMonthlySavings()); + printWriter.append("\n"); + printWriter.append("Type,Source,Amount,Frequency / Month\n"); + + for (Wage wage : userAtHand.getIncome()) { + printWriter.append("Income,"); + printWriter.append("" + wage.getSource() + ","); + printWriter.append("" + wage.getAmount() + ","); + printWriter.append("" + wage.getMonth() + "\n"); + } + + for (Expense exp : userAtHand.getSpending()) { + printWriter.append("Expense,"); + printWriter.append("" + exp.getSource() + ","); + printWriter.append("" + exp.getAmount() + ","); + printWriter.append("" + exp.getFrequency() + "\n"); + } + } + printWriter.close(); // file closes and saves. + + + + } catch (IOException exception) { + exception.printStackTrace(); + } } @Override From 20307cf54f90790a635cd9fb4e61f612de377c4a Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Tue, 27 Jun 2023 19:26:57 -0400 Subject: [PATCH 028/123] Added methods to filter income and expense ArrayLists --- src/ExpenserMain.java | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 1490cea..67ef550 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -4,6 +4,7 @@ import java.io.PrintWriter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; public class ExpenserMain implements Expenser { public User userAtHand = null; @@ -174,4 +175,69 @@ public void updateMonthlySavings() { userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); } + + /** + * Method responsible for producing a filtered expense ArrayList based on the user's frequency of the expense + * @param exp Base Expense ArrayList + * @param freq Frequency as String + * @return New ArrayList of filtered data + */ + static ArrayList filterExpensesFreq(ArrayList exp, String freq) { + ArrayList filteredExpensesFreq = new ArrayList<>(); + for(Expense ex : exp) { + if(String.valueOf(ex.getFrequency()).equals(freq)) { + filteredExpensesFreq.add(ex); + } + } + return filteredExpensesFreq; + } + + /** + * Method responsible for producing a filtered expense ArrayList based on the user's source of the expense + * @param exp Base Expense ArrayList + * @param source Source as String + * @return New ArrayList of filtered data + */ + static ArrayList filterExpensesSource(ArrayList exp, String source) { + ArrayList filteredExpensesSource = new ArrayList<>(); + for(Expense ex : exp) { + if(ex.getSource().equals(source)) { + filteredExpensesSource.add(ex); + } + } + return filteredExpensesSource; + } + + /** + * Method responsible for producing a filtered income ArrayList based on the user's month of income + * @param wage Base Wage ArrayList + * @param month Month as String + * @return New ArrayList of filtered data + */ + static ArrayList filterIncomesMonth(ArrayList wage, String month) { + ArrayList filteredIncomesMonth = new ArrayList<>(); + for(Wage w : wage) { + if(w.getMonth().equals(month)) { + filteredIncomesMonth.add(w); + } + } + return filteredIncomesMonth; + } + + /** + * Method responsible for producing a filtered income ArrayList based on the user's source of the income + * @param wage Base Wage ArrayList + * @param source Source as String + * @return New ArrayList of filtered data + */ + static ArrayList filterIncomesSource(ArrayList wage, String source) { + ArrayList filteredIncomesSource = new ArrayList<>(); + for(Wage w : wage) { + if(w.getSource().equals(source)) { + filteredIncomesSource.add(w); + } + } + return filteredIncomesSource; + } + } From 670671df144aed14fb05dac8b61efb816d51a5b3 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 27 Jun 2023 20:02:26 -0400 Subject: [PATCH 029/123] Tweaking GUI to use new methods Temporary methods removed and replaced with new methods in ExpenserMain --- src/EWalletApp.java | 41 +++++------------------------------------ 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 7798f5f..cd1ba3d 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -1026,7 +1026,8 @@ class incomeRepPanel extends JPanel { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == applyFilter) { - filteredIncomeList = filterIncomes(Income,(String)typeSelector.getItemAt(typeSelector.getSelectedIndex()),(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + filteredIncomeList = + expenserMain.filterIncomesMonth(expenserMain.filterIncomesSource(expenserMain.userAtHand.getIncome(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); incomeRepPanel.model.setNumRows(filteredIncomeList.size()); int i = 0; double incomeSum = 0.00f; @@ -1123,23 +1124,6 @@ static double getIncome(ArrayList wage) { } return sum; } - - /** - * Method responsible for producing a filtered income ArrayList based on user's desired filters like source and month - * @param wage Base Income ArrayList - * @param source Source as String - * @param month Month as String - * @return Filtered ArrayList - */ - static ArrayList filterIncomes(ArrayList wage, String source, String month) { - ArrayList filteredWages = new ArrayList<>(); - for(Wage w : wage) { - if(w.getSource().equals(source) && (w.getMonth().equals(month) || month.equals("")) ) { - filteredWages.add(w); - } - } - return filteredWages; - } } /** @@ -1245,7 +1229,9 @@ class expenseRepPanel extends JPanel { @Override public void actionPerformed(ActionEvent e) { // Filters table results based on user selected categories like month and type. Repopulates table and summary information if(e.getSource() == applyFilter) { - filteredSpending = filterExpenses(Spending,(String)typeSelector.getItemAt(typeSelector.getSelectedIndex()),(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + filteredSpending = expenserMain.filterExpensesFreq + (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) + ,(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); expenseRepPanel.model.setNumRows(filteredSpending.size()); int i = 0; double expenseSum = 0.00f; @@ -1338,23 +1324,6 @@ static double getExpense(ArrayList Ex) { } return sum; } - - /** - * Method responsible for filtering data in table based on user's desired filters of source and frequency. - * @param exp Base Expense ArrayList - * @param source Source as String - * @param freq Frequency as String - * @return New ArrayList of filtered data - */ - static ArrayList filterExpenses(ArrayList exp, String source, String freq) { - ArrayList filteredExpenses = new ArrayList<>(); - for(Expense ex : exp) { - if(ex.getSource().equals(source) && (String.valueOf(ex.getFrequency()).equals(freq)) ) { - filteredExpenses.add(ex); - } - } - return filteredExpenses; - } } /** From a9ea2b79bfb7bc405b92e70b9794130d10266fef Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Thu, 29 Jun 2023 11:21:57 -0400 Subject: [PATCH 030/123] Adding file import file reading Adding file reading capabilty to software and wage object creation. --- src/EWalletApp.java | 13 +++++++++++ src/ExpenserMain.java | 50 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index cd1ba3d..4bda07c 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -747,6 +747,7 @@ public void actionPerformed(ActionEvent e) { */ class importPanel extends JPanel { + ExpenserMain expenserMain; GridBagConstraints gbConst; JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; JButton selectFileButton, importButton; @@ -756,6 +757,9 @@ class importPanel extends JPanel { File userFile; importPanel() { + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + fileChooser = new JFileChooser(); this.setLayout(new GridBagLayout()); @@ -825,6 +829,15 @@ public void actionPerformed(ActionEvent e) { // File chooser component this.add(descriptionLbl, gbConst); importButton = new JButton("Import"); + importButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { + System.out.println("Income Selected"); + expenserMain.loadIncomeFile(userFile.getAbsolutePath()); + } + } + }); gbConst.gridheight = 1; gbConst.gridx = 0; gbConst.gridy = 5; diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 67ef550..ce40264 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -1,7 +1,4 @@ -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; +import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -55,7 +52,7 @@ public void exportReport(String reportTitle) { try { // Creates new csv file with specified title DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); - String filePath = "src/"; + String filePath = ""; String fileName = reportTitle + dateTimeFormatter.format(LocalDateTime.now()); // title + time & date String fileType = "csv"; File reportFile = new File(filePath + fileName + "." + fileType); @@ -162,7 +159,48 @@ public boolean loadExpenseFile(String filePath) { @Override public boolean loadIncomeFile(String filePath) { - return false; + String lineText = ""; + BufferedReader bufferedLineReader = null; + BufferedReader bufferedTextReader = null; + File userFile = new File(filePath); + String source = "", month = "", amount = ""; + try { + int lines = 0; + bufferedLineReader = new BufferedReader(new FileReader(userFile)); + bufferedTextReader = new BufferedReader(new FileReader(userFile)); + while (bufferedLineReader.readLine() != null) { + lines++; + } + Wage wage; + for (int i = 0; i < lines; i++) { + lineText = bufferedTextReader.readLine(); + if( i == 0 && lineText.equalsIgnoreCase("source,amount,month")) { + System.out.println("File start setup correctly."); + } else { + source = ""; + month = ""; + amount = ""; + for(int a = 0; a < lineText.indexOf(',', 0); a++) { + source += lineText.charAt(a); + } + for(int b = lineText.indexOf(',') + 1; b < lineText.lastIndexOf(','); b++) { + amount += lineText.charAt(b); + } + for(int c = lineText.lastIndexOf(',') + 1; c < lineText.length(); c++) { + month += lineText.charAt(c); + } + System.out.println("Text read: " + source + "," + amount + "," + month); + wage = new Wage(source,Double.parseDouble(amount),month); + addMonthlyIncome(wage); + } + } + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + return false; + } + + return true; } @Override From 6f10831f584ec03b29d58e0cb4f5c33b48980bf9 Mon Sep 17 00:00:00 2001 From: Tbusk Date: Fri, 30 Jun 2023 04:46:59 -0400 Subject: [PATCH 031/123] Refactoring update table methods + updating table on import Tweaking how tables are updated. Creating new methods in ExpenserMain to handle updating of tables and values to reduce logic in EWalletApp.java. --- src/EWalletApp.java | 18 ++++++---- src/ExpenserMain.java | 84 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 4bda07c..22910eb 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -537,7 +537,7 @@ public void actionPerformed(ActionEvent e) { amountIncField.setText(""); // Update panel totals - incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",incomeRepPanel.getIncome(expenserMain.userAtHand.getIncome()))); + // incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",incomeRepPanel.getIncome(expenserMain.userAtHand.getIncome()))); // Update JComboBoxes if if(incomeRepPanel.typeSelector.getItemCount() > 0) { @@ -555,13 +555,13 @@ public void actionPerformed(ActionEvent e) { } - // Update Home Income + /*// Update Home Income expenserMain.userAtHand.setBalance(expenserMain.userAtHand.getBalance() + w.getAmount()); - expenserMain.updateMonthlySavings(); - homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",expenserMain.userAtHand.getBalance())); - homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", expenserMain.userAtHand.getMonthlySavings())); + expenserMain.updateMonthlySavings(); // added to updateIncomeValues + homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",expenserMain.userAtHand.getBalance())); // added to updateIncomeValues + homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", expenserMain.userAtHand.getMonthlySavings())); // added to updateIncomeValues - // update income table + // update income table // added to updateIncomeTable() incomeRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table int i = 0; for(Wage wage : expenserMain.userAtHand.getIncome()) { @@ -570,7 +570,9 @@ public void actionPerformed(ActionEvent e) { incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); ++i; } - + */ + expenserMain.updateIncomeTable(); + expenserMain.updateIncomeValues(w); // update detailed table by filling it in with wage and expense data int j = 0; incomeRepPanel.model.setNumRows(expenserMain.userAtHand.getIncome().size()); @@ -835,7 +837,9 @@ public void actionPerformed(ActionEvent e) { if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { System.out.println("Income Selected"); expenserMain.loadIncomeFile(userFile.getAbsolutePath()); + expenserMain.updateIncomeTable(); } + } }); gbConst.gridheight = 1; diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index ce40264..4ca7218 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -165,29 +165,29 @@ public boolean loadIncomeFile(String filePath) { File userFile = new File(filePath); String source = "", month = "", amount = ""; try { - int lines = 0; + int linesInFile = 0; bufferedLineReader = new BufferedReader(new FileReader(userFile)); bufferedTextReader = new BufferedReader(new FileReader(userFile)); while (bufferedLineReader.readLine() != null) { - lines++; + linesInFile++; } Wage wage; - for (int i = 0; i < lines; i++) { + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { lineText = bufferedTextReader.readLine(); - if( i == 0 && lineText.equalsIgnoreCase("source,amount,month")) { + if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { System.out.println("File start setup correctly."); } else { source = ""; month = ""; amount = ""; - for(int a = 0; a < lineText.indexOf(',', 0); a++) { - source += lineText.charAt(a); + for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { + source += lineText.charAt(sourceIndex); } - for(int b = lineText.indexOf(',') + 1; b < lineText.lastIndexOf(','); b++) { - amount += lineText.charAt(b); + for(int amountindex = lineText.indexOf(',') + 1; amountindex < lineText.lastIndexOf(','); amountindex++) { + amount += lineText.charAt(amountindex); } - for(int c = lineText.lastIndexOf(',') + 1; c < lineText.length(); c++) { - month += lineText.charAt(c); + for(int monthIndex = lineText.lastIndexOf(',') + 1; monthIndex < lineText.length(); monthIndex++) { + month += lineText.charAt(monthIndex); } System.out.println("Text read: " + source + "," + amount + "," + month); wage = new Wage(source,Double.parseDouble(amount),month); @@ -199,7 +199,6 @@ public boolean loadIncomeFile(String filePath) { } catch (IOException e) { return false; } - return true; } @@ -278,4 +277,67 @@ static ArrayList filterIncomesSource(ArrayList wage, String source) return filteredIncomesSource; } + /** + * A method that will update income table values based on adding of values through import or the add tool. + */ + public void updateIncomeTable() { + + incomeRepPanel.model.setNumRows(0); + for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { + incomeRepPanel.model.addRow(new Object[]{}); + } + + System.out.println(incomeRepPanel.model.getRowCount()); + int i = 0; + for(Wage wage : userAtHand.getIncome()) { + incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); + incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); + ++i; + } + } + + /** + * A method that will update detailed table values based on adding of values through import or the add tool. + */ + public void updateDetailedTable() { + + } + + /** + * A method that will update expense table values based on adding of values through import or the add tool. + */ + public void updateExpenseTable() { + + } + + /** + * A method that will update values based on adding of values through import or the add tool. + * Values on the home page, income page, and expense page will be updated with this. + */ + public void updateIncomeValues(Wage wage) { + incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); + userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); + updateMonthlySavings(); + homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",userAtHand.getBalance())); + homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); + } + + public void updateExpenseValues(Expense expense) { + + } + + /** + * A method that gets the total income for a user based on an inputted ArrayList of type wage. + * @param wage user's income ArrayList + * @return user's total income + */ + public double getTotalIncome(ArrayList wage) { + double sum = 0.00f; + for(Wage userWage : wage) { + sum += userWage.getAmount(); + } + return sum; + } + } From 36ae23c029b285a45851be8a100c5133e04eaafe Mon Sep 17 00:00:00 2001 From: Tbusk Date: Fri, 30 Jun 2023 05:05:21 -0400 Subject: [PATCH 032/123] Updating type filter in income report panel upon import The type filter in the income report panel will now populate when items are imported. --- src/EWalletApp.java | 18 +++--------------- src/ExpenserMain.java | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 22910eb..0b133d3 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -572,7 +572,7 @@ public void actionPerformed(ActionEvent e) { } */ expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(w); + expenserMain.updateIncomeValues(); // update detailed table by filling it in with wage and expense data int j = 0; incomeRepPanel.model.setNumRows(expenserMain.userAtHand.getIncome().size()); @@ -838,6 +838,7 @@ public void actionPerformed(ActionEvent e) { System.out.println("Income Selected"); expenserMain.loadIncomeFile(userFile.getAbsolutePath()); expenserMain.updateIncomeTable(); + expenserMain.updateIncomeValues(); } } @@ -1030,7 +1031,7 @@ class incomeRepPanel extends JPanel { gbConst.insets = new Insets(0,20,20,20); upperPanel.add(monthSelector,gbConst); - incomeRepPanel.typeSelector = new JComboBox<>(getSources(Income).toArray()); + incomeRepPanel.typeSelector = new JComboBox<>(expenserMain.getSources(Income).toArray()); typeSelector.setFont(new Font(null, Font.PLAIN, 24)); typeSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 2; @@ -1116,19 +1117,6 @@ public void actionPerformed(ActionEvent e) { // exports report to csv } - /** - * Method responsible for obtaining sources for the combobox selector - * @param wage Wage ArrayList - * @return ArrayList of Strings of sources - */ - private ArrayList getSources(ArrayList wage) { - ArrayList sources = new ArrayList<>(); - for(Wage w : wage) { - sources.add(w.getSource()); - } - return sources; - } - /** * Method responsible for obtaining total income information for filtered data * @param wage Filtered ArrayList for income diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 4ca7218..507ff66 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -191,7 +191,24 @@ public boolean loadIncomeFile(String filePath) { } System.out.println("Text read: " + source + "," + amount + "," + month); wage = new Wage(source,Double.parseDouble(amount),month); + userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); addMonthlyIncome(wage); + incomeRepPanel.typeSelector.addItem(source); + + if(incomeRepPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { + if (incomeRepPanel.typeSelector.getItemAt(i).equals(wage.getSource())) { + contains = true; + } + } + if (!contains) { + incomeRepPanel.typeSelector.addItem(wage.getSource()); + } + } else { + incomeRepPanel.typeSelector.addItem(wage.getSource()); + } + } } } catch (FileNotFoundException e) { @@ -282,12 +299,14 @@ static ArrayList filterIncomesSource(ArrayList wage, String source) */ public void updateIncomeTable() { + // Resetting row count - setting it to the income array size incomeRepPanel.model.setNumRows(0); + for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { incomeRepPanel.model.addRow(new Object[]{}); } - System.out.println(incomeRepPanel.model.getRowCount()); + // Updating what is displayed on the table int i = 0; for(Wage wage : userAtHand.getIncome()) { incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); @@ -315,9 +334,8 @@ public void updateExpenseTable() { * A method that will update values based on adding of values through import or the add tool. * Values on the home page, income page, and expense page will be updated with this. */ - public void updateIncomeValues(Wage wage) { + public void updateIncomeValues() { incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); - userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); updateMonthlySavings(); homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",userAtHand.getBalance())); homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); @@ -340,4 +358,18 @@ public double getTotalIncome(ArrayList wage) { return sum; } + /** + * Method responsible for obtaining sources for the combobox selector + * @param updatedWage Wage ArrayList + * @return ArrayList of Strings of sources + */ + public ArrayList getSources(ArrayList updatedWage) { + ArrayList sources = new ArrayList<>(); + + for(Wage wage : updatedWage) { + sources.add(wage.getSource()); + } + return sources; + } + } From 43aca32bee701780af0879f67d9751ef2f0189e0 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Fri, 30 Jun 2023 09:36:56 -0400 Subject: [PATCH 033/123] Updating detailed reports + adding comments + dialog boxes for import page Detailed reports page now contains imported income information. There are now comments explaining whats going on. Also, the buttons now contain basic logic with alerts if, for example, a user forgets to select a file, among others. --- src/EWalletApp.java | 40 +++++++++++------------------ src/ExpenserMain.java | 59 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 0b133d3..a205e37 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -536,9 +536,6 @@ public void actionPerformed(ActionEvent e) { monthComboBox.setSelectedItem(0); amountIncField.setText(""); - // Update panel totals - // incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",incomeRepPanel.getIncome(expenserMain.userAtHand.getIncome()))); - // Update JComboBoxes if if(incomeRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; @@ -555,22 +552,6 @@ public void actionPerformed(ActionEvent e) { } - /*// Update Home Income - expenserMain.userAtHand.setBalance(expenserMain.userAtHand.getBalance() + w.getAmount()); - expenserMain.updateMonthlySavings(); // added to updateIncomeValues - homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",expenserMain.userAtHand.getBalance())); // added to updateIncomeValues - homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", expenserMain.userAtHand.getMonthlySavings())); // added to updateIncomeValues - - // update income table // added to updateIncomeTable() - incomeRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table - int i = 0; - for(Wage wage : expenserMain.userAtHand.getIncome()) { - incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); - incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); - ++i; - } - */ expenserMain.updateIncomeTable(); expenserMain.updateIncomeValues(); // update detailed table by filling it in with wage and expense data @@ -779,13 +760,17 @@ class importPanel extends JPanel { this.add(importLbl, gbConst); selectFileButton = new JButton("File"); - selectFileButton.addActionListener(new ActionListener() { + selectFileButton.addActionListener(new ActionListener() { // When the select file button is pressed @Override public void actionPerformed(ActionEvent e) { // File chooser component if (e.getSource() == selectFileButton) { int userDecision = fileChooser.showOpenDialog(null); // opens file chooser window if(userDecision == JFileChooser.APPROVE_OPTION) { // if file is selected userFile = fileChooser.getSelectedFile(); + if(!userFile.getAbsolutePath().endsWith(".csv")){ // if user selects a non-csv file, the user will be alerted. + JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); + System.out.println("User selected a non csv file!"); + } System.out.println("The user selected: " + userFile.getAbsolutePath()); } else if (userDecision == JFileChooser.CANCEL_OPTION) { // if user backs out System.out.println("The user canceled the operation."); @@ -821,7 +806,7 @@ public void actionPerformed(ActionEvent e) { // File chooser component options.setFont(new Font(null, Font.PLAIN, 24)); this.add(options, gbConst); - descriptionLbl = new JLabel("Note: Only CSV files are supported.

Once you select a file, click the import button."); + descriptionLbl = new JLabel("Note: Only csv files are supported.

The format of the csv file matters.
The first line of the file needs to contain \"source,amount,month\" or
\"source,amount,frequency\", depending on the type

Once you select a file, click the import button."); gbConst.gridwidth = 2; gbConst.gridheight = 2; gbConst.gridx = 0; @@ -833,12 +818,17 @@ public void actionPerformed(ActionEvent e) { // File chooser component importButton = new JButton("Import"); importButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent e) { // When the import button is pressed if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { System.out.println("Income Selected"); - expenserMain.loadIncomeFile(userFile.getAbsolutePath()); - expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(); + if(userFile == null) { // if there isn't a file selected + JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); + } else { // when there is a csv file selected + expenserMain.loadIncomeFile(userFile.getAbsolutePath()); + expenserMain.updateIncomeTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateIncomeValues(); + } } } diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 507ff66..3b9a072 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -157,44 +157,67 @@ public boolean loadExpenseFile(String filePath) { return false; } + /** + * This is a method that loads information from a csv file. The file must start with "source,amount,month" in the first line as a minimum. + * The data will be added to wage objects and loaded into the program on the tables and total locations. + * @param filePath the path of the file that data will be taken from + * @return true if the program had no issues loading the data. false if the program encountered a problem. + */ @Override public boolean loadIncomeFile(String filePath) { + + // Initialization String lineText = ""; BufferedReader bufferedLineReader = null; BufferedReader bufferedTextReader = null; File userFile = new File(filePath); String source = "", month = "", amount = ""; + + try { int linesInFile = 0; bufferedLineReader = new BufferedReader(new FileReader(userFile)); bufferedTextReader = new BufferedReader(new FileReader(userFile)); - while (bufferedLineReader.readLine() != null) { + while (bufferedLineReader.readLine() != null) { // count lines in file linesInFile++; } Wage wage; - for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { - lineText = bufferedTextReader.readLine(); - if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { // loops through entirety of file + lineText = bufferedTextReader.readLine(); // reads each line and puts it into lineText + if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { // first line of file must match the String System.out.println("File start setup correctly."); - } else { + } + else { // Each line outside of the first will go through this operation + // resetting data after each line source = ""; month = ""; amount = ""; + + // Gets from start of line to the first occurence of the comma and stores it in source for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { source += lineText.charAt(sourceIndex); } + // Gets text starting after the first comma up until the next comma and stores it in amount for(int amountindex = lineText.indexOf(',') + 1; amountindex < lineText.lastIndexOf(','); amountindex++) { amount += lineText.charAt(amountindex); } + // Gets text starting after the last comma until the end of the line and stores it in month for(int monthIndex = lineText.lastIndexOf(',') + 1; monthIndex < lineText.length(); monthIndex++) { month += lineText.charAt(monthIndex); } + + // little loop that shows what was read (and will be added) to the program. System.out.println("Text read: " + source + "," + amount + "," + month); + + // Creates a new wage object from the data wage = new Wage(source,Double.parseDouble(amount),month); + + // Updates user balance userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); + // Adds wage object to user's wage ArrayList addMonthlyIncome(wage); - incomeRepPanel.typeSelector.addItem(source); + // Loop that adds items to the type filter dropdown in income reports page, and will not add repeats if(incomeRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { @@ -211,9 +234,9 @@ public boolean loadIncomeFile(String filePath) { } } - } catch (FileNotFoundException e) { + } catch (FileNotFoundException e) { // if file is not found, return false. return false; - } catch (IOException e) { + } catch (IOException e) { // if there is an IO problem (maybe operation interruption) return false; } return true; @@ -306,7 +329,7 @@ public void updateIncomeTable() { incomeRepPanel.model.addRow(new Object[]{}); } - // Updating what is displayed on the table + // Updating what is displayed on the table with new wage data int i = 0; for(Wage wage : userAtHand.getIncome()) { incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); @@ -320,6 +343,22 @@ public void updateIncomeTable() { * A method that will update detailed table values based on adding of values through import or the add tool. */ public void updateDetailedTable() { + // clears detailed table + detailedRepPanel.model.setNumRows(0); + + // re-adds rows based on number of wage objects + for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { + detailedRepPanel.model.addRow(new Object[]{}); + } + + int i = 0; + for(Wage wage : userAtHand.getIncome()) { // repopulates table with wage data + detailedRepPanel.detailedTable.setValueAt("Income", i, 0); + detailedRepPanel.detailedTable.setValueAt(wage.getSource(), i, 1); + detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); + detailedRepPanel.detailedTable.setValueAt(wage.getMonth(), i, 3); + ++i; + } } @@ -359,7 +398,7 @@ public double getTotalIncome(ArrayList wage) { } /** - * Method responsible for obtaining sources for the combobox selector + * Method responsible for obtaining sources for the income combobox selector * @param updatedWage Wage ArrayList * @return ArrayList of Strings of sources */ From a828043397925c28a5e93f80f9efed0dcaa1ae28 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Fri, 30 Jun 2023 09:45:13 -0400 Subject: [PATCH 034/123] Removed unused method Unused method removed. --- src/EWalletApp.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index a205e37..dc3f9df 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -1106,19 +1106,6 @@ public void actionPerformed(ActionEvent e) { // exports report to csv this.add(lowerPanel, BorderLayout.SOUTH); } - - /** - * Method responsible for obtaining total income information for filtered data - * @param wage Filtered ArrayList for income - * @return Total Filtered Income - */ - static double getIncome(ArrayList wage) { - double sum = 0.00f; - for(Wage w : wage) { - sum += w.getAmount(); - } - return sum; - } } /** From 9d4465c87cc549b083973a7c660126961540eef6 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sat, 1 Jul 2023 02:41:46 -0400 Subject: [PATCH 035/123] Adding feature: import expenses from csv + refactoring Users can now import expenses from csv files. Also, additional refactoring was done to improve readability and maintainability. Comments were added. --- src/EWalletApp.java | 103 ++++++------------------ src/ExpenserMain.java | 183 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 186 insertions(+), 100 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index dc3f9df..3f2c785 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -532,11 +532,8 @@ public void actionPerformed(ActionEvent e) { month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); Wage w = new Wage(source, amount, month); expenserMain.userAtHand.addMonthlyIncome(w); // adding it to the user's wage arraylist - nameIncField.setText(""); - monthComboBox.setSelectedItem(0); - amountIncField.setText(""); - // Update JComboBoxes if + // Adds item to combobox for type filter if name is unique if(incomeRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { @@ -551,28 +548,15 @@ public void actionPerformed(ActionEvent e) { incomeRepPanel.typeSelector.addItem(w.getSource()); } - + // Updating tables and values expenserMain.updateIncomeTable(); expenserMain.updateIncomeValues(); - // update detailed table by filling it in with wage and expense data - int j = 0; - incomeRepPanel.model.setNumRows(expenserMain.userAtHand.getIncome().size()); - detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table - for(Wage wge : expenserMain.userAtHand.getIncome()) { - detailedRepPanel.detailedTable.setValueAt("Income", j, 0); - detailedRepPanel.detailedTable.setValueAt(wge.getSource(), j, 1); - detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wge.getAmount()), j, 2); - detailedRepPanel.detailedTable.setValueAt(wge.getMonth(), j, 3); - ++j; - } + expenserMain.updateDetailedTable(); - for(Expense Ex : expenserMain.userAtHand.getSpending()) { - detailedRepPanel.detailedTable.setValueAt("Expense", j, 0); - detailedRepPanel.detailedTable.setValueAt(Ex.getSource(), j, 1); - detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Ex.getAmount()), j, 2); - detailedRepPanel.detailedTable.setValueAt(Ex.getFrequency(), j, 3); - ++j; - } + // Clearing fields + nameIncField.setText(""); + monthComboBox.setSelectedItem(0); + amountIncField.setText(""); } @@ -657,10 +641,9 @@ public void actionPerformed(ActionEvent e) { source = nameExpField.getText(); Expense Ex = new Expense(source, amount, yearlyFrequency); // new expense object expenserMain.addExpense(Ex); // adding it to the user's spending arraylist + expenserMain.updateExpenseValues(); - expenseRepPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",expenseRepPanel.getExpense(expenserMain.userAtHand.getSpending()))); - - // Update JComboBoxes + // Adds item to combobox for type filter if name is unique if(expenseRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { @@ -677,38 +660,8 @@ public void actionPerformed(ActionEvent e) { // update expense table and expenses on home - expenserMain.userAtHand.setExpenses(0.00f); - expenseRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table - int i = 0; - for(Expense Exp : expenserMain.userAtHand.getSpending()) { - expenserMain.userAtHand.setExpenses(expenserMain.userAtHand.getExpenses() + Exp.amount); - expenseRepPanel.spendingTable.setValueAt(Exp.getSource(), i, 0); - expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 1); - expenseRepPanel.spendingTable.setValueAt(Exp.getFrequency(), i, 2); - ++i; - } - expenserMain.updateMonthlySavings(); - homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",expenserMain.userAtHand.getExpenses())); - homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", expenserMain.userAtHand.getMonthlySavings())); - - // update detailed table by filling it in with wage and expense data - i = 0; - detailedRepPanel.model.addRow(new Object[]{}); // adding a blank row in the table - for(Expense Exp : expenserMain.userAtHand.getSpending()) { - detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); - detailedRepPanel.detailedTable.setValueAt(Exp.getSource(), i, 1); - detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",Exp.getAmount()), i, 2); - detailedRepPanel.detailedTable.setValueAt(Exp.getFrequency(), i, 3); - ++i; - } - - for(Wage wage : expenserMain.userAtHand.getIncome()) { - detailedRepPanel.detailedTable.setValueAt("Income", i, 0); - detailedRepPanel.detailedTable.setValueAt(wage.getSource(), i, 1); - detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); - detailedRepPanel.detailedTable.setValueAt(wage.getMonth(), i, 3); - ++i; - } + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); // Clearing fields nameExpField.setText(""); @@ -829,6 +782,16 @@ public void actionPerformed(ActionEvent e) { // When the import button is presse expenserMain.updateDetailedTable(); expenserMain.updateIncomeValues(); } + } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { + System.out.println("Expense Selected"); + if(userFile == null) { // if there isn't a file selected + JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); + } else { // when there is a csv file selected + expenserMain.loadExpenseFile(userFile.getAbsolutePath()); + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateExpenseValues(); + } } } @@ -1021,7 +984,7 @@ class incomeRepPanel extends JPanel { gbConst.insets = new Insets(0,20,20,20); upperPanel.add(monthSelector,gbConst); - incomeRepPanel.typeSelector = new JComboBox<>(expenserMain.getSources(Income).toArray()); + incomeRepPanel.typeSelector = new JComboBox<>(expenserMain.getIncomeSources(Income).toArray()); typeSelector.setFont(new Font(null, Font.PLAIN, 24)); typeSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 2; @@ -1198,7 +1161,7 @@ class expenseRepPanel extends JPanel { gbConst.insets = new Insets(0,20,20,20); upperPanel.add(monthSelector,gbConst); - expenseRepPanel.typeSelector = new JComboBox<>(getSources(Spending).toArray()); + expenseRepPanel.typeSelector = new JComboBox<>(expenserMain.getExpenseSources(Spending).toArray()); typeSelector.setFont(new Font(null, Font.PLAIN, 24)); typeSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 2; @@ -1286,26 +1249,6 @@ public void actionPerformed(ActionEvent e) { this.add(lowerPanel, BorderLayout.SOUTH); } - private ArrayList getSources(ArrayList Ex) { - ArrayList sources = new ArrayList<>(); - for(Expense ex : Ex) { - sources.add(ex.getSource()); - } - return sources; - } - - /** - * Method responsible for getting filtered data's total expenses - * @param Ex ArrayList of Expense - * @return Sum of Expenses - */ - static double getExpense(ArrayList Ex) { - double sum = 0.00f; - for(Expense ex : Ex) { - sum += ex.getAmount(); - } - return sum; - } } /** diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 3b9a072..075f277 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -20,27 +20,27 @@ public void addMonthlyIncome (Wage W) { @Override public void PrintFullreport() { - + // Not used } @Override public void PrintExpensereport() { - + // Not used } @Override public void PrintIncomereport() { - + // Not used } @Override public void PrintIncomereportbyTpe() { - + // Not used } @Override public void PrintExpensebyType() { - + // Not used } /** @@ -152,9 +152,87 @@ public Currency convertForeignCurrency(Currency C, double amount) { return null; } + /** + * This is a method that loads information from a csv file. The file must start with "source,amount,frequency" in the first line as a minimum. + * The data will be added to expense objects and loaded into the program on the tables and total locations. + * @param filePath the path of the file that data will be taken from + * @return true if the program had no issues loading the data. false if the program encountered a problem. + */ @Override public boolean loadExpenseFile(String filePath) { - return false; + // Initialization + String lineText = ""; + BufferedReader bufferedLineReader = null; + BufferedReader bufferedTextReader = null; + File userFile = new File(filePath); + String source = "", frequency = "", amount = ""; + + try { + int linesInFile = 0; + bufferedLineReader = new BufferedReader(new FileReader(userFile)); + bufferedTextReader = new BufferedReader(new FileReader(userFile)); + while (bufferedLineReader.readLine() != null) { // count lines in file + linesInFile++; + } + Expense expense; + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { // loops through entirety of file + lineText = bufferedTextReader.readLine(); // reads each line and puts it into lineText + if(lineIndex == 0 && lineText.trim().equals("source,amount,frequency")) { // first line of file must match the String + System.out.println("File start setup correctly."); + } + else if (lineIndex > 0){ // Each line outside of the first will go through this operation + // resetting data after each line + source = ""; + frequency = ""; + amount = ""; + + // Gets from start of line to the first occurence of the comma and stores it in source + for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { + source += lineText.charAt(sourceIndex); + } + // Gets text starting after the first comma up until the next comma and stores it in amount + for(int amountIndex = lineText.indexOf(',') + 1; amountIndex < lineText.lastIndexOf(','); amountIndex++) { + amount += lineText.charAt(amountIndex); + } + // Gets text starting after the last comma until the end of the line and stores it in frequency + for(int freqIndex = lineText.lastIndexOf(',') + 1; freqIndex < lineText.length(); freqIndex++) { + frequency += lineText.charAt(freqIndex); + } + + // little loop that shows what was read (and will be added) to the program. + System.out.println("Text read: " + source + "," + amount + "," + frequency); + + // Creates a new wage object from the data + expense = new Expense(source,Double.parseDouble(amount),Integer.valueOf(frequency)); + + // Updates user expenses + userAtHand.setExpenses(userAtHand.getExpenses() + expense.getAmount()); + // Adds expense object to user's spending ArrayList + addExpense(expense); + + // Loop that adds items to the type filter dropdown in income reports page, and will not add repeats + if(expenseRepPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { + if (expenseRepPanel.typeSelector.getItemAt(i).equals(expense.getSource())) { + contains = true; + } + } + if (!contains) { + expenseRepPanel.typeSelector.addItem(expense.getSource()); + } + } else { + expenseRepPanel.typeSelector.addItem(expense.getSource()); + } + + } + } + } catch (FileNotFoundException e) { // if file is not found, return false. + return false; + } catch (IOException e) { // if there is an IO problem (maybe operation interruption) + return false; + } + return true; } /** @@ -254,7 +332,7 @@ public void updateMonthlySavings() { /** - * Method responsible for producing a filtered expense ArrayList based on the user's frequency of the expense + * Produces a filtered expense ArrayList based on the user's frequency of the expense * @param exp Base Expense ArrayList * @param freq Frequency as String * @return New ArrayList of filtered data @@ -270,7 +348,7 @@ static ArrayList filterExpensesFreq(ArrayList exp, String freq } /** - * Method responsible for producing a filtered expense ArrayList based on the user's source of the expense + * Produces a filtered expense ArrayList based on the user's source of the expense * @param exp Base Expense ArrayList * @param source Source as String * @return New ArrayList of filtered data @@ -286,7 +364,7 @@ static ArrayList filterExpensesSource(ArrayList exp, String so } /** - * Method responsible for producing a filtered income ArrayList based on the user's month of income + * Produces a filtered income ArrayList based on the user's month of income * @param wage Base Wage ArrayList * @param month Month as String * @return New ArrayList of filtered data @@ -318,7 +396,7 @@ static ArrayList filterIncomesSource(ArrayList wage, String source) } /** - * A method that will update income table values based on adding of values through import or the add tool. + * Updates income table values based on adding of values through import or the add tool. */ public void updateIncomeTable() { @@ -329,9 +407,12 @@ public void updateIncomeTable() { incomeRepPanel.model.addRow(new Object[]{}); } + userAtHand.setBalance(0.00f); + // Updating what is displayed on the table with new wage data int i = 0; for(Wage wage : userAtHand.getIncome()) { + userAtHand.setBalance(userAtHand.getBalance() + wage.amount); incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); @@ -340,14 +421,14 @@ public void updateIncomeTable() { } /** - * A method that will update detailed table values based on adding of values through import or the add tool. + * Updates detailed table values based on adding of values through import or the add tool. */ public void updateDetailedTable() { // clears detailed table detailedRepPanel.model.setNumRows(0); // re-adds rows based on number of wage objects - for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { + for(int j = 0; j < userAtHand.getIncome().size() + userAtHand.getSpending().size(); j++ ) { detailedRepPanel.model.addRow(new Object[]{}); } @@ -360,32 +441,68 @@ public void updateDetailedTable() { ++i; } + for(Expense expense : userAtHand.getSpending()) { // repopulates table with expense data + detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); + detailedRepPanel.detailedTable.setValueAt(expense.getSource(), i, 1); + detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); + detailedRepPanel.detailedTable.setValueAt(expense.getFrequency(), i, 3); + ++i; + } + } /** - * A method that will update expense table values based on adding of values through import or the add tool. + * Updates expense table values based on adding of values through import or the add tool. */ public void updateExpenseTable() { + // Resetting row count - setting it to the income array size + expenseRepPanel.model.setNumRows(0); + + for(int j = 0; j < userAtHand.getSpending().size(); j++ ) { + expenseRepPanel.model.addRow(new Object[]{}); + } + + // Updating what is displayed on the table with new wage data + userAtHand.setExpenses(0.00f); + int i = 0; + for(Expense expense : userAtHand.getSpending()) { + userAtHand.setExpenses(userAtHand.getExpenses() + expense.amount); + expenseRepPanel.spendingTable.setValueAt(expense.getSource(), i, 0); + expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); + expenseRepPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); + ++i; + } } /** - * A method that will update values based on adding of values through import or the add tool. + * Updates income values through import or the add tool * Values on the home page, income page, and expense page will be updated with this. */ public void updateIncomeValues() { - incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); + userAtHand.setExpenses(getExpense(userAtHand.getSpending())); + userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); updateMonthlySavings(); + incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",userAtHand.getBalance())); homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); } - public void updateExpenseValues(Expense expense) { - + /** + * Updates expense values through import or the add tool + * Values on the home page, income page, and expense page will be updated with this. + */ + public void updateExpenseValues() { + userAtHand.setExpenses(getExpense(userAtHand.getSpending())); + userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); + updateMonthlySavings(); + expenseRepPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); + homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",getExpense(userAtHand.getSpending()))); + homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.monthlysavings)); } /** - * A method that gets the total income for a user based on an inputted ArrayList of type wage. + * Gets the total income for a user based on an inputted ArrayList of type wage. * @param wage user's income ArrayList * @return user's total income */ @@ -398,11 +515,11 @@ public double getTotalIncome(ArrayList wage) { } /** - * Method responsible for obtaining sources for the income combobox selector + * Obtains sources for the income combobox selector * @param updatedWage Wage ArrayList * @return ArrayList of Strings of sources */ - public ArrayList getSources(ArrayList updatedWage) { + public ArrayList getIncomeSources(ArrayList updatedWage) { ArrayList sources = new ArrayList<>(); for(Wage wage : updatedWage) { @@ -411,4 +528,30 @@ public ArrayList getSources(ArrayList updatedWage) { return sources; } + /** + * Gets expense sources for the expense combobox selector + * @param expenses ArrayList of Expenses + * @return ArrayList of Sources + */ + public ArrayList getExpenseSources(ArrayList expenses) { + ArrayList sources = new ArrayList<>(); + for(Expense exp : expenses) { + sources.add(exp.getSource()); + } + return sources; + } + + /** + * Gets total expenses + * @param Ex ArrayList of Spending (expense) + * @return Sum of Expenses + */ + public double getExpense(ArrayList Ex) { + double sum = 0.00f; + for(Expense ex : Ex) { + sum += ex.getAmount(); + } + return sum; + } + } From b175676d76ec65429be376784806c1a4afaa6b4c Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Thu, 6 Jul 2023 16:44:18 -0400 Subject: [PATCH 036/123] Added Login Page GUI --- src/EWalletApp.java | 84 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 3f2c785..edf1bcc 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -139,7 +139,7 @@ class appFrame extends JFrame { ExpenserMain expenserMain; JMenuBar navMenuBar; JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav; // different pages + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav; // different pages appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -149,7 +149,8 @@ class appFrame extends JFrame { user = new User("Kevin", "Abc!1234"); // temporary solution until login is set up expenserMain = new ExpenserMain(); expenserMain.userAtHand = user; - + + loginPanel lPanel = new loginPanel(); homePanel hPanel = new homePanel(); addItemPanel addItmPanel = new addItemPanel(); importPanel impPanel = new importPanel(); @@ -300,6 +301,27 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); + + loginNav = new JMenuItem("

Login"); // Add Items Page + loginNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(lPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); // Updating font size of menu and menu items navMenu.setFont(new Font(null, Font.PLAIN, 24)); @@ -310,6 +332,7 @@ public void mouseReleased(MouseEvent e) { incomeReportNav.setFont(new Font(null, Font.PLAIN, 20)); expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); + loginNav.setFont(new Font(null, Font.PLAIN, 20)); // Adding items to the navigation menu navMenu.add(homeNav); @@ -319,7 +342,9 @@ public void mouseReleased(MouseEvent e) { navMenu.add(incomeReportNav); navMenu.add(expenseReportNav); navMenu.add(detailedReportNav); + navMenu.add(loginNav); navMenuBar.add(navMenu); + this.setJMenuBar(navMenuBar); this.setLayout(new CardLayout()); @@ -1328,3 +1353,58 @@ public void actionPerformed(ActionEvent e) { } } + +class loginPanel extends JPanel { + JLabel usernameLbl, passwordLbl, loginLbl; + GridBagConstraints gbConst; + JTextField usernameIncField, passwordIncField; + JPanel usernamePane, passwordPane; + + loginPanel() { + loginLbl = new JLabel("LOGIN"); + usernameLbl = new JLabel("Username: "); + passwordLbl = new JLabel("Password: "); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + passwordIncField = new JTextField(); + passwordIncField.setPreferredSize(new Dimension(200, 40)); + usernameIncField = new JTextField(); + usernameIncField.setPreferredSize(new Dimension(200, 40)); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(-150,20,60,20); + loginLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(loginLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(-20,30,30,30); + passwordIncField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(passwordIncField, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(-124,30,30,30); + usernameIncField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(usernameIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(-5,-300,60,20); + passwordLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(passwordLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(-100,-300,60,20); + usernameLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(usernameLbl, gbConst); + + + } +} From 07024f5b76c8c68b8b91dd08d9b249c6481752d5 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Thu, 6 Jul 2023 17:27:18 -0400 Subject: [PATCH 037/123] Fixed layout and added button --- src/EWalletApp.java | 60 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index edf1bcc..3ab128c 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -139,7 +139,7 @@ class appFrame extends JFrame { ExpenserMain expenserMain; JMenuBar navMenuBar; JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav; // different pages + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; // different pages appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -322,6 +322,27 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); + + createAccNav = new JMenuItem("

Create Account"); // Add Items Page + createAccNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(lPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); // Updating font size of menu and menu items navMenu.setFont(new Font(null, Font.PLAIN, 24)); @@ -333,6 +354,7 @@ public void mouseReleased(MouseEvent e) { expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); loginNav.setFont(new Font(null, Font.PLAIN, 20)); + createAccNav.setFont(new Font(null, Font.PLAIN, 20)); // Adding items to the navigation menu navMenu.add(homeNav); @@ -343,6 +365,7 @@ public void mouseReleased(MouseEvent e) { navMenu.add(expenseReportNav); navMenu.add(detailedReportNav); navMenu.add(loginNav); + navMenu.add(createAccNav); navMenuBar.add(navMenu); @@ -1358,12 +1381,13 @@ class loginPanel extends JPanel { JLabel usernameLbl, passwordLbl, loginLbl; GridBagConstraints gbConst; JTextField usernameIncField, passwordIncField; - JPanel usernamePane, passwordPane; + JButton loginBtn; loginPanel() { loginLbl = new JLabel("LOGIN"); usernameLbl = new JLabel("Username: "); passwordLbl = new JLabel("Password: "); + loginBtn = new JButton("Login"); gbConst = new GridBagConstraints(); this.setLayout(new GridBagLayout()); @@ -1375,36 +1399,44 @@ class loginPanel extends JPanel { gbConst.gridx = 0; gbConst.gridy = 0; gbConst.gridwidth = 2; - gbConst.insets = new Insets(-150,20,60,20); + gbConst.insets = new Insets(20,10,20,40); loginLbl.setFont(new Font(null, Font.PLAIN, 44)); this.add(loginLbl, gbConst); gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(-20,30,30,30); + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(0,5,20,30); passwordIncField.setFont(new Font(null, Font.PLAIN, 28)); this.add(passwordIncField, gbConst); - + gbConst.gridx = 1; gbConst.gridy = 1; - gbConst.insets = new Insets(-124,30,30,30); + gbConst.insets = new Insets(0,5,20,30); usernameIncField.setFont(new Font(null, Font.PLAIN, 28)); this.add(usernameIncField, gbConst); - + gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(-5,-300,60,20); + gbConst.gridy = 2; + gbConst.insets = new Insets(0,0,20,20); passwordLbl.setFont(new Font(null, Font.PLAIN, 44)); this.add(passwordLbl, gbConst); - + gbConst.gridx = 0; gbConst.gridy = 1; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(-100,-300,60,20); + gbConst.insets = new Insets(0,0,20,20); usernameLbl.setFont(new Font(null, Font.PLAIN, 44)); this.add(usernameLbl, gbConst); + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + loginBtn.setFont(new Font(null, Font.PLAIN, 28)); + loginBtn.setPreferredSize(new Dimension(150,60)); + this.add(loginBtn, gbConst); + } } + From 4b751c940256346c75c2ccf210cd0802feda602c Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Sat, 8 Jul 2023 16:10:44 -0400 Subject: [PATCH 038/123] Added create account gui. --- src/EWalletApp.java | 103 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index edf1bcc..ebf8f93 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -139,7 +139,7 @@ class appFrame extends JFrame { ExpenserMain expenserMain; JMenuBar navMenuBar; JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav; // different pages + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; // different pages appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -151,6 +151,7 @@ class appFrame extends JFrame { expenserMain.userAtHand = user; loginPanel lPanel = new loginPanel(); + createAccountPanel createAccPanel = new createAccountPanel(); homePanel hPanel = new homePanel(); addItemPanel addItmPanel = new addItemPanel(); importPanel impPanel = new importPanel(); @@ -322,6 +323,27 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); + + createAccNav = new JMenuItem("

Create Account"); // Add Items Page + createAccNav.addMouseListener(new MouseAdapter() { + // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(createAccPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); // Updating font size of menu and menu items navMenu.setFont(new Font(null, Font.PLAIN, 24)); @@ -333,6 +355,7 @@ public void mouseReleased(MouseEvent e) { expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); loginNav.setFont(new Font(null, Font.PLAIN, 20)); + createAccNav.setFont(new Font(null, Font.PLAIN, 20)); // Adding items to the navigation menu navMenu.add(homeNav); @@ -343,6 +366,7 @@ public void mouseReleased(MouseEvent e) { navMenu.add(expenseReportNav); navMenu.add(detailedReportNav); navMenu.add(loginNav); + navMenu.add(createAccNav); navMenuBar.add(navMenu); @@ -1408,3 +1432,80 @@ class loginPanel extends JPanel { } } + +class createAccountPanel extends JPanel { + JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; + GridBagConstraints gbConst; + JTextField usernameField, passwordField, confPasswordField; + JButton createAccBtn; + + createAccountPanel() { + usernameLbl = new JLabel("Enter Username:"); + passwordLbl = new JLabel("Enter Password:"); + confPasswordLbl = new JLabel("Confirm Password:"); + createAccLbl = new JLabel("Create Account"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + usernameField = new JTextField(); + usernameField.setPreferredSize(new Dimension(200, 40)); + passwordField = new JTextField(); + passwordField.setPreferredSize(new Dimension(200, 40)); + confPasswordField = new JTextField(); + confPasswordField.setPreferredSize(new Dimension(200, 40)); + + createAccBtn = new JButton("Create Account"); + createAccBtn.setPreferredSize(new Dimension(200, 40)); + + gbConst.gridx = 1; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(0,20,40,20); + createAccLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(createAccLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,40,40,0); + usernameLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(usernameLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 1; + gbConst.insets = new Insets(20,0,40,40); + usernameField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(usernameField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,40,40,0); + passwordLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(passwordLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,0,40,40); + passwordField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(passwordField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(0,40,40,0); + confPasswordLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(confPasswordLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,0,40,40); + confPasswordField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(confPasswordField, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 4; + gbConst.insets = new Insets(20, 20, 20, 20); + createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); + this.add(createAccBtn, gbConst); + + } + +} From 3b2aa89a7cc78de92157f94e305b7199c1566c6b Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Tue, 11 Jul 2023 19:19:16 -0400 Subject: [PATCH 039/123] updated with new logins --- src/UserCredentials.csv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/UserCredentials.csv b/src/UserCredentials.csv index eb92047..b9b99f1 100644 --- a/src/UserCredentials.csv +++ b/src/UserCredentials.csv @@ -1 +1,3 @@ admin, Password!123, +Test1,FirstTest1!, +Test2,SecondTest!2, From 39e0ea7f24f5d36ce65414dd2b9efd58057e8dd7 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Tue, 11 Jul 2023 19:23:54 -0400 Subject: [PATCH 040/123] Added functionality to create account gui and updated cvs file with test --- src/EWalletApp.java | 21 +++++++++++++++++++-- src/UserCredentials.csv | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index c2da0b0..36171ec 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -17,7 +17,7 @@ public class EWalletApp { //this is the app class, has the GUI and create one object of your expense calculator class. The expense calculator class is the implementation of the Expenser interface - private ArrayList AllData; + //private ArrayList AllData; /** * Method responsible for creating a user account. It adds username and password to a UserCredentials.csv file. @@ -28,7 +28,7 @@ public void CreateUser(String username, String password) { if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { // If there are no repeat usernames and password is valid, a new account will be created and stored. User user = new User(username, password); - AllData.add(user); + //AllData.add(user); try { // Writes username and password to file in csv format FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); @@ -1442,10 +1442,12 @@ class loginPanel extends JPanel { } class createAccountPanel extends JPanel { + EWalletApp eWalletApp = new EWalletApp(); JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; GridBagConstraints gbConst; JTextField usernameField, passwordField, confPasswordField; JButton createAccBtn; + String username, password, confPassword; createAccountPanel() { usernameLbl = new JLabel("Enter Username:"); @@ -1514,6 +1516,21 @@ class createAccountPanel extends JPanel { createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); this.add(createAccBtn, gbConst); + createAccBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(e.getSource() == createAccBtn) { + if(usernameField.getText().length() > 0 && passwordField.getText().length() > 0 && confPasswordField.getText().length() > 0) { + username = usernameField.getText(); + password = passwordField.getText(); + confPassword = confPasswordField.getText(); + if(confPassword.equals(password)) { + eWalletApp.CreateUser(username, password); + } + } + } + } + }); + } } diff --git a/src/UserCredentials.csv b/src/UserCredentials.csv index b9b99f1..f4ce4f2 100644 --- a/src/UserCredentials.csv +++ b/src/UserCredentials.csv @@ -1,3 +1,4 @@ admin, Password!123, Test1,FirstTest1!, Test2,SecondTest!2, +Test3,ThirdTest3!, From e9028c20d4782bf3070b6f749f2d3af4d1bd934a Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Tue, 11 Jul 2023 20:43:38 -0400 Subject: [PATCH 041/123] tested create account feature --- src/UserCredentials.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/src/UserCredentials.csv b/src/UserCredentials.csv index f4ce4f2..720b772 100644 --- a/src/UserCredentials.csv +++ b/src/UserCredentials.csv @@ -2,3 +2,4 @@ admin, Password!123, Test1,FirstTest1!, Test2,SecondTest!2, Test3,ThirdTest3!, +Test4,FourthTest!4, From 89e4d5dad0872792c3cc49ef064884f6ce886ac2 Mon Sep 17 00:00:00 2001 From: EvanSchulte Date: Tue, 11 Jul 2023 21:36:09 -0400 Subject: [PATCH 042/123] Added login feature --- src/EWalletApp.java | 56 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 36171ec..9f88ee9 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -17,7 +17,7 @@ public class EWalletApp { //this is the app class, has the GUI and create one object of your expense calculator class. The expense calculator class is the implementation of the Expenser interface - //private ArrayList AllData; + private ArrayList AllData = new ArrayList<>(); /** * Method responsible for creating a user account. It adds username and password to a UserCredentials.csv file. @@ -28,7 +28,7 @@ public void CreateUser(String username, String password) { if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { // If there are no repeat usernames and password is valid, a new account will be created and stored. User user = new User(username, password); - //AllData.add(user); + AllData.add(user); try { // Writes username and password to file in csv format FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); @@ -44,6 +44,46 @@ public void CreateUser(String username, String password) { } } } + + public boolean CheckUsername(String username) { + boolean flag = false; + String savedUser; + + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + while(scnr.hasNextLine()) { + savedUser = scnr.nextLine(); + if(savedUser.indexOf(username) != -1) { + flag = true; + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return flag; + } + + public boolean CheckPassword(String password) { + boolean flag = false; + String savedPass; + + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + while(scnr.hasNextLine()) { + savedPass = scnr.nextLine(); + if(savedPass.indexOf(password) != -1) { + flag = true; + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return flag; + } /** * Method that checks to see if a username exists in UserCredentials.csv @@ -1379,10 +1419,12 @@ public void actionPerformed(ActionEvent e) { } class loginPanel extends JPanel { + EWalletApp eWalletApp = new EWalletApp(); JLabel usernameLbl, passwordLbl, loginLbl; GridBagConstraints gbConst; JTextField usernameIncField, passwordIncField; JButton loginBtn; + String username, password; loginPanel() { loginLbl = new JLabel("LOGIN"); @@ -1437,6 +1479,16 @@ class loginPanel extends JPanel { loginBtn.setPreferredSize(new Dimension(150,60)); this.add(loginBtn, gbConst); + loginBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + username = usernameIncField.getText(); + password = passwordIncField.getText(); + if(eWalletApp.CheckUsername(username) == true && eWalletApp.CheckPassword(password) == true) { + System.out.println("Login Successsful"); + } + } + }); + } } From bc16193131a3b450692aac93ed662f688e7534ef Mon Sep 17 00:00:00 2001 From: Tbusk Date: Wed, 12 Jul 2023 05:51:49 -0400 Subject: [PATCH 043/123] Added message dialogs + fixed login feature + cleared fields after creation and login --- src/EWalletApp.java | 47 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 9f88ee9..c0916ca 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -44,7 +44,9 @@ public void CreateUser(String username, String password) { } } } - + + + public boolean CheckUsername(String username) { boolean flag = false; String savedUser; @@ -65,18 +67,26 @@ public boolean CheckUsername(String username) { return flag; } - public boolean CheckPassword(String password) { + public boolean CheckPassword(String username,String password) { boolean flag = false; - String savedPass; + String lineTxt; try { FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); Scanner scnr = new Scanner(fileInputStream); while(scnr.hasNextLine()) { - savedPass = scnr.nextLine(); - if(savedPass.indexOf(password) != -1) { - flag = true; + lineTxt = scnr.nextLine(); + if(lineTxt.indexOf(username) != -1) { + if((lineTxt.indexOf(username) + username.length() + 1) == lineTxt.indexOf(password)) { + for(int i = 0; i < AllData.size(); i++) { + if(AllData.get(i).getUsername().equals(username)) { + appFrame.user = AllData.get(i); + } + } + flag = true; + break; + } } } } catch (FileNotFoundException e) { @@ -186,7 +196,7 @@ class appFrame extends JFrame { this.setMinimumSize(new Dimension(900,700)); this.setTitle("EWallet Application"); - user = new User("Kevin", "Abc!1234"); // temporary solution until login is set up + user = new User("Default", "TempPassword!123"); // Default User. expenserMain = new ExpenserMain(); expenserMain.userAtHand = user; @@ -1483,8 +1493,13 @@ class loginPanel extends JPanel { public void actionPerformed(ActionEvent e) { username = usernameIncField.getText(); password = passwordIncField.getText(); - if(eWalletApp.CheckUsername(username) == true && eWalletApp.CheckPassword(password) == true) { + if(eWalletApp.CheckUsername(username) == true && eWalletApp.CheckPassword(username, password) == true) { + usernameIncField.setText(""); + passwordIncField.setText(""); System.out.println("Login Successsful"); + JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); + } else { + JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); } } }); @@ -1571,12 +1586,22 @@ class createAccountPanel extends JPanel { createAccBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(e.getSource() == createAccBtn) { + username = usernameField.getText(); + password = passwordField.getText(); + confPassword = confPasswordField.getText(); if(usernameField.getText().length() > 0 && passwordField.getText().length() > 0 && confPasswordField.getText().length() > 0) { - username = usernameField.getText(); - password = passwordField.getText(); - confPassword = confPasswordField.getText(); if(confPassword.equals(password)) { eWalletApp.CreateUser(username, password); + if(eWalletApp.checkForRepeatUsernames(usernameField.getText())) { + JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); + } else { + JOptionPane.showMessageDialog(null, "User created successfully."); + usernameField.setText(""); + passwordField.setText(""); + confPasswordField.setText(""); + } + } else { + JOptionPane.showMessageDialog(null, "Passwords do not match!"); } } } From 6e5e9522a8a044b9afdb861f8e99f0bc81bd34df Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Wed, 12 Jul 2023 07:29:01 -0400 Subject: [PATCH 044/123] Fixing account creation bug Fixing a bug with account creation that resulted in fields not being read correctly. --- src/EWalletApp.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index c0916ca..11a1879 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -1493,10 +1493,10 @@ class loginPanel extends JPanel { public void actionPerformed(ActionEvent e) { username = usernameIncField.getText(); password = passwordIncField.getText(); - if(eWalletApp.CheckUsername(username) == true && eWalletApp.CheckPassword(username, password) == true) { + if(eWalletApp.CheckUsername(username) && eWalletApp.CheckPassword(username, password)) { usernameIncField.setText(""); passwordIncField.setText(""); - System.out.println("Login Successsful"); + System.out.println("Login Successful"); JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); } else { JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); @@ -1512,7 +1512,7 @@ class createAccountPanel extends JPanel { EWalletApp eWalletApp = new EWalletApp(); JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; GridBagConstraints gbConst; - JTextField usernameField, passwordField, confPasswordField; + static JTextField usernameField, passwordField, confPasswordField; JButton createAccBtn; String username, password, confPassword; @@ -1591,10 +1591,10 @@ public void actionPerformed(ActionEvent e) { confPassword = confPasswordField.getText(); if(usernameField.getText().length() > 0 && passwordField.getText().length() > 0 && confPasswordField.getText().length() > 0) { if(confPassword.equals(password)) { - eWalletApp.CreateUser(username, password); if(eWalletApp.checkForRepeatUsernames(usernameField.getText())) { JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); } else { + eWalletApp.CreateUser(username, password); JOptionPane.showMessageDialog(null, "User created successfully."); usernameField.setText(""); passwordField.setText(""); @@ -1603,6 +1603,8 @@ public void actionPerformed(ActionEvent e) { } else { JOptionPane.showMessageDialog(null, "Passwords do not match!"); } + } else { + JOptionPane.showMessageDialog(null,"Not all fields filled out. Please fill them out."); } } } From c0035e6e35ed65afbbf5a4781f455c603b1a118e Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 16 Mar 2025 21:24:42 -0400 Subject: [PATCH 045/123] Removing comments --- src/EWalletApp.java | 169 ++++++++++-------------------------------- src/Expense.java | 30 +------- src/Expenser.java | 25 +------ src/ExpenserMain.java | 155 ++++++-------------------------------- src/User.java | 78 +------------------ src/Wage.java | 26 +------ 6 files changed, 78 insertions(+), 405 deletions(-) diff --git a/src/EWalletApp.java b/src/EWalletApp.java index 11a1879..7095d0b 100644 --- a/src/EWalletApp.java +++ b/src/EWalletApp.java @@ -16,21 +16,15 @@ import java.util.regex.Pattern; public class EWalletApp { - //this is the app class, has the GUI and create one object of your expense calculator class. The expense calculator class is the implementation of the Expenser interface private ArrayList AllData = new ArrayList<>(); - /** - * Method responsible for creating a user account. It adds username and password to a UserCredentials.csv file. - * @param username user's desired username - * @param password user's desired password - */ public void CreateUser(String username, String password) { - if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { // If there are no repeat usernames and password is valid, a new account will be created and stored. + if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { User user = new User(username, password); AllData.add(user); - try { // Writes username and password to file in csv format + try { FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); PrintWriter printWriter = new PrintWriter(fileOutputStream); printWriter.append(username); @@ -95,34 +89,29 @@ public boolean CheckPassword(String username,String password) { return flag; } - /** - * Method that checks to see if a username exists in UserCredentials.csv - * @param username user's desired username as String - * @return if username is found, returns true. Otherwise, it will return false. - */ public boolean checkForRepeatUsernames(String username) { try { FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); Scanner scnr = new Scanner(fileInputStream); Path path = Paths.get("src/UserCredentials.csv"); - long lines = Files.lines(path).count(); // Counts lines in UserCredentials.csv + long lines = Files.lines(path).count(); String textAtLine; String readUsername; - if(lines < 1) { // Checks if file is empty + if(lines < 1) { System.out.println("There is no data in file."); } else { - for (int i = 0; i < lines; i++) { // Goes line by line throughout the file + for (int i = 0; i < lines; i++) { textAtLine = scnr.nextLine(); readUsername = ""; - for (int j = 0; j < textAtLine.length(); j++) { // Collects characters until a comma is reached + for (int j = 0; j < textAtLine.length(); j++) { if (textAtLine.charAt(j) != ',') { readUsername += textAtLine.charAt(j); } else { break; } } - if (username.equals(readUsername)) { // Checks if username at line is equal to the user's desired username + if (username.equals(readUsername)) { System.out.println("Username already exists."); return true; @@ -145,16 +134,6 @@ public boolean isComplexPassword(String password) { try { - /* Regex Breakdown - * Passwords must be 8 - 20 characters consisting of at least one digit, symbol, uppercase, lowercase, and it contains no whitespaces. - * ^ - start of String - * $ - end of String - * (?=.*[0-9]) - looks through entire string for at least one occurence of 0-9. - * (?=.*[a-z]) - looks through entire string for at least one occurence of a-z. - * (?=.*[A-Z]) - looks through entire string for at least one occurence of A-Z. - * (?=.*[!@#$%^&+=] - looks through entire string for at least one occurence of !,@,#,$,%,^,&,+, or =. - * {8-20} - minimum of 8 characters, max of 20. - */ String passwordRegEx = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=\\S+$).{8,20}$"; Pattern pattern = Pattern.compile(passwordRegEx); Matcher matcher = pattern.matcher(password); @@ -179,24 +158,20 @@ public static void main(String[] args) { } -/** - * appFrame is a class that makes up ewallet's GUI frame. It contains a JMenu with options to navigate - * between the different features of the app by utilizing a CardLayout while clearing and setting a panel when navigating between the pages. - */ class appFrame extends JFrame { - static User user; // temporary - until login is set up. + static User user; ExpenserMain expenserMain; JMenuBar navMenuBar; JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; // different pages + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; appFrame(){ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setMinimumSize(new Dimension(900,700)); this.setTitle("EWallet Application"); - user = new User("Default", "TempPassword!123"); // Default User. + user = new User("Default", "TempPassword!123"); expenserMain = new ExpenserMain(); expenserMain.userAtHand = user; @@ -209,12 +184,11 @@ class appFrame extends JFrame { incomeRepPanel incRepPanel = new incomeRepPanel(); expenseRepPanel expRepPanel = new expenseRepPanel(); detailedRepPanel detRepPanel = new detailedRepPanel(); - getContentPane().add(hPanel); // setting default page + getContentPane().add(hPanel); navMenuBar = new JMenuBar(); navMenu = new JMenu("

Menu"); // Menu homeNav = new JMenuItem("

Home"); // Home Page homeNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -234,7 +208,6 @@ public void mouseReleased(MouseEvent e) { }); addItemNav = new JMenuItem("

Add Item"); // Add Items Page addItemNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -255,7 +228,6 @@ public void mouseReleased(MouseEvent e) { importNav = new JMenuItem("

Import Tool"); // Import Page importNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { super.mouseClicked(e); @@ -274,7 +246,6 @@ public void mouseReleased(MouseEvent e) { }); estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page estimateNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -292,9 +263,8 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - incomeReportNav = new JMenuItem("

Income Report"); // Income Report Page + incomeReportNav = new JMenuItem("

Income Report"); incomeReportNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -312,9 +282,8 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - expenseReportNav = new JMenuItem("

Expense Report"); // Expense Report Page + expenseReportNav = new JMenuItem("

Expense Report"); expenseReportNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -332,9 +301,9 @@ public void mouseReleased(MouseEvent e) { repaint(); } }); - detailedReportNav = new JMenuItem("

Detailed Report"); // Detailed Report Page + detailedReportNav = new JMenuItem("

Detailed Report"); detailedReportNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed, while discarding previous jpanel instead of storing it + @Override public void mousePressed(MouseEvent e) { @@ -355,7 +324,6 @@ public void mouseReleased(MouseEvent e) { loginNav = new JMenuItem("

Login"); // Add Items Page loginNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -376,7 +344,6 @@ public void mouseReleased(MouseEvent e) { createAccNav = new JMenuItem("

Create Account"); // Add Items Page createAccNav.addMouseListener(new MouseAdapter() { - // once the page is clicked and released, it will be displayed while discarding previous JPanel instead of storing it @Override public void mousePressed(MouseEvent e) { @@ -395,7 +362,6 @@ public void mouseReleased(MouseEvent e) { } }); - // Updating font size of menu and menu items navMenu.setFont(new Font(null, Font.PLAIN, 24)); homeNav.setFont(new Font(null, Font.PLAIN, 20)); addItemNav.setFont(new Font(null, Font.PLAIN, 20)); @@ -407,7 +373,6 @@ public void mouseReleased(MouseEvent e) { loginNav.setFont(new Font(null, Font.PLAIN, 20)); createAccNav.setFont(new Font(null, Font.PLAIN, 20)); - // Adding items to the navigation menu navMenu.add(homeNav); navMenu.add(addItemNav); navMenu.add(importNav); @@ -427,10 +392,6 @@ public void mouseReleased(MouseEvent e) { } } -/** - * homePanel is a class that makes up ewallet's GUI home page. It contains basic total information like total income, - * total expenses, and savings. - */ class homePanel extends JPanel { JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; @@ -494,10 +455,6 @@ class homePanel extends JPanel { } } -/** - * addItemPanel is a class that makes up ewallet's Add Item page. It contains the ability for user to add either an income - * or an expense. Adding items will update the home page as well as the reports pages. - */ class addItemPanel extends JTabbedPane { ExpenserMain expenserMain; @@ -525,12 +482,12 @@ class addItemPanel extends JTabbedPane { monthComboBox = new JComboBox<>(months); monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); - monthComboBox.setSelectedIndex(0); // setting January as default selection + monthComboBox.setSelectedIndex(0); addIncomeButton = new JButton("Add"); addExpenseButton = new JButton("Add"); - gbConst = new GridBagConstraints(); // defining layout managers + gbConst = new GridBagConstraints(); incomePane.setLayout(new GridBagLayout()); expensePane.setLayout(new GridBagLayout()); @@ -611,11 +568,6 @@ class addItemPanel extends JTabbedPane { addIncomeButton.setPreferredSize(new Dimension(150,60)); incomePane.add(addIncomeButton, gbConst); - /* - * When the add income button is pressed, if there is text in the name and amount field, - * the data will be retrieved and put into a wage variable as well as updating both the home table, the item report table - * and the detailed report table. - */ addIncomeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -630,9 +582,8 @@ public void actionPerformed(ActionEvent e) { source = nameIncField.getText(); month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); Wage w = new Wage(source, amount, month); - expenserMain.userAtHand.addMonthlyIncome(w); // adding it to the user's wage arraylist + expenserMain.userAtHand.addMonthlyIncome(w); - // Adds item to combobox for type filter if name is unique if(incomeRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { @@ -647,12 +598,10 @@ public void actionPerformed(ActionEvent e) { incomeRepPanel.typeSelector.addItem(w.getSource()); } - // Updating tables and values expenserMain.updateIncomeTable(); expenserMain.updateIncomeValues(); expenserMain.updateDetailedTable(); - // Clearing fields nameIncField.setText(""); monthComboBox.setSelectedItem(0); amountIncField.setText(""); @@ -718,12 +667,6 @@ public void actionPerformed(ActionEvent e) { addExpenseButton.setPreferredSize(new Dimension(150,60)); expensePane.add(addExpenseButton, gbConst); - - /* - * When the add expense button is pressed, if there is text in the name, amount, and frequency field, - * the data will be retrieved and put into an expense variable as well as updating both the home table, the expense report table - * and the detailed report table. - */ addExpenseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -738,11 +681,10 @@ public void actionPerformed(ActionEvent e) { amount = 0.00f; } source = nameExpField.getText(); - Expense Ex = new Expense(source, amount, yearlyFrequency); // new expense object - expenserMain.addExpense(Ex); // adding it to the user's spending arraylist + Expense Ex = new Expense(source, amount, yearlyFrequency); + expenserMain.addExpense(Ex); expenserMain.updateExpenseValues(); - // Adds item to combobox for type filter if name is unique if(expenseRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { @@ -758,11 +700,9 @@ public void actionPerformed(ActionEvent e) { } - // update expense table and expenses on home expenserMain.updateExpenseTable(); expenserMain.updateDetailedTable(); - // Clearing fields nameExpField.setText(""); frequencyExpField.setText(""); amountExpField.setText(""); @@ -776,10 +716,6 @@ public void actionPerformed(ActionEvent e) { } } -/** - * importPanel is a class that makes up ewallet's import page. It contains the ability for the user to import data from a csv file. - * This will be completed in Sprint 2. - */ class importPanel extends JPanel { ExpenserMain expenserMain; @@ -800,8 +736,8 @@ class importPanel extends JPanel { this.setLayout(new GridBagLayout()); gbConst = new GridBagConstraints(); typesOfImports = new String[] {"Income","Expense"}; - options = new JComboBox<>(typesOfImports); // combo box for selecting which type to input to - options.setSelectedIndex(0); // sets Income as initial selection + options = new JComboBox<>(typesOfImports); + options.setSelectedIndex(0); importLbl = new JLabel("Import From File"); gbConst.gridx = 0; @@ -812,19 +748,19 @@ class importPanel extends JPanel { this.add(importLbl, gbConst); selectFileButton = new JButton("File"); - selectFileButton.addActionListener(new ActionListener() { // When the select file button is pressed + selectFileButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { // File chooser component + public void actionPerformed(ActionEvent e) { if (e.getSource() == selectFileButton) { - int userDecision = fileChooser.showOpenDialog(null); // opens file chooser window - if(userDecision == JFileChooser.APPROVE_OPTION) { // if file is selected + int userDecision = fileChooser.showOpenDialog(null); + if(userDecision == JFileChooser.APPROVE_OPTION) { userFile = fileChooser.getSelectedFile(); - if(!userFile.getAbsolutePath().endsWith(".csv")){ // if user selects a non-csv file, the user will be alerted. + if(!userFile.getAbsolutePath().endsWith(".csv")){ JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); System.out.println("User selected a non csv file!"); } System.out.println("The user selected: " + userFile.getAbsolutePath()); - } else if (userDecision == JFileChooser.CANCEL_OPTION) { // if user backs out + } else if (userDecision == JFileChooser.CANCEL_OPTION) { System.out.println("The user canceled the operation."); } } @@ -870,12 +806,12 @@ public void actionPerformed(ActionEvent e) { // File chooser component importButton = new JButton("Import"); importButton.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { // When the import button is pressed + public void actionPerformed(ActionEvent e) { if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { System.out.println("Income Selected"); - if(userFile == null) { // if there isn't a file selected + if(userFile == null) { JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { // when there is a csv file selected + } else { expenserMain.loadIncomeFile(userFile.getAbsolutePath()); expenserMain.updateIncomeTable(); expenserMain.updateDetailedTable(); @@ -883,9 +819,9 @@ public void actionPerformed(ActionEvent e) { // When the import button is presse } } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { System.out.println("Expense Selected"); - if(userFile == null) { // if there isn't a file selected + if(userFile == null) { JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { // when there is a csv file selected + } else { expenserMain.loadExpenseFile(userFile.getAbsolutePath()); expenserMain.updateExpenseTable(); expenserMain.updateDetailedTable(); @@ -905,10 +841,6 @@ public void actionPerformed(ActionEvent e) { // When the import button is presse } } -/** - * estimatePanel is a class that makes up ewallet's estimate page. It contains the ability for the user to estimate how long it - * will take for a user to save up for an item based on stored income and expense information. - */ class estimatePanel extends JPanel { GridBagConstraints gbConst; JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; @@ -973,7 +905,6 @@ class estimatePanel extends JPanel { estimateButton = new JButton("Get Estimate"); estimateButton.addActionListener(new ActionListener() { - // Will retrieve estimate information. Scheduled for Sprint 2. @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == estimateButton) { @@ -994,10 +925,6 @@ public void actionPerformed(ActionEvent e) { } } -/** - * incomeRepPanel is a class that makes up ewallet's income report page. It shows basic income report information like all - * income information and contains the ability to filter data by month or source. - */ class incomeRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; @@ -1021,7 +948,7 @@ class incomeRepPanel extends JPanel { expenserMain = new ExpenserMain(); expenserMain.userAtHand = appFrame.user; - incomeRepPanel.Income = expenserMain.userAtHand.getIncome(); // retrieving income data + incomeRepPanel.Income = expenserMain.userAtHand.getIncome(); this.setLayout(new BorderLayout()); @@ -1122,8 +1049,8 @@ public void actionPerformed(ActionEvent e) { centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Month"}; - tableVals = new Object[Income.size()][3]; // creating table with 3 columns and as many rows as there are data in Income arraylist - model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model + tableVals = new Object[Income.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); incomeTable = new JTable(model) { public boolean isCellEditable(int row, int column) { // restricting cell editing return false; @@ -1131,7 +1058,6 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing }; jScrollPane = new JScrollPane(incomeTable); - // Centering items in table cells centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); for (int i = 0; i < incomeTable.getColumnCount(); i++) { incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); @@ -1160,7 +1086,6 @@ public void actionPerformed(ActionEvent e) { // exports report to csv exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); - // Creating centered button in bottom part of border layout JPanel lowerPanel = new JPanel(); lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); lowerPanel.add(exportReport, BorderLayout.CENTER); @@ -1170,10 +1095,6 @@ public void actionPerformed(ActionEvent e) { // exports report to csv } } -/** - * expenseRepPanel is a class that makes up ewallet's expense report page. It shows basic expense report information like all - * expense information and will contain the ability to filter data by month or type. - */ class expenseRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; @@ -1271,7 +1192,7 @@ class expenseRepPanel extends JPanel { applyFilter = new JButton("Filter"); applyFilter.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { // Filters table results based on user selected categories like month and type. Repopulates table and summary information + public void actionPerformed(ActionEvent e) { if(e.getSource() == applyFilter) { filteredSpending = expenserMain.filterExpensesFreq (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) @@ -1300,8 +1221,8 @@ public void actionPerformed(ActionEvent e) { // Filters table results based on u centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Frequency"}; - tableVals = new Object[Spending.size()][3]; // creating table with 3 columns and as many rows as there are data in Spending arraylist - model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model + tableVals = new Object[Spending.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); spendingTable = new JTable(model) { public boolean isCellEditable(int row, int column) { // restricting cell editing return false; @@ -1309,7 +1230,6 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing }; jScrollPane = new JScrollPane(spendingTable); - // Centering items in table cells centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); for (int i = 0; i < spendingTable.getColumnCount(); i++) { spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); @@ -1329,7 +1249,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { // Exports report to csv file + exportReport.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == exportReport) { @@ -1340,7 +1260,6 @@ public void actionPerformed(ActionEvent e) { exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); - // Creating centered button in bottom part of border layout JPanel lowerPanel = new JPanel(); lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); lowerPanel.add(exportReport, BorderLayout.CENTER); @@ -1350,10 +1269,6 @@ public void actionPerformed(ActionEvent e) { } } -/** - * detailedRepPanel is a class that makes up ewallet's detailed report page. It shows basic income and expense report information like all - * expense and income information and will contain the ability to filter data by month or type. - */ class detailedRepPanel extends JPanel { static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; @@ -1389,7 +1304,6 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing }; jScrollPane = new JScrollPane(detailedTable); - // Centering items in table cells centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); for (int i = 0; i < detailedTable.getColumnCount(); i++) { detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); @@ -1408,7 +1322,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); - exportReport = new JButton("Export to CSV"); // exports report to csv file + exportReport = new JButton("Export to CSV"); exportReport.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -1418,7 +1332,6 @@ public void actionPerformed(ActionEvent e) { exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); - // Creating centered button in bottom part of border layout JPanel lowerPanel = new JPanel(); lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); lowerPanel.add(exportReport, BorderLayout.CENTER); diff --git a/src/Expense.java b/src/Expense.java index 426f914..478404e 100644 --- a/src/Expense.java +++ b/src/Expense.java @@ -1,44 +1,22 @@ - -/** - * A class for calculating the user's expenses - */ public class Expense { String source; double amount; int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly - - /** - * Accepts the parameter values as inputs and updating the object's values - * @param source user's source of expense - * @param amount user's amount of expense - * @param yearlyfrequency user's frequency of expense - */ + Expense(String source, double amount, int yearlyfrequency) { this.source = source; this.amount = amount; this.yearlyfrequency = yearlyfrequency; } - - /** - * Method responsible for getting the source of the expense - * @param source user's source of the expense - */ + public String getSource() { return this.source; } - - /** - * Method responsible for getting the amount of the expense - * @param amount user's amount of expense - */ + public double getAmount() { return this.amount; } - - /** - * Method responsible for getting the frequency of the expense - * @param yearlyfrequency user's frequency of expense - */ + public int getFrequency() { return this.yearlyfrequency; } diff --git a/src/Expenser.java b/src/Expenser.java index 115e8a0..e60960e 100644 --- a/src/Expenser.java +++ b/src/Expenser.java @@ -1,36 +1,17 @@ import java.util.ArrayList; public interface Expenser { -public User userAtHand= null; - // As a user I'd like to add a monthly expense so I can track and report my expenses - 3pts - public void addExpense (Expense Ex); - // As a user I'd like to add a monthly income so I can track and report my income all year - 3pts + public void addExpense (Expense Ex); public void addMonthlyIncome (Wage W); - //As a user I would like to view a detailed report of all expenses, income, and summary information - //summary information include : total income, total income for each type, total income for each month, total expense, total expense for each type, - //total savings (total income- total expenses) to date, if the total savings are less than zero it should be reported as total new debt. public void PrintFullreport(); - //As a user I would like to view a detailed report of all expenses, and summary information for expenses public void PrintExpensereport(); - //As a user I would like to view a detailed report of all income, and summary information for income public void PrintIncomereport(); - //As a user I would like to view a detailed report of income of a certain type, and summary information for income public void PrintIncomereportbyTpe(); - //As a user I would like to view a detailed report of expense of a certain type , and summary information for expenses public void PrintExpensebyType(); - // As a user I would like to choose a report and export it as an external file (any type is fine preferences are csv or JSON) public void exportReport(String reportTitle); - // As a user I would like to view my current balance in a different currency - //Bonus : try to use the same convert function to convert from foreign currency to USD public Currency convertForeignCurrency(Currency C, double amount); - // As a user I would like to load multiple expenses from an external file all at once returning true if loaded successfully and false otherwise - public boolean loadExpenseFile(String filePath); - // As a user I would like to load multiple income from an external file all at once returning true if loaded successfully and false otherwise + public boolean loadExpenseFile(String filePath); public boolean loadIncomeFile(String filePath); - // As a user I would like to provide an item and a price and get an estimate in number of months needed to save up to buy this item. (based on current monthly saving. public int whenCanIBuy(String itemname,double price); - // updates monthly savings based on latest added income and expenses. This is an internal function not called by the users. Bonus: what is the most efficient way to call it (when?)? - public void updateMonthlySavings(); - - + public void updateMonthlySavings(); } diff --git a/src/ExpenserMain.java b/src/ExpenserMain.java index 075f277..67e9ce5 100644 --- a/src/ExpenserMain.java +++ b/src/ExpenserMain.java @@ -6,13 +6,11 @@ public class ExpenserMain implements Expenser { public User userAtHand = null; - // Add Expense feature @Override public void addExpense (Expense Ex) { userAtHand.addExpense(Ex); } - // Add Monthly Income feature @Override public void addMonthlyIncome (Wage W) { userAtHand.addMonthlyIncome(W); @@ -20,37 +18,27 @@ public void addMonthlyIncome (Wage W) { @Override public void PrintFullreport() { - // Not used } @Override public void PrintExpensereport() { - // Not used } @Override public void PrintIncomereport() { - // Not used } @Override public void PrintIncomereportbyTpe() { - // Not used } @Override public void PrintExpensebyType() { - // Not used } - /** - * Method responsible for exporting reports using the export report button on the various report pages on the GUI - * @param reportTitle title of report as String - */ @Override public void exportReport(String reportTitle) { try { - // Creates new csv file with specified title DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); String filePath = ""; String fileName = reportTitle + dateTimeFormatter.format(LocalDateTime.now()); // title + time & date @@ -59,9 +47,9 @@ public void exportReport(String reportTitle) { FileOutputStream fileStream = new FileOutputStream(reportFile,true); PrintWriter printWriter = new PrintWriter(fileStream); - reportFile.createNewFile(); // creates file + reportFile.createNewFile(); - if (reportTitle.startsWith("Expense Report")) { // If title starts with Expense Report, the following will be written to file + if (reportTitle.startsWith("Expense Report")) { printWriter.append("Total Income"); printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); @@ -85,7 +73,7 @@ public void exportReport(String reportTitle) { printWriter.append("" + exp.getAmount() + ","); printWriter.append("" + exp.getFrequency() + "\n"); } - } else if (reportTitle.startsWith("Income Report")) { // If title starts with Income Report, the following will be written to file + } else if (reportTitle.startsWith("Income Report")) { printWriter.append("Total Income"); printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); @@ -109,7 +97,7 @@ public void exportReport(String reportTitle) { printWriter.append("" + wage.getAmount() + ","); printWriter.append("" + wage.getMonth() + "\n"); } - } else if (reportTitle.startsWith("Detailed Report")) { // If title starts with Detailed Report, the following will be written to file + } else if (reportTitle.startsWith("Detailed Report")) { printWriter.append("Total Income"); printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); @@ -138,7 +126,7 @@ public void exportReport(String reportTitle) { printWriter.append("" + exp.getFrequency() + "\n"); } } - printWriter.close(); // file closes and saves. + printWriter.close(); @@ -152,12 +140,6 @@ public Currency convertForeignCurrency(Currency C, double amount) { return null; } - /** - * This is a method that loads information from a csv file. The file must start with "source,amount,frequency" in the first line as a minimum. - * The data will be added to expense objects and loaded into the program on the tables and total locations. - * @param filePath the path of the file that data will be taken from - * @return true if the program had no issues loading the data. false if the program encountered a problem. - */ @Override public boolean loadExpenseFile(String filePath) { // Initialization @@ -175,42 +157,33 @@ public boolean loadExpenseFile(String filePath) { linesInFile++; } Expense expense; - for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { // loops through entirety of file - lineText = bufferedTextReader.readLine(); // reads each line and puts it into lineText - if(lineIndex == 0 && lineText.trim().equals("source,amount,frequency")) { // first line of file must match the String + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { + lineText = bufferedTextReader.readLine(); + if(lineIndex == 0 && lineText.trim().equals("source,amount,frequency")) { System.out.println("File start setup correctly."); } - else if (lineIndex > 0){ // Each line outside of the first will go through this operation - // resetting data after each line + else if (lineIndex > 0){ source = ""; frequency = ""; amount = ""; - // Gets from start of line to the first occurence of the comma and stores it in source for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { source += lineText.charAt(sourceIndex); } - // Gets text starting after the first comma up until the next comma and stores it in amount for(int amountIndex = lineText.indexOf(',') + 1; amountIndex < lineText.lastIndexOf(','); amountIndex++) { amount += lineText.charAt(amountIndex); } - // Gets text starting after the last comma until the end of the line and stores it in frequency for(int freqIndex = lineText.lastIndexOf(',') + 1; freqIndex < lineText.length(); freqIndex++) { frequency += lineText.charAt(freqIndex); } - // little loop that shows what was read (and will be added) to the program. System.out.println("Text read: " + source + "," + amount + "," + frequency); - // Creates a new wage object from the data expense = new Expense(source,Double.parseDouble(amount),Integer.valueOf(frequency)); - // Updates user expenses userAtHand.setExpenses(userAtHand.getExpenses() + expense.getAmount()); - // Adds expense object to user's spending ArrayList addExpense(expense); - // Loop that adds items to the type filter dropdown in income reports page, and will not add repeats if(expenseRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { @@ -227,20 +200,14 @@ else if (lineIndex > 0){ // Each line outside of the first will go through this } } - } catch (FileNotFoundException e) { // if file is not found, return false. + } catch (FileNotFoundException e) { return false; - } catch (IOException e) { // if there is an IO problem (maybe operation interruption) + } catch (IOException e) { return false; } return true; } - /** - * This is a method that loads information from a csv file. The file must start with "source,amount,month" in the first line as a minimum. - * The data will be added to wage objects and loaded into the program on the tables and total locations. - * @param filePath the path of the file that data will be taken from - * @return true if the program had no issues loading the data. false if the program encountered a problem. - */ @Override public boolean loadIncomeFile(String filePath) { @@ -260,42 +227,34 @@ public boolean loadIncomeFile(String filePath) { linesInFile++; } Wage wage; - for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { // loops through entirety of file - lineText = bufferedTextReader.readLine(); // reads each line and puts it into lineText - if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { // first line of file must match the String + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { + lineText = bufferedTextReader.readLine(); + if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { System.out.println("File start setup correctly."); } - else { // Each line outside of the first will go through this operation - // resetting data after each line + else { source = ""; month = ""; amount = ""; - // Gets from start of line to the first occurence of the comma and stores it in source for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { source += lineText.charAt(sourceIndex); } - // Gets text starting after the first comma up until the next comma and stores it in amount + for(int amountindex = lineText.indexOf(',') + 1; amountindex < lineText.lastIndexOf(','); amountindex++) { amount += lineText.charAt(amountindex); } - // Gets text starting after the last comma until the end of the line and stores it in month for(int monthIndex = lineText.lastIndexOf(',') + 1; monthIndex < lineText.length(); monthIndex++) { month += lineText.charAt(monthIndex); } - // little loop that shows what was read (and will be added) to the program. System.out.println("Text read: " + source + "," + amount + "," + month); - // Creates a new wage object from the data wage = new Wage(source,Double.parseDouble(amount),month); - // Updates user balance userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); - // Adds wage object to user's wage ArrayList addMonthlyIncome(wage); - // Loop that adds items to the type filter dropdown in income reports page, and will not add repeats if(incomeRepPanel.typeSelector.getItemCount() > 0) { boolean contains = false; for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { @@ -312,9 +271,9 @@ public boolean loadIncomeFile(String filePath) { } } - } catch (FileNotFoundException e) { // if file is not found, return false. + } catch (FileNotFoundException e) { return false; - } catch (IOException e) { // if there is an IO problem (maybe operation interruption) + } catch (IOException e) { return false; } return true; @@ -330,13 +289,6 @@ public void updateMonthlySavings() { userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); } - - /** - * Produces a filtered expense ArrayList based on the user's frequency of the expense - * @param exp Base Expense ArrayList - * @param freq Frequency as String - * @return New ArrayList of filtered data - */ static ArrayList filterExpensesFreq(ArrayList exp, String freq) { ArrayList filteredExpensesFreq = new ArrayList<>(); for(Expense ex : exp) { @@ -346,13 +298,7 @@ static ArrayList filterExpensesFreq(ArrayList exp, String freq } return filteredExpensesFreq; } - - /** - * Produces a filtered expense ArrayList based on the user's source of the expense - * @param exp Base Expense ArrayList - * @param source Source as String - * @return New ArrayList of filtered data - */ + static ArrayList filterExpensesSource(ArrayList exp, String source) { ArrayList filteredExpensesSource = new ArrayList<>(); for(Expense ex : exp) { @@ -362,13 +308,7 @@ static ArrayList filterExpensesSource(ArrayList exp, String so } return filteredExpensesSource; } - - /** - * Produces a filtered income ArrayList based on the user's month of income - * @param wage Base Wage ArrayList - * @param month Month as String - * @return New ArrayList of filtered data - */ + static ArrayList filterIncomesMonth(ArrayList wage, String month) { ArrayList filteredIncomesMonth = new ArrayList<>(); for(Wage w : wage) { @@ -378,13 +318,7 @@ static ArrayList filterIncomesMonth(ArrayList wage, String month) { } return filteredIncomesMonth; } - - /** - * Method responsible for producing a filtered income ArrayList based on the user's source of the income - * @param wage Base Wage ArrayList - * @param source Source as String - * @return New ArrayList of filtered data - */ + static ArrayList filterIncomesSource(ArrayList wage, String source) { ArrayList filteredIncomesSource = new ArrayList<>(); for(Wage w : wage) { @@ -395,12 +329,8 @@ static ArrayList filterIncomesSource(ArrayList wage, String source) return filteredIncomesSource; } - /** - * Updates income table values based on adding of values through import or the add tool. - */ public void updateIncomeTable() { - // Resetting row count - setting it to the income array size incomeRepPanel.model.setNumRows(0); for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { @@ -409,7 +339,6 @@ public void updateIncomeTable() { userAtHand.setBalance(0.00f); - // Updating what is displayed on the table with new wage data int i = 0; for(Wage wage : userAtHand.getIncome()) { userAtHand.setBalance(userAtHand.getBalance() + wage.amount); @@ -420,20 +349,15 @@ public void updateIncomeTable() { } } - /** - * Updates detailed table values based on adding of values through import or the add tool. - */ public void updateDetailedTable() { - // clears detailed table detailedRepPanel.model.setNumRows(0); - // re-adds rows based on number of wage objects for(int j = 0; j < userAtHand.getIncome().size() + userAtHand.getSpending().size(); j++ ) { detailedRepPanel.model.addRow(new Object[]{}); } int i = 0; - for(Wage wage : userAtHand.getIncome()) { // repopulates table with wage data + for(Wage wage : userAtHand.getIncome()) { detailedRepPanel.detailedTable.setValueAt("Income", i, 0); detailedRepPanel.detailedTable.setValueAt(wage.getSource(), i, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); @@ -441,7 +365,7 @@ public void updateDetailedTable() { ++i; } - for(Expense expense : userAtHand.getSpending()) { // repopulates table with expense data + for(Expense expense : userAtHand.getSpending()) { detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); detailedRepPanel.detailedTable.setValueAt(expense.getSource(), i, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); @@ -451,19 +375,14 @@ public void updateDetailedTable() { } - /** - * Updates expense table values based on adding of values through import or the add tool. - */ public void updateExpenseTable() { - // Resetting row count - setting it to the income array size expenseRepPanel.model.setNumRows(0); for(int j = 0; j < userAtHand.getSpending().size(); j++ ) { expenseRepPanel.model.addRow(new Object[]{}); } - // Updating what is displayed on the table with new wage data userAtHand.setExpenses(0.00f); int i = 0; for(Expense expense : userAtHand.getSpending()) { @@ -475,10 +394,6 @@ public void updateExpenseTable() { } } - /** - * Updates income values through import or the add tool - * Values on the home page, income page, and expense page will be updated with this. - */ public void updateIncomeValues() { userAtHand.setExpenses(getExpense(userAtHand.getSpending())); userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); @@ -488,10 +403,6 @@ public void updateIncomeValues() { homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); } - /** - * Updates expense values through import or the add tool - * Values on the home page, income page, and expense page will be updated with this. - */ public void updateExpenseValues() { userAtHand.setExpenses(getExpense(userAtHand.getSpending())); userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); @@ -501,11 +412,6 @@ public void updateExpenseValues() { homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.monthlysavings)); } - /** - * Gets the total income for a user based on an inputted ArrayList of type wage. - * @param wage user's income ArrayList - * @return user's total income - */ public double getTotalIncome(ArrayList wage) { double sum = 0.00f; for(Wage userWage : wage) { @@ -514,11 +420,6 @@ public double getTotalIncome(ArrayList wage) { return sum; } - /** - * Obtains sources for the income combobox selector - * @param updatedWage Wage ArrayList - * @return ArrayList of Strings of sources - */ public ArrayList getIncomeSources(ArrayList updatedWage) { ArrayList sources = new ArrayList<>(); @@ -528,11 +429,6 @@ public ArrayList getIncomeSources(ArrayList updatedWage) { return sources; } - /** - * Gets expense sources for the expense combobox selector - * @param expenses ArrayList of Expenses - * @return ArrayList of Sources - */ public ArrayList getExpenseSources(ArrayList expenses) { ArrayList sources = new ArrayList<>(); for(Expense exp : expenses) { @@ -541,11 +437,6 @@ public ArrayList getExpenseSources(ArrayList expenses) { return sources; } - /** - * Gets total expenses - * @param Ex ArrayList of Spending (expense) - * @return Sum of Expenses - */ public double getExpense(ArrayList Ex) { double sum = 0.00f; for(Expense ex : Ex) { diff --git a/src/User.java b/src/User.java index a4baca1..2ad32ff 100644 --- a/src/User.java +++ b/src/User.java @@ -1,144 +1,72 @@ import java.util.ArrayList; -/** - * A class for creating user objects, which contains currency rates, income, expenses, balance, and monthly savings - */ public class User { private ArrayList currencyRates; - private ArrayList Income = new ArrayList<>(); // user income sources that user can record or view or search by type or month - private ArrayList Spending = new ArrayList<>(); //user's expenses + private ArrayList Income = new ArrayList<>(); + private ArrayList Spending = new ArrayList<>(); String username; String pwd; - //current total income - total double balance; - // possible monthly savings, calculated using monthly income (most recent) assuming the data we have is for one year, and monthly and biweekly expenses, here you can assume yearly expenses that are recorded have already been paid. double monthlysavings; double expenses; - //should add constructor(s) - /** - * When creating a User object, the user needs to provide a username and password. - * @param username user's desired username as String - * @param password user's desired password as String - */ User(String username, String password){ this.username = username; this.pwd = password; } - /** - * Method responsible for getting user's username - * @return user's username as String - */ protected String getUsername() { return this.username; } - /** - * Method responsible for getting user's password - * @return user's password as String - */ protected String getPwd() { return this.pwd; } - /** - * Method responsible for updating the user's username - * @param username user's desired username - */ protected void setUsername(String username) { this.username = username; } - /** - * Method responsible for updating the user's password - * @param password user's desired password - */ protected void setPwd(String password) { this.pwd = password; } - - /** - * Method responsible for adding expense to the arraylist - * @param Ex user's calculated expense - */ + protected void addExpense(Expense Ex) { Spending.add(Ex); } - /** - * Method responsible for adding a monthly income to the Income ArrayList - * @param W Wage object - */ protected void addMonthlyIncome(Wage W) { Income.add(W); } - /** - * Method responsible for adding an expense object to Spending ArrayList - * @param Ex Expense object - */ - - /** - * Method responsible for making the ArrayList Income accessible to classes that have access to a user object. - * @return ArrayList of Wage objects. - */ protected ArrayList getIncome() { return this.Income; } - /** - * Method responsible for making the ArrayList Spending accessible to classes that have access to a user object. - * @return ArrayList of Expense objects - */ protected ArrayList getSpending() { return this.Spending; } - /** - * Method responsible for updating balance (income) of user - * @param balance updated income of user as double - */ protected void setBalance(double balance) { this.balance = balance; } - /** - * Method responsible for getting balance of user - * @return current income of user as a double - */ protected double getBalance(){ return this.balance; } - /** - * Method responsible for updating expenses of user - * @param expenses expenses of user as double. - */ protected void setExpenses(double expenses) { this.expenses = expenses; } - /** - * Method responsible for getting expenses of user - * @return expenses of user as double - */ protected double getExpenses() { return this.expenses; } - /** - * Method responsible for getting savings of user - * @return monthly savings of user as double - */ protected double getMonthlySavings() { return this.monthlysavings; } - /** - * Method responsible for updating monthly savings of user - * @param monthlySavings new value of monthly savings of user - */ protected void setMonthlySavings(double monthlySavings) { this.monthlysavings = monthlySavings; } diff --git a/src/Wage.java b/src/Wage.java index 4039b89..bfce2db 100644 --- a/src/Wage.java +++ b/src/Wage.java @@ -3,39 +3,21 @@ public class Wage { String source; double amount; String Month; - - /** - * Accepts the parameter values as inputs and updating the object's values - * @param source user's source of wage - * @param amount user's amount of wage - * @param Month user's month in which they receive the wage - */ + Wage(String source, double amount, String Month) { this.source = source; this.amount = amount; this.Month = Month; } - - /** - * Method responsible for getting the wage's source - * @param source user's source of the wage - */ + public String getSource() { return this.source; } - - /** - * Method responsible for getting the wage's amount - * @param amount user's amount of the wage - */ + public double getAmount() { return this.amount; } - - /** - * Method responsible for getting the month in which the wage was received - * @param Month the month in which the user received the wage - */ + public String getMonth() { return this.Month; } From 3c3ce51e31d5e6da8866396dd43c8a108790ee14 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 16 Mar 2025 21:25:15 -0400 Subject: [PATCH 046/123] Creating file containing the application requirements called requirements.md --- requirements.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 requirements.md diff --git a/requirements.md b/requirements.md new file mode 100644 index 0000000..0508d26 --- /dev/null +++ b/requirements.md @@ -0,0 +1,21 @@ +# Requirements + +## User Stories + +- As a user I would like to provide an item and a price and get an estimate in number of months needed to save up to buy +this item (based on current monthly saving). +- As a user I would like to load multiple income from an external file all at once returning true if loaded successfully +and false otherwise. +- As a user I would like to load multiple expenses from an external file all at once returning true if loaded successfully +and false otherwise. +- As a user I would like to view my current balance in a different currency and back. +- As a user I would like to choose a report and export it as an external file (any type is fine preferences are csv or JSON) +- As a user I would like to view a detailed report of expense of a certain type , and summary information for expenses +- As a user I would like to view a detailed report of income of a certain type, and summary information for income +- As a user I would like to view a detailed report of all income, and summary information for income +- As a user I would like to view a detailed report of all expenses, and summary information for expenses +- As a user I would like to view a detailed report of all expenses, income, and summary information. +summary information include : total income, total income for each type, total income for each month, total expense, total expense for each type, +total savings (total income- total expenses) to date, if the total savings are less than zero it should be reported as total new debt. +- As a user I'd like to add a monthly income so I can track and report my income all year. +- As a user I'd like to add a monthly expense so I can track and report my expenses \ No newline at end of file From 0a6cf4724b34e84a4c907654fa8b99a30c76e3fb Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 16 Mar 2025 21:28:31 -0400 Subject: [PATCH 047/123] Adding project config files --- .idea/.gitignore | 8 ++++++++ .idea/.name | 1 + .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ EWallet.iml | 12 ++++++++++++ 6 files changed, 41 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 EWallet.iml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..4c00fb1 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +EWallet \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b718c81 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..23d6980 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/EWallet.iml b/EWallet.iml new file mode 100644 index 0000000..ea1542a --- /dev/null +++ b/EWallet.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file From ba5145c5b3dcad4ca412f40fa0b1642f36155abf Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 16 Mar 2025 21:29:12 -0400 Subject: [PATCH 048/123] Renaming Project --- .project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.project b/.project index ceb4c39..6a7aca6 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - 210Project-2021 + EWallet From 71b37289659139c687922ce3450d5afe97e4f453 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 16 Mar 2025 21:58:02 -0400 Subject: [PATCH 049/123] Restructuring project tree, switching from eclipse-based project to a maven project, adding maven required configuration and files --- .classpath | 10 - .idea/compiler.xml | 13 + .idea/encodings.xml | 7 + .idea/jarRepositories.xml | 20 + .idea/misc.xml | 8 + .idea/modules.xml | 8 - .project | 17 - EWallet.iml | 12 - ...UserCredentials.csv => UserCredentials.csv | 0 pom.xml | 17 + requirements.md | 2 +- .../java/edu/ferris/seng210}/Currency.java | 13 +- .../java/edu/ferris/seng210}/EWalletApp.java | 3060 +++++++++-------- .../java/edu/ferris/seng210}/Expense.java | 50 +- .../java/edu/ferris/seng210}/Expenser.java | 34 +- .../edu/ferris/seng210}/ExpenserMain.java | 16 +- .../java/edu/ferris/seng210}/User.java | 150 +- .../java/edu/ferris/seng210}/Wage.java | 49 +- 18 files changed, 1757 insertions(+), 1729 deletions(-) delete mode 100644 .classpath create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/modules.xml delete mode 100644 .project delete mode 100644 EWallet.iml rename src/UserCredentials.csv => UserCredentials.csv (100%) create mode 100644 pom.xml rename src/{ => main/java/edu/ferris/seng210}/Currency.java (71%) rename src/{ => main/java/edu/ferris/seng210}/EWalletApp.java (95%) rename src/{ => main/java/edu/ferris/seng210}/Expense.java (94%) rename src/{ => main/java/edu/ferris/seng210}/Expenser.java (92%) rename src/{ => main/java/edu/ferris/seng210}/ExpenserMain.java (96%) rename src/{ => main/java/edu/ferris/seng210}/User.java (94%) rename src/{ => main/java/edu/ferris/seng210}/Wage.java (92%) diff --git a/.classpath b/.classpath deleted file mode 100644 index 75ae95b..0000000 --- a/.classpath +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..005f67d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index b718c81..17de8cc 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,13 @@ + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 23d6980..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.project b/.project deleted file mode 100644 index 6a7aca6..0000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - EWallet - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/EWallet.iml b/EWallet.iml deleted file mode 100644 index ea1542a..0000000 --- a/EWallet.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/UserCredentials.csv b/UserCredentials.csv similarity index 100% rename from src/UserCredentials.csv rename to UserCredentials.csv diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4971557 --- /dev/null +++ b/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + edu.ferris.seng210 + ewallet + 1.0-SNAPSHOT + + + 23 + 23 + UTF-8 + + + \ No newline at end of file diff --git a/requirements.md b/requirements.md index 0508d26..e2fd258 100644 --- a/requirements.md +++ b/requirements.md @@ -1,6 +1,6 @@ # Requirements -## User Stories +## main.java.edu.ferris.seng210.User Stories - As a user I would like to provide an item and a price and get an estimate in number of months needed to save up to buy this item (based on current monthly saving). diff --git a/src/Currency.java b/src/main/java/edu/ferris/seng210/Currency.java similarity index 71% rename from src/Currency.java rename to src/main/java/edu/ferris/seng210/Currency.java index c5b6c8b..c98f091 100644 --- a/src/Currency.java +++ b/src/main/java/edu/ferris/seng210/Currency.java @@ -1,6 +1,7 @@ - -public class Currency { - public double rate; - public String name; - -} +package edu.ferris.seng210; + +public class Currency { + public double rate; + public String name; + +} diff --git a/src/EWalletApp.java b/src/main/java/edu/ferris/seng210/EWalletApp.java similarity index 95% rename from src/EWalletApp.java rename to src/main/java/edu/ferris/seng210/EWalletApp.java index 7095d0b..bb50394 100644 --- a/src/EWalletApp.java +++ b/src/main/java/edu/ferris/seng210/EWalletApp.java @@ -1,1529 +1,1531 @@ -import javax.swing.*; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.DefaultTableModel; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class EWalletApp { - private ArrayList AllData = new ArrayList<>(); - - public void CreateUser(String username, String password) { - - if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { - User user = new User(username, password); - AllData.add(user); - - try { - FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); - PrintWriter printWriter = new PrintWriter(fileOutputStream); - printWriter.append(username); - printWriter.append(","); - printWriter.append(password); - printWriter.append(",\n"); - printWriter.close(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } - } - - - - public boolean CheckUsername(String username) { - boolean flag = false; - String savedUser; - - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - while(scnr.hasNextLine()) { - savedUser = scnr.nextLine(); - if(savedUser.indexOf(username) != -1) { - flag = true; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return flag; - } - - public boolean CheckPassword(String username,String password) { - boolean flag = false; - String lineTxt; - - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - while(scnr.hasNextLine()) { - lineTxt = scnr.nextLine(); - if(lineTxt.indexOf(username) != -1) { - if((lineTxt.indexOf(username) + username.length() + 1) == lineTxt.indexOf(password)) { - for(int i = 0; i < AllData.size(); i++) { - if(AllData.get(i).getUsername().equals(username)) { - appFrame.user = AllData.get(i); - } - } - flag = true; - break; - } - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return flag; - } - - public boolean checkForRepeatUsernames(String username) { - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - Path path = Paths.get("src/UserCredentials.csv"); - long lines = Files.lines(path).count(); - String textAtLine; - String readUsername; - if(lines < 1) { - System.out.println("There is no data in file."); - } else { - for (int i = 0; i < lines; i++) { - textAtLine = scnr.nextLine(); - readUsername = ""; - for (int j = 0; j < textAtLine.length(); j++) { - if (textAtLine.charAt(j) != ',') { - readUsername += textAtLine.charAt(j); - } else { - break; - } - } - if (username.equals(readUsername)) { - - System.out.println("Username already exists."); - return true; - - } - } - } - - } catch (FileNotFoundException e) { - - System.out.println("The file UserCredentials.csv was not found."); - - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - - public boolean isComplexPassword(String password) { - - try { - - String passwordRegEx = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=\\S+$).{8,20}$"; - Pattern pattern = Pattern.compile(passwordRegEx); - Matcher matcher = pattern.matcher(password); - if(!matcher.find()) { - System.out.println("Password is not valid."); - } else { - System.out.println("Password is valid."); - return true; - } - - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } - - - public static void main(String[] args) { - appFrame app = new appFrame(); - - } - -} - -class appFrame extends JFrame { - - static User user; - ExpenserMain expenserMain; - JMenuBar navMenuBar; - JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; - - appFrame(){ - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setMinimumSize(new Dimension(900,700)); - this.setTitle("EWallet Application"); - - user = new User("Default", "TempPassword!123"); - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; - - loginPanel lPanel = new loginPanel(); - createAccountPanel createAccPanel = new createAccountPanel(); - homePanel hPanel = new homePanel(); - addItemPanel addItmPanel = new addItemPanel(); - importPanel impPanel = new importPanel(); - estimatePanel estPanel = new estimatePanel(); - incomeRepPanel incRepPanel = new incomeRepPanel(); - expenseRepPanel expRepPanel = new expenseRepPanel(); - detailedRepPanel detRepPanel = new detailedRepPanel(); - getContentPane().add(hPanel); - navMenuBar = new JMenuBar(); - navMenu = new JMenu("

Menu"); // Menu - homeNav = new JMenuItem("

Home"); // Home Page - homeNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(hPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - addItemNav = new JMenuItem("

Add Item"); // Add Items Page - addItemNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(addItmPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - importNav = new JMenuItem("

Import Tool"); // Import Page - importNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - super.mouseClicked(e); - getContentPane().removeAll(); - revalidate(); - repaint(); - getContentPane().add(impPanel); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page - estimateNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(estPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - incomeReportNav = new JMenuItem("

Income Report"); - incomeReportNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(incRepPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - expenseReportNav = new JMenuItem("

Expense Report"); - expenseReportNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(expRepPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - detailedReportNav = new JMenuItem("

Detailed Report"); - detailedReportNav.addMouseListener(new MouseAdapter() { - - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(detRepPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - loginNav = new JMenuItem("

Login"); // Add Items Page - loginNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(lPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - createAccNav = new JMenuItem("

Create Account"); // Add Items Page - createAccNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(createAccPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - navMenu.setFont(new Font(null, Font.PLAIN, 24)); - homeNav.setFont(new Font(null, Font.PLAIN, 20)); - addItemNav.setFont(new Font(null, Font.PLAIN, 20)); - importNav.setFont(new Font(null, Font.PLAIN, 20)); - estimateNav.setFont(new Font(null, Font.PLAIN, 20)); - incomeReportNav.setFont(new Font(null, Font.PLAIN, 20)); - expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); - detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); - loginNav.setFont(new Font(null, Font.PLAIN, 20)); - createAccNav.setFont(new Font(null, Font.PLAIN, 20)); - - navMenu.add(homeNav); - navMenu.add(addItemNav); - navMenu.add(importNav); - navMenu.add(estimateNav); - navMenu.add(incomeReportNav); - navMenu.add(expenseReportNav); - navMenu.add(detailedReportNav); - navMenu.add(loginNav); - navMenu.add(createAccNav); - navMenuBar.add(navMenu); - - - this.setJMenuBar(navMenuBar); - this.setLayout(new CardLayout()); - this.pack(); - this.setVisible(true); - } -} - -class homePanel extends JPanel { - - JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; - static JLabel totalExpensesAmtLbl, totalSavingsAmtLbl, totalIncomeAmtLbl; - GridBagConstraints gbConst; - homePanel() { - - summaryTxt = new JLabel("User Summary"); - totalIncomeLbl = new JLabel("Total Income: "); - totalIncomeAmtLbl = new JLabel("$0.00"); - totalExpensesLbl = new JLabel("Total Expenses: "); - totalExpensesAmtLbl = new JLabel("$0.00"); - totalSavingsLbl = new JLabel("Total Savings: "); - totalSavingsAmtLbl = new JLabel("$0.00"); - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,20,60,20); - summaryTxt.setFont(new Font(null, Font.PLAIN, 44)); - this.add(summaryTxt, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(20,40,20,5); - totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(20,10,20,40); - totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalIncomeAmtLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(20,40,20,5); - totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalExpensesLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(20,10,20,40); - totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalExpensesAmtLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(20,40,40,5); - totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalSavingsLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(20,10,40,40); - totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalSavingsAmtLbl, gbConst); - } -} - -class addItemPanel extends JTabbedPane { - - ExpenserMain expenserMain; - int yearlyFrequency; - double amount; - String month, source; - GridBagConstraints gbConst; - JPanel incomePane, expensePane; - JLabel addIncomeItemLbl, addExpenseItemLbl; - JLabel nameIncomeLbl, amountIncomeLbl, monthIncomeLbl; - JLabel nameExpenseLbl, amountExpenseLbl, frequencyExpLbl; - JTextField nameIncField, amountIncField, frequencyExpField; - JTextField nameExpField, amountExpField; - JButton addIncomeButton, addExpenseButton; - JComboBox monthComboBox; - String[] months; - addItemPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - - months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; - incomePane = new JPanel(); - expensePane = new JPanel(); - - monthComboBox = new JComboBox<>(months); - monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); - monthComboBox.setSelectedIndex(0); - - addIncomeButton = new JButton("Add"); - addExpenseButton = new JButton("Add"); - - gbConst = new GridBagConstraints(); - incomePane.setLayout(new GridBagLayout()); - expensePane.setLayout(new GridBagLayout()); - - addIncomeItemLbl = new JLabel("Add Item"); - nameIncomeLbl = new JLabel("Name"); - amountIncomeLbl = new JLabel("Amount"); - monthIncomeLbl = new JLabel("Month"); - - addExpenseItemLbl = new JLabel("Add Item"); - nameExpenseLbl = new JLabel("Name"); - amountExpenseLbl = new JLabel("Amount"); - frequencyExpLbl = new JLabel("Freq."); - - nameIncField = new JTextField(); - nameIncField.setPreferredSize(new Dimension(280, 50)); - amountIncField = new JTextField(); - amountIncField.setPreferredSize(new Dimension(280, 50)); - frequencyExpField = new JTextField(); - frequencyExpField.setPreferredSize(new Dimension(280, 50)); - - nameExpField = new JTextField(); - nameExpField.setPreferredSize(new Dimension(280, 50)); - amountExpField = new JTextField(); - amountExpField.setPreferredSize(new Dimension(280, 50)); - monthComboBox.setPreferredSize(new Dimension(280, 50)); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(0,20,60,30); - addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 44)); - incomePane.add(addIncomeItemLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(nameIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,30,30); - nameIncField.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(nameIncField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(amountIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,30,30); - amountIncField.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(amountIncField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - monthIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(monthIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,30,30); - monthComboBox.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(monthComboBox, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,30,30,30); - addIncomeButton.setFont(new Font(null, Font.PLAIN, 28)); - addIncomeButton.setPreferredSize(new Dimension(150,60)); - incomePane.add(addIncomeButton, gbConst); - - addIncomeButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == addIncomeButton) { - if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0) { - try { - amount = Double.parseDouble(amountIncField.getText()); - } catch (NumberFormatException n) { - System.out.println(n.getMessage()); - amount = 0.00f; - } - source = nameIncField.getText(); - month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); - Wage w = new Wage(source, amount, month); - expenserMain.userAtHand.addMonthlyIncome(w); - - if(incomeRepPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { - if (incomeRepPanel.typeSelector.getItemAt(i).equals(w.getSource())) { - contains = true; - } - } - if (!contains) { - incomeRepPanel.typeSelector.addItem(w.getSource()); - } - } else { - incomeRepPanel.typeSelector.addItem(w.getSource()); - } - - expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(); - expenserMain.updateDetailedTable(); - - nameIncField.setText(""); - monthComboBox.setSelectedItem(0); - amountIncField.setText(""); - - } - - } - } - }); - - this.add("Add Income", incomePane); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.insets = new Insets(0,20,60,30); - addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 44)); - expensePane.add(addExpenseItemLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(nameExpenseLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,30,30); - nameExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(nameExpField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(amountExpenseLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,30,30); - amountExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(amountExpField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - frequencyExpLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(frequencyExpLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,30,30); - frequencyExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(frequencyExpField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,30,30,30); - addExpenseButton.setFont(new Font(null, Font.PLAIN, 28)); - addExpenseButton.setPreferredSize(new Dimension(150,60)); - expensePane.add(addExpenseButton, gbConst); - - addExpenseButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == addExpenseButton) { - if(nameExpField.getText().length() > 0 && amountExpField.getText().length() > 0 & frequencyExpField.getText().length() > 0) { - try { - amount = Double.parseDouble(amountExpField.getText()); - yearlyFrequency = Integer.parseInt(frequencyExpField.getText()); - - } catch (NumberFormatException n) { - System.out.println(n.getMessage()); - amount = 0.00f; - } - source = nameExpField.getText(); - Expense Ex = new Expense(source, amount, yearlyFrequency); - expenserMain.addExpense(Ex); - expenserMain.updateExpenseValues(); - - if(expenseRepPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { - if (expenseRepPanel.typeSelector.getItemAt(i).equals(Ex.getSource())) { - contains = true; - } - } - if (!contains) { - expenseRepPanel.typeSelector.addItem(Ex.getSource()); - } - } else { - expenseRepPanel.typeSelector.addItem(Ex.getSource()); - } - - - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - - nameExpField.setText(""); - frequencyExpField.setText(""); - amountExpField.setText(""); - } - } - } - }); - - this.add("Add Expense", expensePane); - this.setFont(new Font(null, Font.PLAIN, 24)); - } -} - -class importPanel extends JPanel { - - ExpenserMain expenserMain; - GridBagConstraints gbConst; - JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; - JButton selectFileButton, importButton; - JFileChooser fileChooser; - String[] typesOfImports; - JComboBox options; - File userFile; - importPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - - fileChooser = new JFileChooser(); - - this.setLayout(new GridBagLayout()); - gbConst = new GridBagConstraints(); - typesOfImports = new String[] {"Income","Expense"}; - options = new JComboBox<>(typesOfImports); - options.setSelectedIndex(0); - - importLbl = new JLabel("Import From File"); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(10,30,20,30); - importLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(importLbl, gbConst); - - selectFileButton = new JButton("File"); - selectFileButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() == selectFileButton) { - int userDecision = fileChooser.showOpenDialog(null); - if(userDecision == JFileChooser.APPROVE_OPTION) { - userFile = fileChooser.getSelectedFile(); - if(!userFile.getAbsolutePath().endsWith(".csv")){ - JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); - System.out.println("User selected a non csv file!"); - } - System.out.println("The user selected: " + userFile.getAbsolutePath()); - } else if (userDecision == JFileChooser.CANCEL_OPTION) { - System.out.println("The user canceled the operation."); - } - } - } - }); - - selectFileLbl = new JLabel("Select File"); - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(30,30,20,0); - selectFileLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(selectFileLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(30,0,20,30); - selectFileButton.setFont(new Font(null, Font.PLAIN, 24)); - this.add(selectFileButton, gbConst); - - selectTypeLbl = new JLabel("Select Type"); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(30,30,20,0); - selectTypeLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(selectTypeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(30,0,20,30); - options.setFont(new Font(null, Font.PLAIN, 24)); - this.add(options, gbConst); - - descriptionLbl = new JLabel("Note: Only csv files are supported.

The format of the csv file matters.
The first line of the file needs to contain \"source,amount,month\" or
\"source,amount,frequency\", depending on the type

Once you select a file, click the import button."); - gbConst.gridwidth = 2; - gbConst.gridheight = 2; - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(30,30,30,30); - descriptionLbl.setFont(new Font(null, Font.PLAIN, 20)); - this.add(descriptionLbl, gbConst); - - importButton = new JButton("Import"); - importButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { - System.out.println("Income Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadIncomeFile(userFile.getAbsolutePath()); - expenserMain.updateIncomeTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateIncomeValues(); - } - } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { - System.out.println("Expense Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadExpenseFile(userFile.getAbsolutePath()); - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateExpenseValues(); - } - } - - } - }); - gbConst.gridheight = 1; - gbConst.gridx = 0; - gbConst.gridy = 5; - gbConst.insets = new Insets(30,0,30,30); - importButton.setFont(new Font(null, Font.PLAIN, 24)); - this.add(importButton, gbConst); - - } -} - -class estimatePanel extends JPanel { - GridBagConstraints gbConst; - JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; - JTextField nameField, priceField; - JButton estimateButton; - estimatePanel() { - this.setLayout(new GridBagLayout()); - gbConst = new GridBagConstraints(); - - estimateTitleLbl = new JLabel("Estimate Tool"); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(10,20,30,30); - estimateTitleLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(estimateTitleLbl, gbConst); - - estimateLbl = new JLabel("Estimate:"); - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,0,30,0); - estimateLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(estimateLbl, gbConst); - - estimateAmtLbl = new JLabel("0 days"); - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(10,0,30,0); - estimateAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(estimateAmtLbl, gbConst); - - nameLbl = new JLabel("Item Name"); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,20,30,30); - nameLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(nameLbl, gbConst); - - nameField = new JTextField(); - nameField.setPreferredSize(new Dimension(280, 50)); - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,30,30); - nameField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(nameField, gbConst); - - priceLbl = new JLabel("Item Price"); - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,20,30,30); - priceLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(priceLbl, gbConst); - - priceField = new JTextField(); - priceField.setPreferredSize(new Dimension(280, 50)); - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,30,30); - priceField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(priceField, gbConst); - - estimateButton = new JButton("Get Estimate"); - estimateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == estimateButton) { - System.out.println("Get Estimate Button Clicked."); - nameField.setText(""); - priceField.setText(""); - } - } - }); - estimateButton.setPreferredSize(new Dimension(220, 60)); - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(30,30,30,30); - estimateButton.setFont(new Font(null, Font.PLAIN, 28)); - this.add(estimateButton, gbConst); - - } -} - -class incomeRepPanel extends JPanel { - static DefaultTableModel model; - DefaultTableCellRenderer centerRenderer; - static JScrollPane jScrollPane; - static ArrayList Income; - static ArrayList filteredIncomeList = new ArrayList<>(); - Object[][] tableVals; // table values - String[] columnHeadings; - static JTable incomeTable; - JLabel incomeText, filterTxt; - JLabel totalIncomeLbl, totalFilteredIncomeLbl; - static JLabel totalIncomeAmtLbl, totalFilteredIncomeAmtLbl; - JButton exportReport, applyFilter; - ExpenserMain expenserMain; - GridBagConstraints gbConst; - JPanel upperPanel; - JComboBox monthSelector; - static JComboBox typeSelector; - String[] months; - incomeRepPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - incomeRepPanel.Income = expenserMain.userAtHand.getIncome(); - - this.setLayout(new BorderLayout()); - - incomeText = new JLabel("Income Report"); - incomeText.setFont(new Font(null, Font.PLAIN, 40)); - incomeText.setHorizontalAlignment(JLabel.CENTER); - - gbConst = new GridBagConstraints(); - upperPanel = new JPanel(); - upperPanel.setLayout(new GridBagLayout()); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 4; - gbConst.insets = new Insets(20,0,20,0); - upperPanel.add(incomeText, gbConst); - - totalIncomeLbl = new JLabel("Total Income"); - totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridwidth = 1; - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(totalIncomeLbl,gbConst); - - totalIncomeAmtLbl = new JLabel("0.00"); - totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalIncomeAmtLbl,gbConst); - - totalFilteredIncomeLbl = new JLabel("Income (Filtered)"); - totalFilteredIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 2; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalFilteredIncomeLbl,gbConst); - - totalFilteredIncomeAmtLbl = new JLabel("0.00"); - totalFilteredIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 3; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,20); - upperPanel.add(totalFilteredIncomeAmtLbl,gbConst); - - filterTxt = new JLabel("Apply a filter"); - filterTxt.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(filterTxt,gbConst); - - months = new String[]{"","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; - monthSelector = new JComboBox<>(months); - monthSelector.setPreferredSize(new Dimension(200,50)); - monthSelector.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(monthSelector,gbConst); - - incomeRepPanel.typeSelector = new JComboBox<>(expenserMain.getIncomeSources(Income).toArray()); - typeSelector.setFont(new Font(null, Font.PLAIN, 24)); - typeSelector.setPreferredSize(new Dimension(200,50)); - gbConst.gridx = 2; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(typeSelector,gbConst); - - applyFilter = new JButton("Filter"); - applyFilter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - filteredIncomeList = - expenserMain.filterIncomesMonth(expenserMain.filterIncomesSource(expenserMain.userAtHand.getIncome(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); - incomeRepPanel.model.setNumRows(filteredIncomeList.size()); - int i = 0; - double incomeSum = 0.00f; - for(Wage wage : filteredIncomeList) { - incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); - incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); - ++i; - incomeSum += wage.getAmount(); - } - totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); - } - } - }); - applyFilter.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 3; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(applyFilter,gbConst); - - this.add(upperPanel, BorderLayout.PAGE_START); - - centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Source","Amount", "Month"}; - tableVals = new Object[Income.size()][3]; - model = new DefaultTableModel(tableVals, columnHeadings); - incomeTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing - return false; - } - }; - jScrollPane = new JScrollPane(incomeTable); - - centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 0; i < incomeTable.getColumnCount(); i++) { - incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); - } - incomeTable.setDefaultRenderer(String.class, centerRenderer); - - incomeTable.setFont(new Font(null, Font.PLAIN, 24)); - incomeTable.setRowHeight(45); - incomeTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - incomeTable.getTableHeader().setReorderingAllowed(false); - incomeTable.setFocusable(true); - incomeTable.setRowSelectionAllowed(true); - incomeTable.setCellSelectionEnabled(true); - incomeTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); - incomeTable.setShowVerticalLines(false); - - this.add(jScrollPane, BorderLayout.CENTER); - - exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { // exports report to csv - expenserMain.exportReport("Income Report"); - } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); - - } -} - -class expenseRepPanel extends JPanel { - static DefaultTableModel model; - DefaultTableCellRenderer centerRenderer; - static JScrollPane jScrollPane; - static ArrayList Spending; - static ArrayList filteredSpending = new ArrayList<>(); - Object[][] tableVals; - String[] columnHeadings; - static JTable spendingTable; - JLabel expenseText; - JLabel totalExpenseLbl, totalFilteredExpenseLbl, filterTxt ; - static JLabel totalExpenseAmtLbl, totalFilteredExpenseAmtLbl; - JButton exportReport, applyFilter; - ExpenserMain expenserMain; - GridBagConstraints gbConst; - JPanel upperPanel; - JComboBox monthSelector; - static JComboBox typeSelector; - String[] frequency; - - expenseRepPanel() { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - expenseRepPanel.Spending = expenserMain.userAtHand.getSpending(); - - this.setLayout(new BorderLayout()); - - - expenseText = new JLabel("Expense Report"); - expenseText.setFont(new Font(null, Font.PLAIN, 40)); - expenseText.setHorizontalAlignment(JLabel.CENTER); - - gbConst = new GridBagConstraints(); - upperPanel = new JPanel(); - upperPanel.setLayout(new GridBagLayout()); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 4; - gbConst.insets = new Insets(20,0,20,0); - upperPanel.add(expenseText, gbConst); - - totalExpenseLbl = new JLabel("Total Expense"); - totalExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridwidth = 1; - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(totalExpenseLbl,gbConst); - - totalExpenseAmtLbl = new JLabel("0.00"); - totalExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalExpenseAmtLbl,gbConst); - - totalFilteredExpenseLbl = new JLabel("Expenses (Filtered)"); - totalFilteredExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 2; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalFilteredExpenseLbl,gbConst); - - totalFilteredExpenseAmtLbl = new JLabel("0.00"); - totalFilteredExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 3; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,20); - upperPanel.add(totalFilteredExpenseAmtLbl,gbConst); - - filterTxt = new JLabel("Apply a filter"); - filterTxt.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(filterTxt,gbConst); - - frequency = new String[]{"1", "12","24"}; - monthSelector = new JComboBox<>(frequency); - monthSelector.setFont(new Font(null, Font.PLAIN, 24)); - monthSelector.setPreferredSize(new Dimension(200,50)); - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(monthSelector,gbConst); - - expenseRepPanel.typeSelector = new JComboBox<>(expenserMain.getExpenseSources(Spending).toArray()); - typeSelector.setFont(new Font(null, Font.PLAIN, 24)); - typeSelector.setPreferredSize(new Dimension(200,50)); - gbConst.gridx = 2; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(typeSelector,gbConst); - - applyFilter = new JButton("Filter"); - applyFilter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - filteredSpending = expenserMain.filterExpensesFreq - (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) - ,(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); - expenseRepPanel.model.setNumRows(filteredSpending.size()); - int i = 0; - double expenseSum = 0.00f; - for(Expense exp : filteredSpending) { - expenseRepPanel.spendingTable.setValueAt(exp.getSource(), i, 0); - expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); - expenseRepPanel.spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); - ++i; - expenseSum += exp.getAmount(); - } - totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); - } - } - }); - applyFilter.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 3; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(applyFilter,gbConst); - - this.add(upperPanel, BorderLayout.PAGE_START); - - centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Source","Amount", "Frequency"}; - tableVals = new Object[Spending.size()][3]; - model = new DefaultTableModel(tableVals, columnHeadings); - spendingTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing - return false; - } - }; - jScrollPane = new JScrollPane(spendingTable); - - centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 0; i < spendingTable.getColumnCount(); i++) { - spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); - } - spendingTable.setDefaultRenderer(String.class, centerRenderer); - - spendingTable.setFont(new Font(null, Font.PLAIN, 24)); - spendingTable.setRowHeight(45); - spendingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - spendingTable.getTableHeader().setReorderingAllowed(false); - spendingTable.setFocusable(true); - spendingTable.setRowSelectionAllowed(true); - spendingTable.setCellSelectionEnabled(true); - spendingTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); - spendingTable.setShowVerticalLines(false); - - this.add(jScrollPane, BorderLayout.CENTER); - - exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == exportReport) { - expenserMain.exportReport("Expense Report"); - } - } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); - - } -} - -class detailedRepPanel extends JPanel { - static DefaultTableModel model; - DefaultTableCellRenderer centerRenderer; - static JScrollPane jScrollPane; - ArrayList Spending; - ArrayList Income; - Object[][] tableVals; - String[] columnHeadings; - static JTable detailedTable; - JLabel detaileReportTxt; - JButton exportReport; - ExpenserMain expenserMain; - detailedRepPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - - this.setLayout(new BorderLayout()); - detaileReportTxt = new JLabel("Detailed Report"); - detaileReportTxt.setFont(new Font(null, Font.PLAIN, 40)); - detaileReportTxt.setHorizontalAlignment(JLabel.CENTER); - this.add(detaileReportTxt, BorderLayout.PAGE_START); - centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; - Spending = expenserMain.userAtHand.getSpending(); - Income = expenserMain.userAtHand.getIncome(); - tableVals = new Object[Spending.size()+Income.size()][4]; - model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model - detailedTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing - return false; - } - }; - jScrollPane = new JScrollPane(detailedTable); - - centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 0; i < detailedTable.getColumnCount(); i++) { - detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); - } - detailedTable.setDefaultRenderer(String.class, centerRenderer); - - detailedTable.setFont(new Font(null, Font.PLAIN, 24)); - detailedTable.setRowHeight(45); - detailedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - detailedTable.getTableHeader().setReorderingAllowed(false); - detailedTable.setFocusable(true); - detailedTable.setRowSelectionAllowed(true); - detailedTable.setCellSelectionEnabled(true); - detailedTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); - detailedTable.setShowVerticalLines(false); - - this.add(jScrollPane, BorderLayout.CENTER); - - exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - expenserMain.exportReport("Detailed Report"); - } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); - } - -} - -class loginPanel extends JPanel { - EWalletApp eWalletApp = new EWalletApp(); - JLabel usernameLbl, passwordLbl, loginLbl; - GridBagConstraints gbConst; - JTextField usernameIncField, passwordIncField; - JButton loginBtn; - String username, password; - - loginPanel() { - loginLbl = new JLabel("LOGIN"); - usernameLbl = new JLabel("Username: "); - passwordLbl = new JLabel("Password: "); - loginBtn = new JButton("Login"); - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); - - passwordIncField = new JTextField(); - passwordIncField.setPreferredSize(new Dimension(200, 40)); - usernameIncField = new JTextField(); - usernameIncField.setPreferredSize(new Dimension(200, 40)); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,10,20,40); - loginLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(loginLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(0,5,20,30); - passwordIncField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(passwordIncField, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,30); - usernameIncField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(usernameIncField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,0,20,20); - passwordLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(passwordLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,0,20,20); - usernameLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(usernameLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,30,30,30); - loginBtn.setFont(new Font(null, Font.PLAIN, 28)); - loginBtn.setPreferredSize(new Dimension(150,60)); - this.add(loginBtn, gbConst); - - loginBtn.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - username = usernameIncField.getText(); - password = passwordIncField.getText(); - if(eWalletApp.CheckUsername(username) && eWalletApp.CheckPassword(username, password)) { - usernameIncField.setText(""); - passwordIncField.setText(""); - System.out.println("Login Successful"); - JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); - } else { - JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); - } - } - }); - - - } -} - -class createAccountPanel extends JPanel { - EWalletApp eWalletApp = new EWalletApp(); - JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; - GridBagConstraints gbConst; - static JTextField usernameField, passwordField, confPasswordField; - JButton createAccBtn; - String username, password, confPassword; - - createAccountPanel() { - usernameLbl = new JLabel("Enter Username:"); - passwordLbl = new JLabel("Enter Password:"); - confPasswordLbl = new JLabel("Confirm Password:"); - createAccLbl = new JLabel("Create Account"); - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); - - usernameField = new JTextField(); - usernameField.setPreferredSize(new Dimension(200, 40)); - passwordField = new JTextField(); - passwordField.setPreferredSize(new Dimension(200, 40)); - confPasswordField = new JTextField(); - confPasswordField.setPreferredSize(new Dimension(200, 40)); - - createAccBtn = new JButton("Create Account"); - createAccBtn.setPreferredSize(new Dimension(200, 40)); - - gbConst.gridx = 1; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(0,20,40,20); - createAccLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(createAccLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,40,40,0); - usernameLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(usernameLbl, gbConst); - - gbConst.gridx = -1; - gbConst.gridy = 1; - gbConst.insets = new Insets(20,0,40,40); - usernameField.setFont(new Font(null, Font.PLAIN, 32)); - this.add(usernameField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,40,40,0); - passwordLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(passwordLbl, gbConst); - - gbConst.gridx = -1; - gbConst.gridy = 2; - gbConst.insets = new Insets(20,0,40,40); - passwordField.setFont(new Font(null, Font.PLAIN, 32)); - this.add(passwordField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(0,40,40,0); - confPasswordLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(confPasswordLbl, gbConst); - - gbConst.gridx = -1; - gbConst.gridy = 3; - gbConst.insets = new Insets(20,0,40,40); - confPasswordField.setFont(new Font(null, Font.PLAIN, 32)); - this.add(confPasswordField, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 4; - gbConst.insets = new Insets(20, 20, 20, 20); - createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); - this.add(createAccBtn, gbConst); - - createAccBtn.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if(e.getSource() == createAccBtn) { - username = usernameField.getText(); - password = passwordField.getText(); - confPassword = confPasswordField.getText(); - if(usernameField.getText().length() > 0 && passwordField.getText().length() > 0 && confPasswordField.getText().length() > 0) { - if(confPassword.equals(password)) { - if(eWalletApp.checkForRepeatUsernames(usernameField.getText())) { - JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); - } else { - eWalletApp.CreateUser(username, password); - JOptionPane.showMessageDialog(null, "User created successfully."); - usernameField.setText(""); - passwordField.setText(""); - confPasswordField.setText(""); - } - } else { - JOptionPane.showMessageDialog(null, "Passwords do not match!"); - } - } else { - JOptionPane.showMessageDialog(null,"Not all fields filled out. Please fill them out."); - } - } - } - }); - - } - -} - +package edu.ferris.seng210; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class EWalletApp { + private ArrayList AllData = new ArrayList<>(); + + public void CreateUser(String username, String password) { + + if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { + User user = new User(username, password); + AllData.add(user); + + try { + FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); + PrintWriter printWriter = new PrintWriter(fileOutputStream); + printWriter.append(username); + printWriter.append(","); + printWriter.append(password); + printWriter.append(",\n"); + printWriter.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + } + + + + public boolean CheckUsername(String username) { + boolean flag = false; + String savedUser; + + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + while(scnr.hasNextLine()) { + savedUser = scnr.nextLine(); + if(savedUser.indexOf(username) != -1) { + flag = true; + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return flag; + } + + public boolean CheckPassword(String username,String password) { + boolean flag = false; + String lineTxt; + + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + while(scnr.hasNextLine()) { + lineTxt = scnr.nextLine(); + if(lineTxt.indexOf(username) != -1) { + if((lineTxt.indexOf(username) + username.length() + 1) == lineTxt.indexOf(password)) { + for(int i = 0; i < AllData.size(); i++) { + if(AllData.get(i).getUsername().equals(username)) { + appFrame.user = AllData.get(i); + } + } + flag = true; + break; + } + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return flag; + } + + public boolean checkForRepeatUsernames(String username) { + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + Path path = Paths.get("src/UserCredentials.csv"); + long lines = Files.lines(path).count(); + String textAtLine; + String readUsername; + if(lines < 1) { + System.out.println("There is no data in file."); + } else { + for (int i = 0; i < lines; i++) { + textAtLine = scnr.nextLine(); + readUsername = ""; + for (int j = 0; j < textAtLine.length(); j++) { + if (textAtLine.charAt(j) != ',') { + readUsername += textAtLine.charAt(j); + } else { + break; + } + } + if (username.equals(readUsername)) { + + System.out.println("Username already exists."); + return true; + + } + } + } + + } catch (FileNotFoundException e) { + + System.out.println("The file UserCredentials.csv was not found."); + + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + public boolean isComplexPassword(String password) { + + try { + + String passwordRegEx = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=\\S+$).{8,20}$"; + Pattern pattern = Pattern.compile(passwordRegEx); + Matcher matcher = pattern.matcher(password); + if(!matcher.find()) { + System.out.println("Password is not valid."); + } else { + System.out.println("Password is valid."); + return true; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + public static void main(String[] args) { + appFrame app = new appFrame(); + + } + +} + +class appFrame extends JFrame { + + static User user; + ExpenserMain expenserMain; + JMenuBar navMenuBar; + JMenu navMenu; + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; + + appFrame(){ + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setMinimumSize(new Dimension(900,700)); + this.setTitle("EWallet Application"); + + user = new User("Default", "TempPassword!123"); + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + + loginPanel lPanel = new loginPanel(); + createAccountPanel createAccPanel = new createAccountPanel(); + homePanel hPanel = new homePanel(); + addItemPanel addItmPanel = new addItemPanel(); + importPanel impPanel = new importPanel(); + estimatePanel estPanel = new estimatePanel(); + incomeRepPanel incRepPanel = new incomeRepPanel(); + expenseRepPanel expRepPanel = new expenseRepPanel(); + detailedRepPanel detRepPanel = new detailedRepPanel(); + getContentPane().add(hPanel); + navMenuBar = new JMenuBar(); + navMenu = new JMenu("

Menu"); // Menu + homeNav = new JMenuItem("

Home"); // Home Page + homeNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(hPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + addItemNav = new JMenuItem("

Add Item"); // Add Items Page + addItemNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(addItmPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + importNav = new JMenuItem("

Import Tool"); // Import Page + importNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mouseClicked(e); + getContentPane().removeAll(); + revalidate(); + repaint(); + getContentPane().add(impPanel); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page + estimateNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(estPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + incomeReportNav = new JMenuItem("

Income Report"); + incomeReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(incRepPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + expenseReportNav = new JMenuItem("

main.java.seng210.Expense Report"); + expenseReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(expRepPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + detailedReportNav = new JMenuItem("

Detailed Report"); + detailedReportNav.addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(detRepPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + loginNav = new JMenuItem("

Login"); // Add Items Page + loginNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(lPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + createAccNav = new JMenuItem("

Create Account"); // Add Items Page + createAccNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(createAccPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + navMenu.setFont(new Font(null, Font.PLAIN, 24)); + homeNav.setFont(new Font(null, Font.PLAIN, 20)); + addItemNav.setFont(new Font(null, Font.PLAIN, 20)); + importNav.setFont(new Font(null, Font.PLAIN, 20)); + estimateNav.setFont(new Font(null, Font.PLAIN, 20)); + incomeReportNav.setFont(new Font(null, Font.PLAIN, 20)); + expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); + detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); + loginNav.setFont(new Font(null, Font.PLAIN, 20)); + createAccNav.setFont(new Font(null, Font.PLAIN, 20)); + + navMenu.add(homeNav); + navMenu.add(addItemNav); + navMenu.add(importNav); + navMenu.add(estimateNav); + navMenu.add(incomeReportNav); + navMenu.add(expenseReportNav); + navMenu.add(detailedReportNav); + navMenu.add(loginNav); + navMenu.add(createAccNav); + navMenuBar.add(navMenu); + + + this.setJMenuBar(navMenuBar); + this.setLayout(new CardLayout()); + this.pack(); + this.setVisible(true); + } +} + +class homePanel extends JPanel { + + JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; + static JLabel totalExpensesAmtLbl, totalSavingsAmtLbl, totalIncomeAmtLbl; + GridBagConstraints gbConst; + homePanel() { + + summaryTxt = new JLabel("main.java.seng210.User Summary"); + totalIncomeLbl = new JLabel("Total Income: "); + totalIncomeAmtLbl = new JLabel("$0.00"); + totalExpensesLbl = new JLabel("Total Expenses: "); + totalExpensesAmtLbl = new JLabel("$0.00"); + totalSavingsLbl = new JLabel("Total Savings: "); + totalSavingsAmtLbl = new JLabel("$0.00"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,20,60,20); + summaryTxt.setFont(new Font(null, Font.PLAIN, 44)); + this.add(summaryTxt, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(20,40,20,5); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(20,10,20,40); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalIncomeAmtLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,40,20,5); + totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalExpensesLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,10,20,40); + totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalExpensesAmtLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,40,40,5); + totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalSavingsLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,10,40,40); + totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalSavingsAmtLbl, gbConst); + } +} + +class addItemPanel extends JTabbedPane { + + ExpenserMain expenserMain; + int yearlyFrequency; + double amount; + String month, source; + GridBagConstraints gbConst; + JPanel incomePane, expensePane; + JLabel addIncomeItemLbl, addExpenseItemLbl; + JLabel nameIncomeLbl, amountIncomeLbl, monthIncomeLbl; + JLabel nameExpenseLbl, amountExpenseLbl, frequencyExpLbl; + JTextField nameIncField, amountIncField, frequencyExpField; + JTextField nameExpField, amountExpField; + JButton addIncomeButton, addExpenseButton; + JComboBox monthComboBox; + String[] months; + addItemPanel() { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + + months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + incomePane = new JPanel(); + expensePane = new JPanel(); + + monthComboBox = new JComboBox<>(months); + monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); + monthComboBox.setSelectedIndex(0); + + addIncomeButton = new JButton("Add"); + addExpenseButton = new JButton("Add"); + + gbConst = new GridBagConstraints(); + incomePane.setLayout(new GridBagLayout()); + expensePane.setLayout(new GridBagLayout()); + + addIncomeItemLbl = new JLabel("Add Item"); + nameIncomeLbl = new JLabel("Name"); + amountIncomeLbl = new JLabel("Amount"); + monthIncomeLbl = new JLabel("Month"); + + addExpenseItemLbl = new JLabel("Add Item"); + nameExpenseLbl = new JLabel("Name"); + amountExpenseLbl = new JLabel("Amount"); + frequencyExpLbl = new JLabel("Freq."); + + nameIncField = new JTextField(); + nameIncField.setPreferredSize(new Dimension(280, 50)); + amountIncField = new JTextField(); + amountIncField.setPreferredSize(new Dimension(280, 50)); + frequencyExpField = new JTextField(); + frequencyExpField.setPreferredSize(new Dimension(280, 50)); + + nameExpField = new JTextField(); + nameExpField.setPreferredSize(new Dimension(280, 50)); + amountExpField = new JTextField(); + amountExpField.setPreferredSize(new Dimension(280, 50)); + monthComboBox.setPreferredSize(new Dimension(280, 50)); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(0,20,60,30); + addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 44)); + incomePane.add(addIncomeItemLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(nameIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,10,30,30); + nameIncField.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(nameIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(amountIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + amountIncField.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(amountIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + monthIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(monthIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + monthComboBox.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(monthComboBox, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + addIncomeButton.setFont(new Font(null, Font.PLAIN, 28)); + addIncomeButton.setPreferredSize(new Dimension(150,60)); + incomePane.add(addIncomeButton, gbConst); + + addIncomeButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == addIncomeButton) { + if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0) { + try { + amount = Double.parseDouble(amountIncField.getText()); + } catch (NumberFormatException n) { + System.out.println(n.getMessage()); + amount = 0.00f; + } + source = nameIncField.getText(); + month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); + Wage w = new Wage(source, amount, month); + expenserMain.userAtHand.addMonthlyIncome(w); + + if(incomeRepPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { + if (incomeRepPanel.typeSelector.getItemAt(i).equals(w.getSource())) { + contains = true; + } + } + if (!contains) { + incomeRepPanel.typeSelector.addItem(w.getSource()); + } + } else { + incomeRepPanel.typeSelector.addItem(w.getSource()); + } + + expenserMain.updateIncomeTable(); + expenserMain.updateIncomeValues(); + expenserMain.updateDetailedTable(); + + nameIncField.setText(""); + monthComboBox.setSelectedItem(0); + amountIncField.setText(""); + + } + + } + } + }); + + this.add("Add Income", incomePane); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.insets = new Insets(0,20,60,30); + addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 44)); + expensePane.add(addExpenseItemLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(nameExpenseLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,10,30,30); + nameExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(nameExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(amountExpenseLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + amountExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(amountExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + frequencyExpLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(frequencyExpLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + frequencyExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(frequencyExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + addExpenseButton.setFont(new Font(null, Font.PLAIN, 28)); + addExpenseButton.setPreferredSize(new Dimension(150,60)); + expensePane.add(addExpenseButton, gbConst); + + addExpenseButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == addExpenseButton) { + if(nameExpField.getText().length() > 0 && amountExpField.getText().length() > 0 & frequencyExpField.getText().length() > 0) { + try { + amount = Double.parseDouble(amountExpField.getText()); + yearlyFrequency = Integer.parseInt(frequencyExpField.getText()); + + } catch (NumberFormatException n) { + System.out.println(n.getMessage()); + amount = 0.00f; + } + source = nameExpField.getText(); + Expense Ex = new Expense(source, amount, yearlyFrequency); + expenserMain.addExpense(Ex); + expenserMain.updateExpenseValues(); + + if(expenseRepPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { + if (expenseRepPanel.typeSelector.getItemAt(i).equals(Ex.getSource())) { + contains = true; + } + } + if (!contains) { + expenseRepPanel.typeSelector.addItem(Ex.getSource()); + } + } else { + expenseRepPanel.typeSelector.addItem(Ex.getSource()); + } + + + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + + nameExpField.setText(""); + frequencyExpField.setText(""); + amountExpField.setText(""); + } + } + } + }); + + this.add("Add main.java.seng210.Expense", expensePane); + this.setFont(new Font(null, Font.PLAIN, 24)); + } +} + +class importPanel extends JPanel { + + ExpenserMain expenserMain; + GridBagConstraints gbConst; + JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; + JButton selectFileButton, importButton; + JFileChooser fileChooser; + String[] typesOfImports; + JComboBox options; + File userFile; + importPanel() { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + + fileChooser = new JFileChooser(); + + this.setLayout(new GridBagLayout()); + gbConst = new GridBagConstraints(); + typesOfImports = new String[] {"Income","main.java.seng210.Expense"}; + options = new JComboBox<>(typesOfImports); + options.setSelectedIndex(0); + + importLbl = new JLabel("Import From File"); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,30,20,30); + importLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(importLbl, gbConst); + + selectFileButton = new JButton("File"); + selectFileButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == selectFileButton) { + int userDecision = fileChooser.showOpenDialog(null); + if(userDecision == JFileChooser.APPROVE_OPTION) { + userFile = fileChooser.getSelectedFile(); + if(!userFile.getAbsolutePath().endsWith(".csv")){ + JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); + System.out.println("main.java.seng210.User selected a non csv file!"); + } + System.out.println("The user selected: " + userFile.getAbsolutePath()); + } else if (userDecision == JFileChooser.CANCEL_OPTION) { + System.out.println("The user canceled the operation."); + } + } + } + }); + + selectFileLbl = new JLabel("Select File"); + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(30,30,20,0); + selectFileLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectFileLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(30,0,20,30); + selectFileButton.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectFileButton, gbConst); + + selectTypeLbl = new JLabel("Select Type"); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(30,30,20,0); + selectTypeLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectTypeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(30,0,20,30); + options.setFont(new Font(null, Font.PLAIN, 24)); + this.add(options, gbConst); + + descriptionLbl = new JLabel("Note: Only csv files are supported.

The format of the csv file matters.
The first line of the file needs to contain \"source,amount,month\" or
\"source,amount,frequency\", depending on the type

Once you select a file, click the import button."); + gbConst.gridwidth = 2; + gbConst.gridheight = 2; + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(30,30,30,30); + descriptionLbl.setFont(new Font(null, Font.PLAIN, 20)); + this.add(descriptionLbl, gbConst); + + importButton = new JButton("Import"); + importButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { + System.out.println("Income Selected"); + if(userFile == null) { + JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); + } else { + expenserMain.loadIncomeFile(userFile.getAbsolutePath()); + expenserMain.updateIncomeTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateIncomeValues(); + } + } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { + System.out.println("main.java.seng210.Expense Selected"); + if(userFile == null) { + JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); + } else { + expenserMain.loadExpenseFile(userFile.getAbsolutePath()); + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateExpenseValues(); + } + } + + } + }); + gbConst.gridheight = 1; + gbConst.gridx = 0; + gbConst.gridy = 5; + gbConst.insets = new Insets(30,0,30,30); + importButton.setFont(new Font(null, Font.PLAIN, 24)); + this.add(importButton, gbConst); + + } +} + +class estimatePanel extends JPanel { + GridBagConstraints gbConst; + JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; + JTextField nameField, priceField; + JButton estimateButton; + estimatePanel() { + this.setLayout(new GridBagLayout()); + gbConst = new GridBagConstraints(); + + estimateTitleLbl = new JLabel("Estimate Tool"); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,20,30,30); + estimateTitleLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(estimateTitleLbl, gbConst); + + estimateLbl = new JLabel("Estimate:"); + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,0,30,0); + estimateLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(estimateLbl, gbConst); + + estimateAmtLbl = new JLabel("0 days"); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,0,30,0); + estimateAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(estimateAmtLbl, gbConst); + + nameLbl = new JLabel("Item Name"); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,20,30,30); + nameLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(nameLbl, gbConst); + + nameField = new JTextField(); + nameField.setPreferredSize(new Dimension(280, 50)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + nameField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(nameField, gbConst); + + priceLbl = new JLabel("Item Price"); + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,20,30,30); + priceLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(priceLbl, gbConst); + + priceField = new JTextField(); + priceField.setPreferredSize(new Dimension(280, 50)); + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + priceField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(priceField, gbConst); + + estimateButton = new JButton("Get Estimate"); + estimateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == estimateButton) { + System.out.println("Get Estimate Button Clicked."); + nameField.setText(""); + priceField.setText(""); + } + } + }); + estimateButton.setPreferredSize(new Dimension(220, 60)); + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(30,30,30,30); + estimateButton.setFont(new Font(null, Font.PLAIN, 28)); + this.add(estimateButton, gbConst); + + } +} + +class incomeRepPanel extends JPanel { + static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + static JScrollPane jScrollPane; + static ArrayList Income; + static ArrayList filteredIncomeList = new ArrayList<>(); + Object[][] tableVals; // table values + String[] columnHeadings; + static JTable incomeTable; + JLabel incomeText, filterTxt; + JLabel totalIncomeLbl, totalFilteredIncomeLbl; + static JLabel totalIncomeAmtLbl, totalFilteredIncomeAmtLbl; + JButton exportReport, applyFilter; + ExpenserMain expenserMain; + GridBagConstraints gbConst; + JPanel upperPanel; + JComboBox monthSelector; + static JComboBox typeSelector; + String[] months; + incomeRepPanel() { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + incomeRepPanel.Income = expenserMain.userAtHand.getIncome(); + + this.setLayout(new BorderLayout()); + + incomeText = new JLabel("Income Report"); + incomeText.setFont(new Font(null, Font.PLAIN, 40)); + incomeText.setHorizontalAlignment(JLabel.CENTER); + + gbConst = new GridBagConstraints(); + upperPanel = new JPanel(); + upperPanel.setLayout(new GridBagLayout()); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 4; + gbConst.insets = new Insets(20,0,20,0); + upperPanel.add(incomeText, gbConst); + + totalIncomeLbl = new JLabel("Total Income"); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridwidth = 1; + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(totalIncomeLbl,gbConst); + + totalIncomeAmtLbl = new JLabel("0.00"); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalIncomeAmtLbl,gbConst); + + totalFilteredIncomeLbl = new JLabel("Income (Filtered)"); + totalFilteredIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 2; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalFilteredIncomeLbl,gbConst); + + totalFilteredIncomeAmtLbl = new JLabel("0.00"); + totalFilteredIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 3; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,20); + upperPanel.add(totalFilteredIncomeAmtLbl,gbConst); + + filterTxt = new JLabel("Apply a filter"); + filterTxt.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(filterTxt,gbConst); + + months = new String[]{"","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + monthSelector = new JComboBox<>(months); + monthSelector.setPreferredSize(new Dimension(200,50)); + monthSelector.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(monthSelector,gbConst); + + incomeRepPanel.typeSelector = new JComboBox<>(expenserMain.getIncomeSources(Income).toArray()); + typeSelector.setFont(new Font(null, Font.PLAIN, 24)); + typeSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 2; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(typeSelector,gbConst); + + applyFilter = new JButton("Filter"); + applyFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == applyFilter) { + filteredIncomeList = + expenserMain.filterIncomesMonth(expenserMain.filterIncomesSource(expenserMain.userAtHand.getIncome(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + incomeRepPanel.model.setNumRows(filteredIncomeList.size()); + int i = 0; + double incomeSum = 0.00f; + for(Wage wage : filteredIncomeList) { + incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); + incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); + ++i; + incomeSum += wage.getAmount(); + } + totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); + } + } + }); + applyFilter.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 3; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(applyFilter,gbConst); + + this.add(upperPanel, BorderLayout.PAGE_START); + + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Source","Amount", "Month"}; + tableVals = new Object[Income.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); + incomeTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { // restricting cell editing + return false; + } + }; + jScrollPane = new JScrollPane(incomeTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < incomeTable.getColumnCount(); i++) { + incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + incomeTable.setDefaultRenderer(String.class, centerRenderer); + + incomeTable.setFont(new Font(null, Font.PLAIN, 24)); + incomeTable.setRowHeight(45); + incomeTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + incomeTable.getTableHeader().setReorderingAllowed(false); + incomeTable.setFocusable(true); + incomeTable.setRowSelectionAllowed(true); + incomeTable.setCellSelectionEnabled(true); + incomeTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + incomeTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { // exports report to csv + expenserMain.exportReport("Income Report"); + } + }); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + + } +} + +class expenseRepPanel extends JPanel { + static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + static JScrollPane jScrollPane; + static ArrayList Spending; + static ArrayList filteredSpending = new ArrayList<>(); + Object[][] tableVals; + String[] columnHeadings; + static JTable spendingTable; + JLabel expenseText; + JLabel totalExpenseLbl, totalFilteredExpenseLbl, filterTxt ; + static JLabel totalExpenseAmtLbl, totalFilteredExpenseAmtLbl; + JButton exportReport, applyFilter; + ExpenserMain expenserMain; + GridBagConstraints gbConst; + JPanel upperPanel; + JComboBox monthSelector; + static JComboBox typeSelector; + String[] frequency; + + expenseRepPanel() { + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + expenseRepPanel.Spending = expenserMain.userAtHand.getSpending(); + + this.setLayout(new BorderLayout()); + + + expenseText = new JLabel("main.java.seng210.Expense Report"); + expenseText.setFont(new Font(null, Font.PLAIN, 40)); + expenseText.setHorizontalAlignment(JLabel.CENTER); + + gbConst = new GridBagConstraints(); + upperPanel = new JPanel(); + upperPanel.setLayout(new GridBagLayout()); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 4; + gbConst.insets = new Insets(20,0,20,0); + upperPanel.add(expenseText, gbConst); + + totalExpenseLbl = new JLabel("Total main.java.seng210.Expense"); + totalExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridwidth = 1; + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(totalExpenseLbl,gbConst); + + totalExpenseAmtLbl = new JLabel("0.00"); + totalExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalExpenseAmtLbl,gbConst); + + totalFilteredExpenseLbl = new JLabel("Expenses (Filtered)"); + totalFilteredExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 2; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalFilteredExpenseLbl,gbConst); + + totalFilteredExpenseAmtLbl = new JLabel("0.00"); + totalFilteredExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 3; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,20); + upperPanel.add(totalFilteredExpenseAmtLbl,gbConst); + + filterTxt = new JLabel("Apply a filter"); + filterTxt.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(filterTxt,gbConst); + + frequency = new String[]{"1", "12","24"}; + monthSelector = new JComboBox<>(frequency); + monthSelector.setFont(new Font(null, Font.PLAIN, 24)); + monthSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(monthSelector,gbConst); + + expenseRepPanel.typeSelector = new JComboBox<>(expenserMain.getExpenseSources(Spending).toArray()); + typeSelector.setFont(new Font(null, Font.PLAIN, 24)); + typeSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 2; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(typeSelector,gbConst); + + applyFilter = new JButton("Filter"); + applyFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == applyFilter) { + filteredSpending = expenserMain.filterExpensesFreq + (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) + ,(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + expenseRepPanel.model.setNumRows(filteredSpending.size()); + int i = 0; + double expenseSum = 0.00f; + for(Expense exp : filteredSpending) { + expenseRepPanel.spendingTable.setValueAt(exp.getSource(), i, 0); + expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); + expenseRepPanel.spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); + ++i; + expenseSum += exp.getAmount(); + } + totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); + } + } + }); + applyFilter.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 3; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(applyFilter,gbConst); + + this.add(upperPanel, BorderLayout.PAGE_START); + + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Source","Amount", "Frequency"}; + tableVals = new Object[Spending.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); + spendingTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { // restricting cell editing + return false; + } + }; + jScrollPane = new JScrollPane(spendingTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < spendingTable.getColumnCount(); i++) { + spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + spendingTable.setDefaultRenderer(String.class, centerRenderer); + + spendingTable.setFont(new Font(null, Font.PLAIN, 24)); + spendingTable.setRowHeight(45); + spendingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + spendingTable.getTableHeader().setReorderingAllowed(false); + spendingTable.setFocusable(true); + spendingTable.setRowSelectionAllowed(true); + spendingTable.setCellSelectionEnabled(true); + spendingTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + spendingTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == exportReport) { + expenserMain.exportReport("main.java.seng210.Expense Report"); + } + } + }); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + + } +} + +class detailedRepPanel extends JPanel { + static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + static JScrollPane jScrollPane; + ArrayList Spending; + ArrayList Income; + Object[][] tableVals; + String[] columnHeadings; + static JTable detailedTable; + JLabel detaileReportTxt; + JButton exportReport; + ExpenserMain expenserMain; + detailedRepPanel() { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = appFrame.user; + + this.setLayout(new BorderLayout()); + detaileReportTxt = new JLabel("Detailed Report"); + detaileReportTxt.setFont(new Font(null, Font.PLAIN, 40)); + detaileReportTxt.setHorizontalAlignment(JLabel.CENTER); + this.add(detaileReportTxt, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; + Spending = expenserMain.userAtHand.getSpending(); + Income = expenserMain.userAtHand.getIncome(); + tableVals = new Object[Spending.size()+Income.size()][4]; + model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model + detailedTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { // restricting cell editing + return false; + } + }; + jScrollPane = new JScrollPane(detailedTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < detailedTable.getColumnCount(); i++) { + detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + detailedTable.setDefaultRenderer(String.class, centerRenderer); + + detailedTable.setFont(new Font(null, Font.PLAIN, 24)); + detailedTable.setRowHeight(45); + detailedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + detailedTable.getTableHeader().setReorderingAllowed(false); + detailedTable.setFocusable(true); + detailedTable.setRowSelectionAllowed(true); + detailedTable.setCellSelectionEnabled(true); + detailedTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + detailedTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + expenserMain.exportReport("Detailed Report"); + } + }); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + } + +} + +class loginPanel extends JPanel { + EWalletApp eWalletApp = new EWalletApp(); + JLabel usernameLbl, passwordLbl, loginLbl; + GridBagConstraints gbConst; + JTextField usernameIncField, passwordIncField; + JButton loginBtn; + String username, password; + + loginPanel() { + loginLbl = new JLabel("LOGIN"); + usernameLbl = new JLabel("Username: "); + passwordLbl = new JLabel("Password: "); + loginBtn = new JButton("Login"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + passwordIncField = new JTextField(); + passwordIncField.setPreferredSize(new Dimension(200, 40)); + usernameIncField = new JTextField(); + usernameIncField.setPreferredSize(new Dimension(200, 40)); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,10,20,40); + loginLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(loginLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(0,5,20,30); + passwordIncField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(passwordIncField, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,30); + usernameIncField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(usernameIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,0,20,20); + passwordLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(passwordLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,0,20,20); + usernameLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(usernameLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + loginBtn.setFont(new Font(null, Font.PLAIN, 28)); + loginBtn.setPreferredSize(new Dimension(150,60)); + this.add(loginBtn, gbConst); + + loginBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + username = usernameIncField.getText(); + password = passwordIncField.getText(); + if(eWalletApp.CheckUsername(username) && eWalletApp.CheckPassword(username, password)) { + usernameIncField.setText(""); + passwordIncField.setText(""); + System.out.println("Login Successful"); + JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); + } else { + JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); + } + } + }); + + + } +} + +class createAccountPanel extends JPanel { + EWalletApp eWalletApp = new EWalletApp(); + JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; + GridBagConstraints gbConst; + static JTextField usernameField, passwordField, confPasswordField; + JButton createAccBtn; + String username, password, confPassword; + + createAccountPanel() { + usernameLbl = new JLabel("Enter Username:"); + passwordLbl = new JLabel("Enter Password:"); + confPasswordLbl = new JLabel("Confirm Password:"); + createAccLbl = new JLabel("Create Account"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + usernameField = new JTextField(); + usernameField.setPreferredSize(new Dimension(200, 40)); + passwordField = new JTextField(); + passwordField.setPreferredSize(new Dimension(200, 40)); + confPasswordField = new JTextField(); + confPasswordField.setPreferredSize(new Dimension(200, 40)); + + createAccBtn = new JButton("Create Account"); + createAccBtn.setPreferredSize(new Dimension(200, 40)); + + gbConst.gridx = 1; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(0,20,40,20); + createAccLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(createAccLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,40,40,0); + usernameLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(usernameLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 1; + gbConst.insets = new Insets(20,0,40,40); + usernameField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(usernameField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,40,40,0); + passwordLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(passwordLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,0,40,40); + passwordField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(passwordField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(0,40,40,0); + confPasswordLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(confPasswordLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,0,40,40); + confPasswordField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(confPasswordField, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 4; + gbConst.insets = new Insets(20, 20, 20, 20); + createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); + this.add(createAccBtn, gbConst); + + createAccBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(e.getSource() == createAccBtn) { + username = usernameField.getText(); + password = passwordField.getText(); + confPassword = confPasswordField.getText(); + if(usernameField.getText().length() > 0 && passwordField.getText().length() > 0 && confPasswordField.getText().length() > 0) { + if(confPassword.equals(password)) { + if(eWalletApp.checkForRepeatUsernames(usernameField.getText())) { + JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); + } else { + eWalletApp.CreateUser(username, password); + JOptionPane.showMessageDialog(null, "main.java.seng210.User created successfully."); + usernameField.setText(""); + passwordField.setText(""); + confPasswordField.setText(""); + } + } else { + JOptionPane.showMessageDialog(null, "Passwords do not match!"); + } + } else { + JOptionPane.showMessageDialog(null,"Not all fields filled out. Please fill them out."); + } + } + } + }); + + } + +} + diff --git a/src/Expense.java b/src/main/java/edu/ferris/seng210/Expense.java similarity index 94% rename from src/Expense.java rename to src/main/java/edu/ferris/seng210/Expense.java index 478404e..a07560e 100644 --- a/src/Expense.java +++ b/src/main/java/edu/ferris/seng210/Expense.java @@ -1,24 +1,26 @@ -public class Expense { - String source; - double amount; - int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly - - Expense(String source, double amount, int yearlyfrequency) { - this.source = source; - this.amount = amount; - this.yearlyfrequency = yearlyfrequency; - } - - public String getSource() { - return this.source; - } - - public double getAmount() { - return this.amount; - } - - public int getFrequency() { - return this.yearlyfrequency; - } - -} +package edu.ferris.seng210; + +public class Expense { + String source; + double amount; + int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly + + Expense(String source, double amount, int yearlyfrequency) { + this.source = source; + this.amount = amount; + this.yearlyfrequency = yearlyfrequency; + } + + public String getSource() { + return this.source; + } + + public double getAmount() { + return this.amount; + } + + public int getFrequency() { + return this.yearlyfrequency; + } + +} diff --git a/src/Expenser.java b/src/main/java/edu/ferris/seng210/Expenser.java similarity index 92% rename from src/Expenser.java rename to src/main/java/edu/ferris/seng210/Expenser.java index e60960e..5be809e 100644 --- a/src/Expenser.java +++ b/src/main/java/edu/ferris/seng210/Expenser.java @@ -1,17 +1,17 @@ -import java.util.ArrayList; - -public interface Expenser { - public void addExpense (Expense Ex); - public void addMonthlyIncome (Wage W); - public void PrintFullreport(); - public void PrintExpensereport(); - public void PrintIncomereport(); - public void PrintIncomereportbyTpe(); - public void PrintExpensebyType(); - public void exportReport(String reportTitle); - public Currency convertForeignCurrency(Currency C, double amount); - public boolean loadExpenseFile(String filePath); - public boolean loadIncomeFile(String filePath); - public int whenCanIBuy(String itemname,double price); - public void updateMonthlySavings(); -} +package edu.ferris.seng210; + +public interface Expenser { + public void addExpense (Expense Ex); + public void addMonthlyIncome (Wage W); + public void PrintFullreport(); + public void PrintExpensereport(); + public void PrintIncomereport(); + public void PrintIncomereportbyTpe(); + public void PrintExpensebyType(); + public void exportReport(String reportTitle); + public Currency convertForeignCurrency(Currency C, double amount); + public boolean loadExpenseFile(String filePath); + public boolean loadIncomeFile(String filePath); + public int whenCanIBuy(String itemname,double price); + public void updateMonthlySavings(); +} diff --git a/src/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java similarity index 96% rename from src/ExpenserMain.java rename to src/main/java/edu/ferris/seng210/ExpenserMain.java index 67e9ce5..102c63d 100644 --- a/src/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -1,3 +1,5 @@ +package edu.ferris.seng210; + import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -49,16 +51,16 @@ public void exportReport(String reportTitle) { reportFile.createNewFile(); - if (reportTitle.startsWith("Expense Report")) { + if (reportTitle.startsWith("main.java.seng210.Expense Report")) { printWriter.append("Total Income"); printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); printWriter.append("\n"); - printWriter.append("Total Expense"); + printWriter.append("Total main.java.seng210.Expense"); printWriter.append(","); printWriter.append("" + userAtHand.getExpenses()); printWriter.append("\n"); - printWriter.append("Filtered Expense"); + printWriter.append("Filtered main.java.seng210.Expense"); printWriter.append(","); printWriter.append("" + expenseRepPanel.totalFilteredExpenseAmtLbl.getText()); printWriter.append("\n"); @@ -78,7 +80,7 @@ public void exportReport(String reportTitle) { printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); printWriter.append("\n"); - printWriter.append("Total Expense"); + printWriter.append("Total main.java.seng210.Expense"); printWriter.append(","); printWriter.append("" + userAtHand.getExpenses()); printWriter.append("\n"); @@ -102,7 +104,7 @@ public void exportReport(String reportTitle) { printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); printWriter.append("\n"); - printWriter.append("Total Expense"); + printWriter.append("Total main.java.seng210.Expense"); printWriter.append(","); printWriter.append("" + userAtHand.getExpenses()); printWriter.append("\n"); @@ -120,7 +122,7 @@ public void exportReport(String reportTitle) { } for (Expense exp : userAtHand.getSpending()) { - printWriter.append("Expense,"); + printWriter.append("main.java.seng210.Expense,"); printWriter.append("" + exp.getSource() + ","); printWriter.append("" + exp.getAmount() + ","); printWriter.append("" + exp.getFrequency() + "\n"); @@ -366,7 +368,7 @@ public void updateDetailedTable() { } for(Expense expense : userAtHand.getSpending()) { - detailedRepPanel.detailedTable.setValueAt("Expense", i, 0); + detailedRepPanel.detailedTable.setValueAt("main.java.seng210.Expense", i, 0); detailedRepPanel.detailedTable.setValueAt(expense.getSource(), i, 1); detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); detailedRepPanel.detailedTable.setValueAt(expense.getFrequency(), i, 3); diff --git a/src/User.java b/src/main/java/edu/ferris/seng210/User.java similarity index 94% rename from src/User.java rename to src/main/java/edu/ferris/seng210/User.java index 2ad32ff..38c1e22 100644 --- a/src/User.java +++ b/src/main/java/edu/ferris/seng210/User.java @@ -1,74 +1,76 @@ -import java.util.ArrayList; - -public class User { - private ArrayList currencyRates; - private ArrayList Income = new ArrayList<>(); - private ArrayList Spending = new ArrayList<>(); - String username; - String pwd; - double balance; - double monthlysavings; - double expenses; - - User(String username, String password){ - this.username = username; - this.pwd = password; - } - - protected String getUsername() { - return this.username; - } - - protected String getPwd() { - return this.pwd; - } - - protected void setUsername(String username) { - this.username = username; - } - - protected void setPwd(String password) { - this.pwd = password; - } - - protected void addExpense(Expense Ex) { - Spending.add(Ex); - } - - protected void addMonthlyIncome(Wage W) { - Income.add(W); - } - - protected ArrayList getIncome() { - return this.Income; - } - - protected ArrayList getSpending() { - return this.Spending; - } - - protected void setBalance(double balance) { - this.balance = balance; - } - - protected double getBalance(){ - return this.balance; - } - - protected void setExpenses(double expenses) { - this.expenses = expenses; - } - - protected double getExpenses() { - return this.expenses; - } - - protected double getMonthlySavings() { - return this.monthlysavings; - } - - protected void setMonthlySavings(double monthlySavings) { - this.monthlysavings = monthlySavings; - } -} - +package edu.ferris.seng210; + +import java.util.ArrayList; + +public class User { + private ArrayList currencyRates; + private ArrayList Income = new ArrayList<>(); + private ArrayList Spending = new ArrayList<>(); + String username; + String pwd; + double balance; + double monthlysavings; + double expenses; + + User(String username, String password){ + this.username = username; + this.pwd = password; + } + + protected String getUsername() { + return this.username; + } + + protected String getPwd() { + return this.pwd; + } + + protected void setUsername(String username) { + this.username = username; + } + + protected void setPwd(String password) { + this.pwd = password; + } + + protected void addExpense(Expense Ex) { + Spending.add(Ex); + } + + protected void addMonthlyIncome(Wage W) { + Income.add(W); + } + + protected ArrayList getIncome() { + return this.Income; + } + + protected ArrayList getSpending() { + return this.Spending; + } + + protected void setBalance(double balance) { + this.balance = balance; + } + + protected double getBalance(){ + return this.balance; + } + + protected void setExpenses(double expenses) { + this.expenses = expenses; + } + + protected double getExpenses() { + return this.expenses; + } + + protected double getMonthlySavings() { + return this.monthlysavings; + } + + protected void setMonthlySavings(double monthlySavings) { + this.monthlysavings = monthlySavings; + } +} + diff --git a/src/Wage.java b/src/main/java/edu/ferris/seng210/Wage.java similarity index 92% rename from src/Wage.java rename to src/main/java/edu/ferris/seng210/Wage.java index bfce2db..69f20b5 100644 --- a/src/Wage.java +++ b/src/main/java/edu/ferris/seng210/Wage.java @@ -1,24 +1,25 @@ - -public class Wage { - String source; - double amount; - String Month; - - Wage(String source, double amount, String Month) { - this.source = source; - this.amount = amount; - this.Month = Month; - } - - public String getSource() { - return this.source; - } - - public double getAmount() { - return this.amount; - } - - public String getMonth() { - return this.Month; - } -} +package edu.ferris.seng210; + +public class Wage { + String source; + double amount; + String Month; + + Wage(String source, double amount, String Month) { + this.source = source; + this.amount = amount; + this.Month = Month; + } + + public String getSource() { + return this.source; + } + + public double getAmount() { + return this.amount; + } + + public String getMonth() { + return this.Month; + } +} From b386ff8b575896d25ff393d43ad85106d60b0f07 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Sun, 16 Mar 2025 21:59:41 -0400 Subject: [PATCH 050/123] changing back User Stories title after renaming issue in requirements.md --- requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.md b/requirements.md index e2fd258..0508d26 100644 --- a/requirements.md +++ b/requirements.md @@ -1,6 +1,6 @@ # Requirements -## main.java.edu.ferris.seng210.User Stories +## User Stories - As a user I would like to provide an item and a price and get an estimate in number of months needed to save up to buy this item (based on current monthly saving). From a9d1a119d516df336626e178178341bc03f245db Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 00:37:34 -0400 Subject: [PATCH 051/123] Splitting up --- .../java/edu/ferris/seng210/AppFrame.java | 243 +++ .../java/edu/ferris/seng210/EWalletApp.java | 1527 +---------------- src/main/java/edu/ferris/seng210/Expense.java | 2 +- .../java/edu/ferris/seng210/Expenser.java | 26 +- .../java/edu/ferris/seng210/ExpenserMain.java | 94 +- .../seng210/PasswordCheckerService.java | 37 + .../seng210/PasswordComplexityChecker.java | 10 + .../ferris/seng210/UserCreationService.java | 35 + .../edu/ferris/seng210/UsernameChecker.java | 73 + src/main/java/edu/ferris/seng210/Wage.java | 2 +- .../ferris/seng210/{ => account}/User.java | 36 +- .../ferris/seng210/panels/AddItemPanel.java | 273 +++ .../seng210/panels/CreateAccountPanel.java | 116 ++ .../seng210/panels/DetailedReportPanel.java | 86 + .../ferris/seng210/panels/EstimatePanel.java | 91 + .../seng210/panels/ExpenseReportPanel.java | 188 ++ .../edu/ferris/seng210/panels/HomePanel.java | 68 + .../ferris/seng210/panels/ImportPanel.java | 136 ++ .../seng210/panels/IncomeReportPanel.java | 185 ++ .../edu/ferris/seng210/panels/LoginPanel.java | 93 + 20 files changed, 1725 insertions(+), 1596 deletions(-) create mode 100644 src/main/java/edu/ferris/seng210/AppFrame.java create mode 100644 src/main/java/edu/ferris/seng210/PasswordCheckerService.java create mode 100644 src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java create mode 100644 src/main/java/edu/ferris/seng210/UserCreationService.java create mode 100644 src/main/java/edu/ferris/seng210/UsernameChecker.java rename src/main/java/edu/ferris/seng210/{ => account}/User.java (51%) create mode 100644 src/main/java/edu/ferris/seng210/panels/AddItemPanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/EstimatePanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/HomePanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/ImportPanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java create mode 100644 src/main/java/edu/ferris/seng210/panels/LoginPanel.java diff --git a/src/main/java/edu/ferris/seng210/AppFrame.java b/src/main/java/edu/ferris/seng210/AppFrame.java new file mode 100644 index 0000000..3c7c461 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/AppFrame.java @@ -0,0 +1,243 @@ +package edu.ferris.seng210; + +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.panels.*; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class AppFrame extends JFrame { + + ExpenserMain expenserMain; + JMenuBar navMenuBar; + JMenu navMenu; + JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; + + AppFrame(){ + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setMinimumSize(new Dimension(900,700)); + this.setTitle("EWallet Application"); + + User user = new User("Default", "TempPassword!123"); + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + + LoginPanel loginPanel = new LoginPanel(); + CreateAccountPanel createAccountPanel = new CreateAccountPanel(); + HomePanel homePanel = new HomePanel(); + ImportPanel importPanel = new ImportPanel(user); + EstimatePanel estimatePanel = new EstimatePanel(); + IncomeReportPanel incomeReportPanel = new IncomeReportPanel(user); + ExpenseReportPanel expenseReportPanel = new ExpenseReportPanel(user); + DetailedReportPanel detailedReportPanel = new DetailedReportPanel(user); + AddItemPanel addItemPanel = new AddItemPanel(user, expenseReportPanel, incomeReportPanel); + getContentPane().add(homePanel); + navMenuBar = new JMenuBar(); + navMenu = new JMenu("

Menu"); // Menu + homeNav = new JMenuItem("

Home"); // Home Page + homeNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(homePanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + addItemNav = new JMenuItem("

Add Item"); // Add Items Page + addItemNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(addItemPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + importNav = new JMenuItem("

Import Tool"); // Import Page + importNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mouseClicked(e); + getContentPane().removeAll(); + revalidate(); + repaint(); + getContentPane().add(importPanel); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page + estimateNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(estimatePanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + incomeReportNav = new JMenuItem("

Income Report"); + incomeReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(incomeReportPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + expenseReportNav = new JMenuItem("

Expense Report"); + expenseReportNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(expenseReportPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + detailedReportNav = new JMenuItem("

Detailed Report"); + detailedReportNav.addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(detailedReportPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + loginNav = new JMenuItem("

Login"); // Add Items Page + loginNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(loginPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + createAccNav = new JMenuItem("

Create Account"); // Add Items Page + createAccNav.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(createAccountPanel); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }); + + navMenu.setFont(new Font(null, Font.PLAIN, 24)); + homeNav.setFont(new Font(null, Font.PLAIN, 20)); + addItemNav.setFont(new Font(null, Font.PLAIN, 20)); + importNav.setFont(new Font(null, Font.PLAIN, 20)); + estimateNav.setFont(new Font(null, Font.PLAIN, 20)); + incomeReportNav.setFont(new Font(null, Font.PLAIN, 20)); + expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); + detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); + loginNav.setFont(new Font(null, Font.PLAIN, 20)); + createAccNav.setFont(new Font(null, Font.PLAIN, 20)); + + navMenu.add(homeNav); + navMenu.add(addItemNav); + navMenu.add(importNav); + navMenu.add(estimateNav); + navMenu.add(incomeReportNav); + navMenu.add(expenseReportNav); + navMenu.add(detailedReportNav); + navMenu.add(loginNav); + navMenu.add(createAccNav); + navMenuBar.add(navMenu); + + + this.setJMenuBar(navMenuBar); + this.setLayout(new CardLayout()); + this.pack(); + this.setVisible(true); + } + +} diff --git a/src/main/java/edu/ferris/seng210/EWalletApp.java b/src/main/java/edu/ferris/seng210/EWalletApp.java index bb50394..285bcb0 100644 --- a/src/main/java/edu/ferris/seng210/EWalletApp.java +++ b/src/main/java/edu/ferris/seng210/EWalletApp.java @@ -1,1531 +1,16 @@ package edu.ferris.seng210; -import javax.swing.*; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.DefaultTableModel; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import edu.ferris.seng210.account.User; + import java.util.ArrayList; -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.List; public class EWalletApp { - private ArrayList AllData = new ArrayList<>(); - - public void CreateUser(String username, String password) { - - if (!checkForRepeatUsernames(username) && isComplexPassword(password)) { - User user = new User(username, password); - AllData.add(user); - - try { - FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); - PrintWriter printWriter = new PrintWriter(fileOutputStream); - printWriter.append(username); - printWriter.append(","); - printWriter.append(password); - printWriter.append(",\n"); - printWriter.close(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } - } - - - - public boolean CheckUsername(String username) { - boolean flag = false; - String savedUser; - - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - while(scnr.hasNextLine()) { - savedUser = scnr.nextLine(); - if(savedUser.indexOf(username) != -1) { - flag = true; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return flag; - } - - public boolean CheckPassword(String username,String password) { - boolean flag = false; - String lineTxt; - - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - while(scnr.hasNextLine()) { - lineTxt = scnr.nextLine(); - if(lineTxt.indexOf(username) != -1) { - if((lineTxt.indexOf(username) + username.length() + 1) == lineTxt.indexOf(password)) { - for(int i = 0; i < AllData.size(); i++) { - if(AllData.get(i).getUsername().equals(username)) { - appFrame.user = AllData.get(i); - } - } - flag = true; - break; - } - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return flag; - } - - public boolean checkForRepeatUsernames(String username) { - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - Path path = Paths.get("src/UserCredentials.csv"); - long lines = Files.lines(path).count(); - String textAtLine; - String readUsername; - if(lines < 1) { - System.out.println("There is no data in file."); - } else { - for (int i = 0; i < lines; i++) { - textAtLine = scnr.nextLine(); - readUsername = ""; - for (int j = 0; j < textAtLine.length(); j++) { - if (textAtLine.charAt(j) != ',') { - readUsername += textAtLine.charAt(j); - } else { - break; - } - } - if (username.equals(readUsername)) { - - System.out.println("Username already exists."); - return true; - - } - } - } - - } catch (FileNotFoundException e) { - - System.out.println("The file UserCredentials.csv was not found."); - - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - - public boolean isComplexPassword(String password) { - - try { - - String passwordRegEx = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=\\S+$).{8,20}$"; - Pattern pattern = Pattern.compile(passwordRegEx); - Matcher matcher = pattern.matcher(password); - if(!matcher.find()) { - System.out.println("Password is not valid."); - } else { - System.out.println("Password is valid."); - return true; - } - - } catch (Exception e) { - e.printStackTrace(); - } - return false; - } + public static List users = new ArrayList<>(); + public static User activeUser = null; public static void main(String[] args) { - appFrame app = new appFrame(); - + AppFrame app = new AppFrame(); } - } - -class appFrame extends JFrame { - - static User user; - ExpenserMain expenserMain; - JMenuBar navMenuBar; - JMenu navMenu; - JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; - - appFrame(){ - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - this.setMinimumSize(new Dimension(900,700)); - this.setTitle("EWallet Application"); - - user = new User("Default", "TempPassword!123"); - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; - - loginPanel lPanel = new loginPanel(); - createAccountPanel createAccPanel = new createAccountPanel(); - homePanel hPanel = new homePanel(); - addItemPanel addItmPanel = new addItemPanel(); - importPanel impPanel = new importPanel(); - estimatePanel estPanel = new estimatePanel(); - incomeRepPanel incRepPanel = new incomeRepPanel(); - expenseRepPanel expRepPanel = new expenseRepPanel(); - detailedRepPanel detRepPanel = new detailedRepPanel(); - getContentPane().add(hPanel); - navMenuBar = new JMenuBar(); - navMenu = new JMenu("

Menu"); // Menu - homeNav = new JMenuItem("

Home"); // Home Page - homeNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(hPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - addItemNav = new JMenuItem("

Add Item"); // Add Items Page - addItemNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(addItmPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - importNav = new JMenuItem("

Import Tool"); // Import Page - importNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - super.mouseClicked(e); - getContentPane().removeAll(); - revalidate(); - repaint(); - getContentPane().add(impPanel); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page - estimateNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(estPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - incomeReportNav = new JMenuItem("

Income Report"); - incomeReportNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(incRepPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - expenseReportNav = new JMenuItem("

main.java.seng210.Expense Report"); - expenseReportNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(expRepPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - detailedReportNav = new JMenuItem("

Detailed Report"); - detailedReportNav.addMouseListener(new MouseAdapter() { - - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(detRepPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - loginNav = new JMenuItem("

Login"); // Add Items Page - loginNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(lPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - createAccNav = new JMenuItem("

Create Account"); // Add Items Page - createAccNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(createAccPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); - - navMenu.setFont(new Font(null, Font.PLAIN, 24)); - homeNav.setFont(new Font(null, Font.PLAIN, 20)); - addItemNav.setFont(new Font(null, Font.PLAIN, 20)); - importNav.setFont(new Font(null, Font.PLAIN, 20)); - estimateNav.setFont(new Font(null, Font.PLAIN, 20)); - incomeReportNav.setFont(new Font(null, Font.PLAIN, 20)); - expenseReportNav.setFont(new Font(null, Font.PLAIN, 20)); - detailedReportNav.setFont(new Font(null, Font.PLAIN, 20)); - loginNav.setFont(new Font(null, Font.PLAIN, 20)); - createAccNav.setFont(new Font(null, Font.PLAIN, 20)); - - navMenu.add(homeNav); - navMenu.add(addItemNav); - navMenu.add(importNav); - navMenu.add(estimateNav); - navMenu.add(incomeReportNav); - navMenu.add(expenseReportNav); - navMenu.add(detailedReportNav); - navMenu.add(loginNav); - navMenu.add(createAccNav); - navMenuBar.add(navMenu); - - - this.setJMenuBar(navMenuBar); - this.setLayout(new CardLayout()); - this.pack(); - this.setVisible(true); - } -} - -class homePanel extends JPanel { - - JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; - static JLabel totalExpensesAmtLbl, totalSavingsAmtLbl, totalIncomeAmtLbl; - GridBagConstraints gbConst; - homePanel() { - - summaryTxt = new JLabel("main.java.seng210.User Summary"); - totalIncomeLbl = new JLabel("Total Income: "); - totalIncomeAmtLbl = new JLabel("$0.00"); - totalExpensesLbl = new JLabel("Total Expenses: "); - totalExpensesAmtLbl = new JLabel("$0.00"); - totalSavingsLbl = new JLabel("Total Savings: "); - totalSavingsAmtLbl = new JLabel("$0.00"); - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,20,60,20); - summaryTxt.setFont(new Font(null, Font.PLAIN, 44)); - this.add(summaryTxt, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(20,40,20,5); - totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(20,10,20,40); - totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalIncomeAmtLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(20,40,20,5); - totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalExpensesLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(20,10,20,40); - totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalExpensesAmtLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(20,40,40,5); - totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalSavingsLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(20,10,40,40); - totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(totalSavingsAmtLbl, gbConst); - } -} - -class addItemPanel extends JTabbedPane { - - ExpenserMain expenserMain; - int yearlyFrequency; - double amount; - String month, source; - GridBagConstraints gbConst; - JPanel incomePane, expensePane; - JLabel addIncomeItemLbl, addExpenseItemLbl; - JLabel nameIncomeLbl, amountIncomeLbl, monthIncomeLbl; - JLabel nameExpenseLbl, amountExpenseLbl, frequencyExpLbl; - JTextField nameIncField, amountIncField, frequencyExpField; - JTextField nameExpField, amountExpField; - JButton addIncomeButton, addExpenseButton; - JComboBox monthComboBox; - String[] months; - addItemPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - - months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; - incomePane = new JPanel(); - expensePane = new JPanel(); - - monthComboBox = new JComboBox<>(months); - monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); - monthComboBox.setSelectedIndex(0); - - addIncomeButton = new JButton("Add"); - addExpenseButton = new JButton("Add"); - - gbConst = new GridBagConstraints(); - incomePane.setLayout(new GridBagLayout()); - expensePane.setLayout(new GridBagLayout()); - - addIncomeItemLbl = new JLabel("Add Item"); - nameIncomeLbl = new JLabel("Name"); - amountIncomeLbl = new JLabel("Amount"); - monthIncomeLbl = new JLabel("Month"); - - addExpenseItemLbl = new JLabel("Add Item"); - nameExpenseLbl = new JLabel("Name"); - amountExpenseLbl = new JLabel("Amount"); - frequencyExpLbl = new JLabel("Freq."); - - nameIncField = new JTextField(); - nameIncField.setPreferredSize(new Dimension(280, 50)); - amountIncField = new JTextField(); - amountIncField.setPreferredSize(new Dimension(280, 50)); - frequencyExpField = new JTextField(); - frequencyExpField.setPreferredSize(new Dimension(280, 50)); - - nameExpField = new JTextField(); - nameExpField.setPreferredSize(new Dimension(280, 50)); - amountExpField = new JTextField(); - amountExpField.setPreferredSize(new Dimension(280, 50)); - monthComboBox.setPreferredSize(new Dimension(280, 50)); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(0,20,60,30); - addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 44)); - incomePane.add(addIncomeItemLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(nameIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,30,30); - nameIncField.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(nameIncField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(amountIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,30,30); - amountIncField.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(amountIncField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - monthIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - incomePane.add(monthIncomeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,30,30); - monthComboBox.setFont(new Font(null, Font.PLAIN, 28)); - incomePane.add(monthComboBox, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,30,30,30); - addIncomeButton.setFont(new Font(null, Font.PLAIN, 28)); - addIncomeButton.setPreferredSize(new Dimension(150,60)); - incomePane.add(addIncomeButton, gbConst); - - addIncomeButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == addIncomeButton) { - if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0) { - try { - amount = Double.parseDouble(amountIncField.getText()); - } catch (NumberFormatException n) { - System.out.println(n.getMessage()); - amount = 0.00f; - } - source = nameIncField.getText(); - month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); - Wage w = new Wage(source, amount, month); - expenserMain.userAtHand.addMonthlyIncome(w); - - if(incomeRepPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { - if (incomeRepPanel.typeSelector.getItemAt(i).equals(w.getSource())) { - contains = true; - } - } - if (!contains) { - incomeRepPanel.typeSelector.addItem(w.getSource()); - } - } else { - incomeRepPanel.typeSelector.addItem(w.getSource()); - } - - expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(); - expenserMain.updateDetailedTable(); - - nameIncField.setText(""); - monthComboBox.setSelectedItem(0); - amountIncField.setText(""); - - } - - } - } - }); - - this.add("Add Income", incomePane); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.insets = new Insets(0,20,60,30); - addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 44)); - expensePane.add(addExpenseItemLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(nameExpenseLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(10,10,30,30); - nameExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(nameExpField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(amountExpenseLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,30,30); - amountExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(amountExpField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,20,30,30); - frequencyExpLbl.setFont(new Font(null, Font.PLAIN, 32)); - expensePane.add(frequencyExpLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,30,30); - frequencyExpField.setFont(new Font(null, Font.PLAIN, 28)); - expensePane.add(frequencyExpField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,30,30,30); - addExpenseButton.setFont(new Font(null, Font.PLAIN, 28)); - addExpenseButton.setPreferredSize(new Dimension(150,60)); - expensePane.add(addExpenseButton, gbConst); - - addExpenseButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == addExpenseButton) { - if(nameExpField.getText().length() > 0 && amountExpField.getText().length() > 0 & frequencyExpField.getText().length() > 0) { - try { - amount = Double.parseDouble(amountExpField.getText()); - yearlyFrequency = Integer.parseInt(frequencyExpField.getText()); - - } catch (NumberFormatException n) { - System.out.println(n.getMessage()); - amount = 0.00f; - } - source = nameExpField.getText(); - Expense Ex = new Expense(source, amount, yearlyFrequency); - expenserMain.addExpense(Ex); - expenserMain.updateExpenseValues(); - - if(expenseRepPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { - if (expenseRepPanel.typeSelector.getItemAt(i).equals(Ex.getSource())) { - contains = true; - } - } - if (!contains) { - expenseRepPanel.typeSelector.addItem(Ex.getSource()); - } - } else { - expenseRepPanel.typeSelector.addItem(Ex.getSource()); - } - - - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - - nameExpField.setText(""); - frequencyExpField.setText(""); - amountExpField.setText(""); - } - } - } - }); - - this.add("Add main.java.seng210.Expense", expensePane); - this.setFont(new Font(null, Font.PLAIN, 24)); - } -} - -class importPanel extends JPanel { - - ExpenserMain expenserMain; - GridBagConstraints gbConst; - JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; - JButton selectFileButton, importButton; - JFileChooser fileChooser; - String[] typesOfImports; - JComboBox options; - File userFile; - importPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - - fileChooser = new JFileChooser(); - - this.setLayout(new GridBagLayout()); - gbConst = new GridBagConstraints(); - typesOfImports = new String[] {"Income","main.java.seng210.Expense"}; - options = new JComboBox<>(typesOfImports); - options.setSelectedIndex(0); - - importLbl = new JLabel("Import From File"); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(10,30,20,30); - importLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(importLbl, gbConst); - - selectFileButton = new JButton("File"); - selectFileButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() == selectFileButton) { - int userDecision = fileChooser.showOpenDialog(null); - if(userDecision == JFileChooser.APPROVE_OPTION) { - userFile = fileChooser.getSelectedFile(); - if(!userFile.getAbsolutePath().endsWith(".csv")){ - JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); - System.out.println("main.java.seng210.User selected a non csv file!"); - } - System.out.println("The user selected: " + userFile.getAbsolutePath()); - } else if (userDecision == JFileChooser.CANCEL_OPTION) { - System.out.println("The user canceled the operation."); - } - } - } - }); - - selectFileLbl = new JLabel("Select File"); - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(30,30,20,0); - selectFileLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(selectFileLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(30,0,20,30); - selectFileButton.setFont(new Font(null, Font.PLAIN, 24)); - this.add(selectFileButton, gbConst); - - selectTypeLbl = new JLabel("Select Type"); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(30,30,20,0); - selectTypeLbl.setFont(new Font(null, Font.PLAIN, 24)); - this.add(selectTypeLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(30,0,20,30); - options.setFont(new Font(null, Font.PLAIN, 24)); - this.add(options, gbConst); - - descriptionLbl = new JLabel("Note: Only csv files are supported.

The format of the csv file matters.
The first line of the file needs to contain \"source,amount,month\" or
\"source,amount,frequency\", depending on the type

Once you select a file, click the import button."); - gbConst.gridwidth = 2; - gbConst.gridheight = 2; - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(30,30,30,30); - descriptionLbl.setFont(new Font(null, Font.PLAIN, 20)); - this.add(descriptionLbl, gbConst); - - importButton = new JButton("Import"); - importButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { - System.out.println("Income Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadIncomeFile(userFile.getAbsolutePath()); - expenserMain.updateIncomeTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateIncomeValues(); - } - } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { - System.out.println("main.java.seng210.Expense Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadExpenseFile(userFile.getAbsolutePath()); - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateExpenseValues(); - } - } - - } - }); - gbConst.gridheight = 1; - gbConst.gridx = 0; - gbConst.gridy = 5; - gbConst.insets = new Insets(30,0,30,30); - importButton.setFont(new Font(null, Font.PLAIN, 24)); - this.add(importButton, gbConst); - - } -} - -class estimatePanel extends JPanel { - GridBagConstraints gbConst; - JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; - JTextField nameField, priceField; - JButton estimateButton; - estimatePanel() { - this.setLayout(new GridBagLayout()); - gbConst = new GridBagConstraints(); - - estimateTitleLbl = new JLabel("Estimate Tool"); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(10,20,30,30); - estimateTitleLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(estimateTitleLbl, gbConst); - - estimateLbl = new JLabel("Estimate:"); - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(10,0,30,0); - estimateLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(estimateLbl, gbConst); - - estimateAmtLbl = new JLabel("0 days"); - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(10,0,30,0); - estimateAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(estimateAmtLbl, gbConst); - - nameLbl = new JLabel("Item Name"); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,20,30,30); - nameLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(nameLbl, gbConst); - - nameField = new JTextField(); - nameField.setPreferredSize(new Dimension(280, 50)); - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(10,10,30,30); - nameField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(nameField, gbConst); - - priceLbl = new JLabel("Item Price"); - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,20,30,30); - priceLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(priceLbl, gbConst); - - priceField = new JTextField(); - priceField.setPreferredSize(new Dimension(280, 50)); - gbConst.gridx = 1; - gbConst.gridy = 3; - gbConst.insets = new Insets(10,10,30,30); - priceField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(priceField, gbConst); - - estimateButton = new JButton("Get Estimate"); - estimateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == estimateButton) { - System.out.println("Get Estimate Button Clicked."); - nameField.setText(""); - priceField.setText(""); - } - } - }); - estimateButton.setPreferredSize(new Dimension(220, 60)); - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(30,30,30,30); - estimateButton.setFont(new Font(null, Font.PLAIN, 28)); - this.add(estimateButton, gbConst); - - } -} - -class incomeRepPanel extends JPanel { - static DefaultTableModel model; - DefaultTableCellRenderer centerRenderer; - static JScrollPane jScrollPane; - static ArrayList Income; - static ArrayList filteredIncomeList = new ArrayList<>(); - Object[][] tableVals; // table values - String[] columnHeadings; - static JTable incomeTable; - JLabel incomeText, filterTxt; - JLabel totalIncomeLbl, totalFilteredIncomeLbl; - static JLabel totalIncomeAmtLbl, totalFilteredIncomeAmtLbl; - JButton exportReport, applyFilter; - ExpenserMain expenserMain; - GridBagConstraints gbConst; - JPanel upperPanel; - JComboBox monthSelector; - static JComboBox typeSelector; - String[] months; - incomeRepPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - incomeRepPanel.Income = expenserMain.userAtHand.getIncome(); - - this.setLayout(new BorderLayout()); - - incomeText = new JLabel("Income Report"); - incomeText.setFont(new Font(null, Font.PLAIN, 40)); - incomeText.setHorizontalAlignment(JLabel.CENTER); - - gbConst = new GridBagConstraints(); - upperPanel = new JPanel(); - upperPanel.setLayout(new GridBagLayout()); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 4; - gbConst.insets = new Insets(20,0,20,0); - upperPanel.add(incomeText, gbConst); - - totalIncomeLbl = new JLabel("Total Income"); - totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridwidth = 1; - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(totalIncomeLbl,gbConst); - - totalIncomeAmtLbl = new JLabel("0.00"); - totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalIncomeAmtLbl,gbConst); - - totalFilteredIncomeLbl = new JLabel("Income (Filtered)"); - totalFilteredIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 2; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalFilteredIncomeLbl,gbConst); - - totalFilteredIncomeAmtLbl = new JLabel("0.00"); - totalFilteredIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 3; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,20); - upperPanel.add(totalFilteredIncomeAmtLbl,gbConst); - - filterTxt = new JLabel("Apply a filter"); - filterTxt.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(filterTxt,gbConst); - - months = new String[]{"","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; - monthSelector = new JComboBox<>(months); - monthSelector.setPreferredSize(new Dimension(200,50)); - monthSelector.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(monthSelector,gbConst); - - incomeRepPanel.typeSelector = new JComboBox<>(expenserMain.getIncomeSources(Income).toArray()); - typeSelector.setFont(new Font(null, Font.PLAIN, 24)); - typeSelector.setPreferredSize(new Dimension(200,50)); - gbConst.gridx = 2; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(typeSelector,gbConst); - - applyFilter = new JButton("Filter"); - applyFilter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - filteredIncomeList = - expenserMain.filterIncomesMonth(expenserMain.filterIncomesSource(expenserMain.userAtHand.getIncome(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); - incomeRepPanel.model.setNumRows(filteredIncomeList.size()); - int i = 0; - double incomeSum = 0.00f; - for(Wage wage : filteredIncomeList) { - incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); - incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); - ++i; - incomeSum += wage.getAmount(); - } - totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); - } - } - }); - applyFilter.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 3; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(applyFilter,gbConst); - - this.add(upperPanel, BorderLayout.PAGE_START); - - centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Source","Amount", "Month"}; - tableVals = new Object[Income.size()][3]; - model = new DefaultTableModel(tableVals, columnHeadings); - incomeTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing - return false; - } - }; - jScrollPane = new JScrollPane(incomeTable); - - centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 0; i < incomeTable.getColumnCount(); i++) { - incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); - } - incomeTable.setDefaultRenderer(String.class, centerRenderer); - - incomeTable.setFont(new Font(null, Font.PLAIN, 24)); - incomeTable.setRowHeight(45); - incomeTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - incomeTable.getTableHeader().setReorderingAllowed(false); - incomeTable.setFocusable(true); - incomeTable.setRowSelectionAllowed(true); - incomeTable.setCellSelectionEnabled(true); - incomeTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); - incomeTable.setShowVerticalLines(false); - - this.add(jScrollPane, BorderLayout.CENTER); - - exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { // exports report to csv - expenserMain.exportReport("Income Report"); - } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); - - } -} - -class expenseRepPanel extends JPanel { - static DefaultTableModel model; - DefaultTableCellRenderer centerRenderer; - static JScrollPane jScrollPane; - static ArrayList Spending; - static ArrayList filteredSpending = new ArrayList<>(); - Object[][] tableVals; - String[] columnHeadings; - static JTable spendingTable; - JLabel expenseText; - JLabel totalExpenseLbl, totalFilteredExpenseLbl, filterTxt ; - static JLabel totalExpenseAmtLbl, totalFilteredExpenseAmtLbl; - JButton exportReport, applyFilter; - ExpenserMain expenserMain; - GridBagConstraints gbConst; - JPanel upperPanel; - JComboBox monthSelector; - static JComboBox typeSelector; - String[] frequency; - - expenseRepPanel() { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - expenseRepPanel.Spending = expenserMain.userAtHand.getSpending(); - - this.setLayout(new BorderLayout()); - - - expenseText = new JLabel("main.java.seng210.Expense Report"); - expenseText.setFont(new Font(null, Font.PLAIN, 40)); - expenseText.setHorizontalAlignment(JLabel.CENTER); - - gbConst = new GridBagConstraints(); - upperPanel = new JPanel(); - upperPanel.setLayout(new GridBagLayout()); - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 4; - gbConst.insets = new Insets(20,0,20,0); - upperPanel.add(expenseText, gbConst); - - totalExpenseLbl = new JLabel("Total main.java.seng210.Expense"); - totalExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridwidth = 1; - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(totalExpenseLbl,gbConst); - - totalExpenseAmtLbl = new JLabel("0.00"); - totalExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalExpenseAmtLbl,gbConst); - - totalFilteredExpenseLbl = new JLabel("Expenses (Filtered)"); - totalFilteredExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 2; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,5); - upperPanel.add(totalFilteredExpenseLbl,gbConst); - - totalFilteredExpenseAmtLbl = new JLabel("0.00"); - totalFilteredExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); - gbConst.gridx = 3; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,20); - upperPanel.add(totalFilteredExpenseAmtLbl,gbConst); - - filterTxt = new JLabel("Apply a filter"); - filterTxt.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,0); - upperPanel.add(filterTxt,gbConst); - - frequency = new String[]{"1", "12","24"}; - monthSelector = new JComboBox<>(frequency); - monthSelector.setFont(new Font(null, Font.PLAIN, 24)); - monthSelector.setPreferredSize(new Dimension(200,50)); - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(monthSelector,gbConst); - - expenseRepPanel.typeSelector = new JComboBox<>(expenserMain.getExpenseSources(Spending).toArray()); - typeSelector.setFont(new Font(null, Font.PLAIN, 24)); - typeSelector.setPreferredSize(new Dimension(200,50)); - gbConst.gridx = 2; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(typeSelector,gbConst); - - applyFilter = new JButton("Filter"); - applyFilter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - filteredSpending = expenserMain.filterExpensesFreq - (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) - ,(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); - expenseRepPanel.model.setNumRows(filteredSpending.size()); - int i = 0; - double expenseSum = 0.00f; - for(Expense exp : filteredSpending) { - expenseRepPanel.spendingTable.setValueAt(exp.getSource(), i, 0); - expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); - expenseRepPanel.spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); - ++i; - expenseSum += exp.getAmount(); - } - totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); - } - } - }); - applyFilter.setFont(new Font(null, Font.PLAIN, 24)); - gbConst.gridx = 3; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(applyFilter,gbConst); - - this.add(upperPanel, BorderLayout.PAGE_START); - - centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Source","Amount", "Frequency"}; - tableVals = new Object[Spending.size()][3]; - model = new DefaultTableModel(tableVals, columnHeadings); - spendingTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing - return false; - } - }; - jScrollPane = new JScrollPane(spendingTable); - - centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 0; i < spendingTable.getColumnCount(); i++) { - spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); - } - spendingTable.setDefaultRenderer(String.class, centerRenderer); - - spendingTable.setFont(new Font(null, Font.PLAIN, 24)); - spendingTable.setRowHeight(45); - spendingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - spendingTable.getTableHeader().setReorderingAllowed(false); - spendingTable.setFocusable(true); - spendingTable.setRowSelectionAllowed(true); - spendingTable.setCellSelectionEnabled(true); - spendingTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); - spendingTable.setShowVerticalLines(false); - - this.add(jScrollPane, BorderLayout.CENTER); - - exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == exportReport) { - expenserMain.exportReport("main.java.seng210.Expense Report"); - } - } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); - - } -} - -class detailedRepPanel extends JPanel { - static DefaultTableModel model; - DefaultTableCellRenderer centerRenderer; - static JScrollPane jScrollPane; - ArrayList Spending; - ArrayList Income; - Object[][] tableVals; - String[] columnHeadings; - static JTable detailedTable; - JLabel detaileReportTxt; - JButton exportReport; - ExpenserMain expenserMain; - detailedRepPanel() { - - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = appFrame.user; - - this.setLayout(new BorderLayout()); - detaileReportTxt = new JLabel("Detailed Report"); - detaileReportTxt.setFont(new Font(null, Font.PLAIN, 40)); - detaileReportTxt.setHorizontalAlignment(JLabel.CENTER); - this.add(detaileReportTxt, BorderLayout.PAGE_START); - centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; - Spending = expenserMain.userAtHand.getSpending(); - Income = expenserMain.userAtHand.getIncome(); - tableVals = new Object[Spending.size()+Income.size()][4]; - model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model - detailedTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing - return false; - } - }; - jScrollPane = new JScrollPane(detailedTable); - - centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); - for (int i = 0; i < detailedTable.getColumnCount(); i++) { - detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); - } - detailedTable.setDefaultRenderer(String.class, centerRenderer); - - detailedTable.setFont(new Font(null, Font.PLAIN, 24)); - detailedTable.setRowHeight(45); - detailedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - detailedTable.getTableHeader().setReorderingAllowed(false); - detailedTable.setFocusable(true); - detailedTable.setRowSelectionAllowed(true); - detailedTable.setCellSelectionEnabled(true); - detailedTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); - detailedTable.setShowVerticalLines(false); - - this.add(jScrollPane, BorderLayout.CENTER); - - exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - expenserMain.exportReport("Detailed Report"); - } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); - } - -} - -class loginPanel extends JPanel { - EWalletApp eWalletApp = new EWalletApp(); - JLabel usernameLbl, passwordLbl, loginLbl; - GridBagConstraints gbConst; - JTextField usernameIncField, passwordIncField; - JButton loginBtn; - String username, password; - - loginPanel() { - loginLbl = new JLabel("LOGIN"); - usernameLbl = new JLabel("Username: "); - passwordLbl = new JLabel("Password: "); - loginBtn = new JButton("Login"); - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); - - passwordIncField = new JTextField(); - passwordIncField.setPreferredSize(new Dimension(200, 40)); - usernameIncField = new JTextField(); - usernameIncField.setPreferredSize(new Dimension(200, 40)); - - gbConst.gridx = 0; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,10,20,40); - loginLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(loginLbl, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 2; - gbConst.gridwidth = 1; - gbConst.insets = new Insets(0,5,20,30); - passwordIncField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(passwordIncField, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,5,20,30); - usernameIncField.setFont(new Font(null, Font.PLAIN, 28)); - this.add(usernameIncField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,0,20,20); - passwordLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(passwordLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,0,20,20); - usernameLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(usernameLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 4; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(20,30,30,30); - loginBtn.setFont(new Font(null, Font.PLAIN, 28)); - loginBtn.setPreferredSize(new Dimension(150,60)); - this.add(loginBtn, gbConst); - - loginBtn.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - username = usernameIncField.getText(); - password = passwordIncField.getText(); - if(eWalletApp.CheckUsername(username) && eWalletApp.CheckPassword(username, password)) { - usernameIncField.setText(""); - passwordIncField.setText(""); - System.out.println("Login Successful"); - JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); - } else { - JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); - } - } - }); - - - } -} - -class createAccountPanel extends JPanel { - EWalletApp eWalletApp = new EWalletApp(); - JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; - GridBagConstraints gbConst; - static JTextField usernameField, passwordField, confPasswordField; - JButton createAccBtn; - String username, password, confPassword; - - createAccountPanel() { - usernameLbl = new JLabel("Enter Username:"); - passwordLbl = new JLabel("Enter Password:"); - confPasswordLbl = new JLabel("Confirm Password:"); - createAccLbl = new JLabel("Create Account"); - gbConst = new GridBagConstraints(); - this.setLayout(new GridBagLayout()); - - usernameField = new JTextField(); - usernameField.setPreferredSize(new Dimension(200, 40)); - passwordField = new JTextField(); - passwordField.setPreferredSize(new Dimension(200, 40)); - confPasswordField = new JTextField(); - confPasswordField.setPreferredSize(new Dimension(200, 40)); - - createAccBtn = new JButton("Create Account"); - createAccBtn.setPreferredSize(new Dimension(200, 40)); - - gbConst.gridx = 1; - gbConst.gridy = 0; - gbConst.gridwidth = 2; - gbConst.insets = new Insets(0,20,40,20); - createAccLbl.setFont(new Font(null, Font.PLAIN, 44)); - this.add(createAccLbl, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 1; - gbConst.insets = new Insets(0,40,40,0); - usernameLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(usernameLbl, gbConst); - - gbConst.gridx = -1; - gbConst.gridy = 1; - gbConst.insets = new Insets(20,0,40,40); - usernameField.setFont(new Font(null, Font.PLAIN, 32)); - this.add(usernameField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 2; - gbConst.insets = new Insets(0,40,40,0); - passwordLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(passwordLbl, gbConst); - - gbConst.gridx = -1; - gbConst.gridy = 2; - gbConst.insets = new Insets(20,0,40,40); - passwordField.setFont(new Font(null, Font.PLAIN, 32)); - this.add(passwordField, gbConst); - - gbConst.gridx = 0; - gbConst.gridy = 3; - gbConst.insets = new Insets(0,40,40,0); - confPasswordLbl.setFont(new Font(null, Font.PLAIN, 32)); - this.add(confPasswordLbl, gbConst); - - gbConst.gridx = -1; - gbConst.gridy = 3; - gbConst.insets = new Insets(20,0,40,40); - confPasswordField.setFont(new Font(null, Font.PLAIN, 32)); - this.add(confPasswordField, gbConst); - - gbConst.gridx = 1; - gbConst.gridy = 4; - gbConst.insets = new Insets(20, 20, 20, 20); - createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); - this.add(createAccBtn, gbConst); - - createAccBtn.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if(e.getSource() == createAccBtn) { - username = usernameField.getText(); - password = passwordField.getText(); - confPassword = confPasswordField.getText(); - if(usernameField.getText().length() > 0 && passwordField.getText().length() > 0 && confPasswordField.getText().length() > 0) { - if(confPassword.equals(password)) { - if(eWalletApp.checkForRepeatUsernames(usernameField.getText())) { - JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); - } else { - eWalletApp.CreateUser(username, password); - JOptionPane.showMessageDialog(null, "main.java.seng210.User created successfully."); - usernameField.setText(""); - passwordField.setText(""); - confPasswordField.setText(""); - } - } else { - JOptionPane.showMessageDialog(null, "Passwords do not match!"); - } - } else { - JOptionPane.showMessageDialog(null,"Not all fields filled out. Please fill them out."); - } - } - } - }); - - } - -} - diff --git a/src/main/java/edu/ferris/seng210/Expense.java b/src/main/java/edu/ferris/seng210/Expense.java index a07560e..99b170e 100644 --- a/src/main/java/edu/ferris/seng210/Expense.java +++ b/src/main/java/edu/ferris/seng210/Expense.java @@ -5,7 +5,7 @@ public class Expense { double amount; int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly - Expense(String source, double amount, int yearlyfrequency) { + public Expense(String source, double amount, int yearlyfrequency) { this.source = source; this.amount = amount; this.yearlyfrequency = yearlyfrequency; diff --git a/src/main/java/edu/ferris/seng210/Expenser.java b/src/main/java/edu/ferris/seng210/Expenser.java index 5be809e..ac43eeb 100644 --- a/src/main/java/edu/ferris/seng210/Expenser.java +++ b/src/main/java/edu/ferris/seng210/Expenser.java @@ -1,17 +1,17 @@ package edu.ferris.seng210; public interface Expenser { - public void addExpense (Expense Ex); - public void addMonthlyIncome (Wage W); - public void PrintFullreport(); - public void PrintExpensereport(); - public void PrintIncomereport(); - public void PrintIncomereportbyTpe(); - public void PrintExpensebyType(); - public void exportReport(String reportTitle); - public Currency convertForeignCurrency(Currency C, double amount); - public boolean loadExpenseFile(String filePath); - public boolean loadIncomeFile(String filePath); - public int whenCanIBuy(String itemname,double price); - public void updateMonthlySavings(); + void addExpense (Expense Ex); + void addMonthlyIncome (Wage W); + void PrintFullreport(); + void PrintExpensereport(); + void PrintIncomereport(); + void PrintIncomereportbyTpe(); + void PrintExpensebyType(); + void exportReport(String reportTitle); + Currency convertForeignCurrency(Currency C, double amount); + boolean loadExpenseFile(String filePath); + boolean loadIncomeFile(String filePath); + int whenCanIBuy(String itemname,double price); + void updateMonthlySavings(); } diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java index 102c63d..94ffbaf 100644 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -1,5 +1,11 @@ package edu.ferris.seng210; +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.panels.DetailedReportPanel; +import edu.ferris.seng210.panels.ExpenseReportPanel; +import edu.ferris.seng210.panels.HomePanel; +import edu.ferris.seng210.panels.IncomeReportPanel; + import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -62,7 +68,7 @@ public void exportReport(String reportTitle) { printWriter.append("\n"); printWriter.append("Filtered main.java.seng210.Expense"); printWriter.append(","); - printWriter.append("" + expenseRepPanel.totalFilteredExpenseAmtLbl.getText()); + printWriter.append("" + ExpenseReportPanel.totalFilteredExpenseAmtLbl.getText()); printWriter.append("\n"); printWriter.append("Total Savings"); printWriter.append(","); @@ -70,7 +76,7 @@ public void exportReport(String reportTitle) { printWriter.append("\n"); printWriter.append("Source,Amount,Frequency\n"); - for (Expense exp : expenseRepPanel.filteredSpending) { + for (Expense exp : ExpenseReportPanel.filteredSpending) { printWriter.append("" + exp.getSource() + ","); printWriter.append("" + exp.getAmount() + ","); printWriter.append("" + exp.getFrequency() + "\n"); @@ -86,7 +92,7 @@ public void exportReport(String reportTitle) { printWriter.append("\n"); printWriter.append("Filtered Income"); printWriter.append(","); - printWriter.append("" + incomeRepPanel.totalFilteredIncomeAmtLbl.getText()); + printWriter.append("" + IncomeReportPanel.totalFilteredIncomeAmtLbl.getText()); printWriter.append("\n"); printWriter.append("Total Savings"); printWriter.append(","); @@ -94,7 +100,7 @@ public void exportReport(String reportTitle) { printWriter.append("\n"); printWriter.append("Source,Amount,Frequency\n"); - for (Wage wage : incomeRepPanel.filteredIncomeList) { + for (Wage wage : IncomeReportPanel.filteredIncomeList) { printWriter.append("" + wage.getSource() + ","); printWriter.append("" + wage.getAmount() + ","); printWriter.append("" + wage.getMonth() + "\n"); @@ -186,18 +192,18 @@ else if (lineIndex > 0){ userAtHand.setExpenses(userAtHand.getExpenses() + expense.getAmount()); addExpense(expense); - if(expenseRepPanel.typeSelector.getItemCount() > 0) { + if(ExpenseReportPanel.typeSelector.getItemCount() > 0) { boolean contains = false; - for (int i = 0; i < expenseRepPanel.typeSelector.getItemCount(); i++) { - if (expenseRepPanel.typeSelector.getItemAt(i).equals(expense.getSource())) { + for (int i = 0; i < ExpenseReportPanel.typeSelector.getItemCount(); i++) { + if (ExpenseReportPanel.typeSelector.getItemAt(i).equals(expense.getSource())) { contains = true; } } if (!contains) { - expenseRepPanel.typeSelector.addItem(expense.getSource()); + ExpenseReportPanel.typeSelector.addItem(expense.getSource()); } } else { - expenseRepPanel.typeSelector.addItem(expense.getSource()); + ExpenseReportPanel.typeSelector.addItem(expense.getSource()); } } @@ -257,18 +263,18 @@ public boolean loadIncomeFile(String filePath) { userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); addMonthlyIncome(wage); - if(incomeRepPanel.typeSelector.getItemCount() > 0) { + if(IncomeReportPanel.typeSelector.getItemCount() > 0) { boolean contains = false; - for (int i = 0; i < incomeRepPanel.typeSelector.getItemCount(); i++) { - if (incomeRepPanel.typeSelector.getItemAt(i).equals(wage.getSource())) { + for (int i = 0; i < IncomeReportPanel.typeSelector.getItemCount(); i++) { + if (IncomeReportPanel.typeSelector.getItemAt(i).equals(wage.getSource())) { contains = true; } } if (!contains) { - incomeRepPanel.typeSelector.addItem(wage.getSource()); + IncomeReportPanel.typeSelector.addItem(wage.getSource()); } } else { - incomeRepPanel.typeSelector.addItem(wage.getSource()); + IncomeReportPanel.typeSelector.addItem(wage.getSource()); } } @@ -291,7 +297,7 @@ public void updateMonthlySavings() { userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); } - static ArrayList filterExpensesFreq(ArrayList exp, String freq) { + public static ArrayList filterExpensesFreq(ArrayList exp, String freq) { ArrayList filteredExpensesFreq = new ArrayList<>(); for(Expense ex : exp) { if(String.valueOf(ex.getFrequency()).equals(freq)) { @@ -301,7 +307,7 @@ static ArrayList filterExpensesFreq(ArrayList exp, String freq return filteredExpensesFreq; } - static ArrayList filterExpensesSource(ArrayList exp, String source) { + public static ArrayList filterExpensesSource(ArrayList exp, String source) { ArrayList filteredExpensesSource = new ArrayList<>(); for(Expense ex : exp) { if(ex.getSource().equals(source)) { @@ -311,7 +317,7 @@ static ArrayList filterExpensesSource(ArrayList exp, String so return filteredExpensesSource; } - static ArrayList filterIncomesMonth(ArrayList wage, String month) { + public static ArrayList filterIncomesMonth(ArrayList wage, String month) { ArrayList filteredIncomesMonth = new ArrayList<>(); for(Wage w : wage) { if(w.getMonth().equals(month)) { @@ -321,7 +327,7 @@ static ArrayList filterIncomesMonth(ArrayList wage, String month) { return filteredIncomesMonth; } - static ArrayList filterIncomesSource(ArrayList wage, String source) { + public static ArrayList filterIncomesSource(ArrayList wage, String source) { ArrayList filteredIncomesSource = new ArrayList<>(); for(Wage w : wage) { if(w.getSource().equals(source)) { @@ -333,10 +339,10 @@ static ArrayList filterIncomesSource(ArrayList wage, String source) public void updateIncomeTable() { - incomeRepPanel.model.setNumRows(0); + IncomeReportPanel.model.setNumRows(0); for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { - incomeRepPanel.model.addRow(new Object[]{}); + IncomeReportPanel.model.addRow(new Object[]{}); } userAtHand.setBalance(0.00f); @@ -344,34 +350,34 @@ public void updateIncomeTable() { int i = 0; for(Wage wage : userAtHand.getIncome()) { userAtHand.setBalance(userAtHand.getBalance() + wage.amount); - incomeRepPanel.incomeTable.setValueAt(wage.getSource(), i, 0); - incomeRepPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - incomeRepPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); + IncomeReportPanel.incomeTable.setValueAt(wage.getSource(), i, 0); + IncomeReportPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + IncomeReportPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); ++i; } } public void updateDetailedTable() { - detailedRepPanel.model.setNumRows(0); + DetailedReportPanel.model.setNumRows(0); for(int j = 0; j < userAtHand.getIncome().size() + userAtHand.getSpending().size(); j++ ) { - detailedRepPanel.model.addRow(new Object[]{}); + DetailedReportPanel.model.addRow(new Object[]{}); } int i = 0; for(Wage wage : userAtHand.getIncome()) { - detailedRepPanel.detailedTable.setValueAt("Income", i, 0); - detailedRepPanel.detailedTable.setValueAt(wage.getSource(), i, 1); - detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); - detailedRepPanel.detailedTable.setValueAt(wage.getMonth(), i, 3); + DetailedReportPanel.detailedTable.setValueAt("Income", i, 0); + DetailedReportPanel.detailedTable.setValueAt(wage.getSource(), i, 1); + DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); + DetailedReportPanel.detailedTable.setValueAt(wage.getMonth(), i, 3); ++i; } for(Expense expense : userAtHand.getSpending()) { - detailedRepPanel.detailedTable.setValueAt("main.java.seng210.Expense", i, 0); - detailedRepPanel.detailedTable.setValueAt(expense.getSource(), i, 1); - detailedRepPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); - detailedRepPanel.detailedTable.setValueAt(expense.getFrequency(), i, 3); + DetailedReportPanel.detailedTable.setValueAt("main.java.seng210.Expense", i, 0); + DetailedReportPanel.detailedTable.setValueAt(expense.getSource(), i, 1); + DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); + DetailedReportPanel.detailedTable.setValueAt(expense.getFrequency(), i, 3); ++i; } @@ -379,19 +385,19 @@ public void updateDetailedTable() { public void updateExpenseTable() { - expenseRepPanel.model.setNumRows(0); + ExpenseReportPanel.model.setNumRows(0); for(int j = 0; j < userAtHand.getSpending().size(); j++ ) { - expenseRepPanel.model.addRow(new Object[]{}); + ExpenseReportPanel.model.addRow(new Object[]{}); } userAtHand.setExpenses(0.00f); int i = 0; for(Expense expense : userAtHand.getSpending()) { userAtHand.setExpenses(userAtHand.getExpenses() + expense.amount); - expenseRepPanel.spendingTable.setValueAt(expense.getSource(), i, 0); - expenseRepPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); - expenseRepPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); + ExpenseReportPanel.spendingTable.setValueAt(expense.getSource(), i, 0); + ExpenseReportPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); + ExpenseReportPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); ++i; } } @@ -400,18 +406,18 @@ public void updateIncomeValues() { userAtHand.setExpenses(getExpense(userAtHand.getSpending())); userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); updateMonthlySavings(); - incomeRepPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); - homePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",userAtHand.getBalance())); - homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); + IncomeReportPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); + HomePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",userAtHand.getBalance())); + HomePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); } public void updateExpenseValues() { userAtHand.setExpenses(getExpense(userAtHand.getSpending())); userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); updateMonthlySavings(); - expenseRepPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); - homePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",getExpense(userAtHand.getSpending()))); - homePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.monthlysavings)); + ExpenseReportPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); + HomePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",getExpense(userAtHand.getSpending()))); + HomePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); } public double getTotalIncome(ArrayList wage) { diff --git a/src/main/java/edu/ferris/seng210/PasswordCheckerService.java b/src/main/java/edu/ferris/seng210/PasswordCheckerService.java new file mode 100644 index 0000000..bb2af47 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/PasswordCheckerService.java @@ -0,0 +1,37 @@ +package edu.ferris.seng210; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.Scanner; + +public class PasswordCheckerService { + + public boolean check(String username,String password) { + boolean flag = false; + String lineTxt; + + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + while(scnr.hasNextLine()) { + lineTxt = scnr.nextLine(); + if(lineTxt.indexOf(username) != -1) { + if((lineTxt.indexOf(username) + username.length() + 1) == lineTxt.indexOf(password)) { + for(int i = 0; i < EWalletApp.users.size(); i++) { + if(EWalletApp.users.get(i).getUsername().equals(username)) { + EWalletApp.activeUser = EWalletApp.users.get(i); + } + } + flag = true; + break; + } + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return flag; + } + +} diff --git a/src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java b/src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java new file mode 100644 index 0000000..edec58a --- /dev/null +++ b/src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java @@ -0,0 +1,10 @@ +package edu.ferris.seng210; + +public class PasswordComplexityChecker { + + public boolean check(String password) { + String passwordRegEx = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=\\S+$).{8,20}$"; + + return password.matches(passwordRegEx); + } +} diff --git a/src/main/java/edu/ferris/seng210/UserCreationService.java b/src/main/java/edu/ferris/seng210/UserCreationService.java new file mode 100644 index 0000000..70ce8b9 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/UserCreationService.java @@ -0,0 +1,35 @@ +package edu.ferris.seng210; + +import edu.ferris.seng210.account.User; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintWriter; + +public class UserCreationService { + + public void create(String username, String password) { + + UsernameChecker checker = new UsernameChecker(); + PasswordComplexityChecker passwordComplexityChecker = new PasswordComplexityChecker(); + + if (!checker.hasRepeat(username) && passwordComplexityChecker.check(password)) { + User user = new User(username, password); + EWalletApp.users.add(user); + + try { + FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); + PrintWriter printWriter = new PrintWriter(fileOutputStream); + printWriter.append(username); + printWriter.append(","); + printWriter.append(password); + printWriter.append(",\n"); + printWriter.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/src/main/java/edu/ferris/seng210/UsernameChecker.java b/src/main/java/edu/ferris/seng210/UsernameChecker.java new file mode 100644 index 0000000..daaac83 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/UsernameChecker.java @@ -0,0 +1,73 @@ +package edu.ferris.seng210; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Scanner; + +public class UsernameChecker { + + public boolean check(String username) { + boolean flag = false; + String savedUser; + + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + while(scnr.hasNextLine()) { + savedUser = scnr.nextLine(); + if(savedUser.indexOf(username) != -1) { + flag = true; + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return flag; + } + + public boolean hasRepeat(String username) { + try { + FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + Scanner scnr = new Scanner(fileInputStream); + + Path path = Paths.get("src/UserCredentials.csv"); + long lines = Files.lines(path).count(); + String textAtLine; + String readUsername; + if(lines < 1) { + System.out.println("There is no data in file."); + } else { + for (int i = 0; i < lines; i++) { + textAtLine = scnr.nextLine(); + readUsername = ""; + for (int j = 0; j < textAtLine.length(); j++) { + if (textAtLine.charAt(j) != ',') { + readUsername += textAtLine.charAt(j); + } else { + break; + } + } + if (username.equals(readUsername)) { + + System.out.println("Username already exists."); + return true; + + } + } + } + + } catch (FileNotFoundException e) { + + System.out.println("The file UserCredentials.csv was not found."); + + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } +} diff --git a/src/main/java/edu/ferris/seng210/Wage.java b/src/main/java/edu/ferris/seng210/Wage.java index 69f20b5..839dfba 100644 --- a/src/main/java/edu/ferris/seng210/Wage.java +++ b/src/main/java/edu/ferris/seng210/Wage.java @@ -5,7 +5,7 @@ public class Wage { double amount; String Month; - Wage(String source, double amount, String Month) { + public Wage(String source, double amount, String Month) { this.source = source; this.amount = amount; this.Month = Month; diff --git a/src/main/java/edu/ferris/seng210/User.java b/src/main/java/edu/ferris/seng210/account/User.java similarity index 51% rename from src/main/java/edu/ferris/seng210/User.java rename to src/main/java/edu/ferris/seng210/account/User.java index 38c1e22..fd92726 100644 --- a/src/main/java/edu/ferris/seng210/User.java +++ b/src/main/java/edu/ferris/seng210/account/User.java @@ -1,4 +1,8 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.account; + +import edu.ferris.seng210.Currency; +import edu.ferris.seng210.Expense; +import edu.ferris.seng210.Wage; import java.util.ArrayList; @@ -12,64 +16,64 @@ public class User { double monthlysavings; double expenses; - User(String username, String password){ + public User(String username, String password){ this.username = username; this.pwd = password; } - protected String getUsername() { + public String getUsername() { return this.username; } - protected String getPwd() { + public String getPwd() { return this.pwd; } - protected void setUsername(String username) { + public void setUsername(String username) { this.username = username; } - protected void setPwd(String password) { + public void setPwd(String password) { this.pwd = password; } - protected void addExpense(Expense Ex) { + public void addExpense(Expense Ex) { Spending.add(Ex); } - protected void addMonthlyIncome(Wage W) { + public void addMonthlyIncome(Wage W) { Income.add(W); } - protected ArrayList getIncome() { + public ArrayList getIncome() { return this.Income; } - protected ArrayList getSpending() { + public ArrayList getSpending() { return this.Spending; } - protected void setBalance(double balance) { + public void setBalance(double balance) { this.balance = balance; } - protected double getBalance(){ + public double getBalance(){ return this.balance; } - protected void setExpenses(double expenses) { + public void setExpenses(double expenses) { this.expenses = expenses; } - protected double getExpenses() { + public double getExpenses() { return this.expenses; } - protected double getMonthlySavings() { + public double getMonthlySavings() { return this.monthlysavings; } - protected void setMonthlySavings(double monthlySavings) { + public void setMonthlySavings(double monthlySavings) { this.monthlysavings = monthlySavings; } } diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java new file mode 100644 index 0000000..5bfe1b6 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -0,0 +1,273 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.Expense; +import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.Wage; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class AddItemPanel extends JPanel{ + + ExpenserMain expenserMain; + int yearlyFrequency; + double amount; + String month, source; + GridBagConstraints gbConst; + JPanel incomePane, expensePane; + JLabel addIncomeItemLbl, addExpenseItemLbl; + JLabel nameIncomeLbl, amountIncomeLbl, monthIncomeLbl; + JLabel nameExpenseLbl, amountExpenseLbl, frequencyExpLbl; + JTextField nameIncField, amountIncField, frequencyExpField; + JTextField nameExpField, amountExpField; + JButton addIncomeButton, addExpenseButton; + JComboBox monthComboBox; + String[] months; + public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel) { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + + months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + incomePane = new JPanel(); + expensePane = new JPanel(); + + monthComboBox = new JComboBox<>(months); + monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); + monthComboBox.setSelectedIndex(0); + + addIncomeButton = new JButton("Add"); + addExpenseButton = new JButton("Add"); + + gbConst = new GridBagConstraints(); + incomePane.setLayout(new GridBagLayout()); + expensePane.setLayout(new GridBagLayout()); + + addIncomeItemLbl = new JLabel("Add Item"); + nameIncomeLbl = new JLabel("Name"); + amountIncomeLbl = new JLabel("Amount"); + monthIncomeLbl = new JLabel("Month"); + + addExpenseItemLbl = new JLabel("Add Item"); + nameExpenseLbl = new JLabel("Name"); + amountExpenseLbl = new JLabel("Amount"); + frequencyExpLbl = new JLabel("Freq."); + + nameIncField = new JTextField(); + nameIncField.setPreferredSize(new Dimension(280, 50)); + amountIncField = new JTextField(); + amountIncField.setPreferredSize(new Dimension(280, 50)); + frequencyExpField = new JTextField(); + frequencyExpField.setPreferredSize(new Dimension(280, 50)); + + nameExpField = new JTextField(); + nameExpField.setPreferredSize(new Dimension(280, 50)); + amountExpField = new JTextField(); + amountExpField.setPreferredSize(new Dimension(280, 50)); + monthComboBox.setPreferredSize(new Dimension(280, 50)); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(0,20,60,30); + addIncomeItemLbl.setFont(new Font(null, Font.PLAIN, 44)); + incomePane.add(addIncomeItemLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + nameIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(nameIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,10,30,30); + nameIncField.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(nameIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + amountIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(amountIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + amountIncField.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(amountIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + monthIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + incomePane.add(monthIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + monthComboBox.setFont(new Font(null, Font.PLAIN, 28)); + incomePane.add(monthComboBox, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + addIncomeButton.setFont(new Font(null, Font.PLAIN, 28)); + addIncomeButton.setPreferredSize(new Dimension(150,60)); + incomePane.add(addIncomeButton, gbConst); + + addIncomeButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == addIncomeButton) { + if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0) { + try { + amount = Double.parseDouble(amountIncField.getText()); + } catch (NumberFormatException n) { + System.out.println(n.getMessage()); + amount = 0.00f; + } + source = nameIncField.getText(); + month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); + Wage w = new Wage(source, amount, month); + expenserMain.userAtHand.addMonthlyIncome(w); + + if(incomeReportPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < incomeReportPanel.typeSelector.getItemCount(); i++) { + if (incomeReportPanel.typeSelector.getItemAt(i).equals(w.getSource())) { + contains = true; + } + } + if (!contains) { + incomeReportPanel.typeSelector.addItem(w.getSource()); + } + } else { + incomeReportPanel.typeSelector.addItem(w.getSource()); + } + + expenserMain.updateIncomeTable(); + expenserMain.updateIncomeValues(); + expenserMain.updateDetailedTable(); + + nameIncField.setText(""); + monthComboBox.setSelectedItem(0); + amountIncField.setText(""); + + } + + } + } + }); + + this.add("Add Income", incomePane); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.insets = new Insets(0,20,60,30); + addExpenseItemLbl.setFont(new Font(null, Font.PLAIN, 44)); + expensePane.add(addExpenseItemLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + nameExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(nameExpenseLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,10,30,30); + nameExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(nameExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + amountExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(amountExpenseLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + amountExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(amountExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,20,30,30); + frequencyExpLbl.setFont(new Font(null, Font.PLAIN, 32)); + expensePane.add(frequencyExpLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + frequencyExpField.setFont(new Font(null, Font.PLAIN, 28)); + expensePane.add(frequencyExpField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + addExpenseButton.setFont(new Font(null, Font.PLAIN, 28)); + addExpenseButton.setPreferredSize(new Dimension(150,60)); + expensePane.add(addExpenseButton, gbConst); + + addExpenseButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == addExpenseButton) { + if(nameExpField.getText().length() > 0 && amountExpField.getText().length() > 0 & frequencyExpField.getText().length() > 0) { + try { + amount = Double.parseDouble(amountExpField.getText()); + yearlyFrequency = Integer.parseInt(frequencyExpField.getText()); + + } catch (NumberFormatException n) { + System.out.println(n.getMessage()); + amount = 0.00f; + } + source = nameExpField.getText(); + Expense Ex = new Expense(source, amount, yearlyFrequency); + expenserMain.addExpense(Ex); + expenserMain.updateExpenseValues(); + + if(expenseReportPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < expenseReportPanel.typeSelector.getItemCount(); i++) { + if (expenseReportPanel.typeSelector.getItemAt(i).equals(Ex.getSource())) { + contains = true; + } + } + if (!contains) { + expenseReportPanel.typeSelector.addItem(Ex.getSource()); + } + } else { + expenseReportPanel.typeSelector.addItem(Ex.getSource()); + } + + + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + + nameExpField.setText(""); + frequencyExpField.setText(""); + amountExpField.setText(""); + } + } + } + }); + + this.add("Add expense", expensePane); + this.setFont(new Font(null, Font.PLAIN, 24)); + } + +} diff --git a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java new file mode 100644 index 0000000..2362887 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java @@ -0,0 +1,116 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.UserCreationService; +import edu.ferris.seng210.UsernameChecker; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class CreateAccountPanel extends JPanel { + + JLabel usernameLbl, passwordLbl, confPasswordLbl, createAccLbl; + GridBagConstraints gbConst; + static JTextField usernameField, passwordField, confPasswordField; + JButton createAccBtn; + String username, password, confPassword; + + public CreateAccountPanel() { + usernameLbl = new JLabel("Enter Username:"); + passwordLbl = new JLabel("Enter Password:"); + confPasswordLbl = new JLabel("Confirm Password:"); + createAccLbl = new JLabel("Create Account"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + usernameField = new JTextField(); + usernameField.setPreferredSize(new Dimension(200, 40)); + passwordField = new JTextField(); + passwordField.setPreferredSize(new Dimension(200, 40)); + confPasswordField = new JTextField(); + confPasswordField.setPreferredSize(new Dimension(200, 40)); + + createAccBtn = new JButton("Create Account"); + createAccBtn.setPreferredSize(new Dimension(200, 40)); + + gbConst.gridx = 1; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(0, 20, 40, 20); + createAccLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(createAccLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0, 40, 40, 0); + usernameLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(usernameLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 1; + gbConst.insets = new Insets(20, 0, 40, 40); + usernameField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(usernameField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0, 40, 40, 0); + passwordLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(passwordLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 2; + gbConst.insets = new Insets(20, 0, 40, 40); + passwordField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(passwordField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(0, 40, 40, 0); + confPasswordLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(confPasswordLbl, gbConst); + + gbConst.gridx = -1; + gbConst.gridy = 3; + gbConst.insets = new Insets(20, 0, 40, 40); + confPasswordField.setFont(new Font(null, Font.PLAIN, 32)); + this.add(confPasswordField, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 4; + gbConst.insets = new Insets(20, 20, 20, 20); + createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); + this.add(createAccBtn, gbConst); + + createAccBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (e.getSource() == createAccBtn) { + username = usernameField.getText(); + password = passwordField.getText(); + confPassword = confPasswordField.getText(); + if (!usernameField.getText().isEmpty() && !passwordField.getText().isEmpty() && !confPasswordField.getText().isEmpty()) { + if (confPassword.equals(password)) { + UsernameChecker usernameChecker = new UsernameChecker(); + if (usernameChecker.hasRepeat(usernameField.getText())) { + JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); + } else { + UserCreationService userCreationService = new UserCreationService(); + + userCreationService.create(username, password); + JOptionPane.showMessageDialog(null, "main.java.seng210.User created successfully."); + usernameField.setText(""); + passwordField.setText(""); + confPasswordField.setText(""); + } + } else { + JOptionPane.showMessageDialog(null, "Passwords do not match!"); + } + } else { + JOptionPane.showMessageDialog(null, "Not all fields filled out. Please fill them out."); + } + } + } + }); + } +} diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java new file mode 100644 index 0000000..30ba13a --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -0,0 +1,86 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.Expense; +import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.Wage; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +public class DetailedReportPanel extends JPanel { + + public static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + public static JScrollPane jScrollPane; + ArrayList Spending; + ArrayList Income; + Object[][] tableVals; + String[] columnHeadings; + public static JTable detailedTable; + JLabel detaileReportTxt; + JButton exportReport; + ExpenserMain expenserMain; + public DetailedReportPanel(User user) { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + + this.setLayout(new BorderLayout()); + detaileReportTxt = new JLabel("Detailed Report"); + detaileReportTxt.setFont(new Font(null, Font.PLAIN, 40)); + detaileReportTxt.setHorizontalAlignment(JLabel.CENTER); + this.add(detaileReportTxt, BorderLayout.PAGE_START); + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; + Spending = expenserMain.userAtHand.getSpending(); + Income = expenserMain.userAtHand.getIncome(); + tableVals = new Object[Spending.size()+Income.size()][4]; + model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model + detailedTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { // restricting cell editing + return false; + } + }; + jScrollPane = new JScrollPane(detailedTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < detailedTable.getColumnCount(); i++) { + detailedTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + detailedTable.setDefaultRenderer(String.class, centerRenderer); + + detailedTable.setFont(new Font(null, Font.PLAIN, 24)); + detailedTable.setRowHeight(45); + detailedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + detailedTable.getTableHeader().setReorderingAllowed(false); + detailedTable.setFocusable(true); + detailedTable.setRowSelectionAllowed(true); + detailedTable.setCellSelectionEnabled(true); + detailedTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + detailedTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + expenserMain.exportReport("Detailed Report"); + } + }); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + } +} diff --git a/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java b/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java new file mode 100644 index 0000000..3814234 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java @@ -0,0 +1,91 @@ +package edu.ferris.seng210.panels; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class EstimatePanel extends JPanel { + + GridBagConstraints gbConst; + JLabel estimateTitleLbl, nameLbl, priceLbl, estimateLbl, estimateAmtLbl; + JTextField nameField, priceField; + JButton estimateButton; + public EstimatePanel() { + this.setLayout(new GridBagLayout()); + gbConst = new GridBagConstraints(); + + estimateTitleLbl = new JLabel("Estimate Tool"); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,20,30,30); + estimateTitleLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(estimateTitleLbl, gbConst); + + estimateLbl = new JLabel("Estimate:"); + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(10,0,30,0); + estimateLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(estimateLbl, gbConst); + + estimateAmtLbl = new JLabel("0 days"); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(10,0,30,0); + estimateAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(estimateAmtLbl, gbConst); + + nameLbl = new JLabel("Item Name"); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,20,30,30); + nameLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(nameLbl, gbConst); + + nameField = new JTextField(); + nameField.setPreferredSize(new Dimension(280, 50)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(10,10,30,30); + nameField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(nameField, gbConst); + + priceLbl = new JLabel("Item Price"); + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,20,30,30); + priceLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(priceLbl, gbConst); + + priceField = new JTextField(); + priceField.setPreferredSize(new Dimension(280, 50)); + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(10,10,30,30); + priceField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(priceField, gbConst); + + estimateButton = new JButton("Get Estimate"); + estimateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == estimateButton) { + System.out.println("Get Estimate Button Clicked."); + nameField.setText(""); + priceField.setText(""); + } + } + }); + estimateButton.setPreferredSize(new Dimension(220, 60)); + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(30,30,30,30); + estimateButton.setFont(new Font(null, Font.PLAIN, 28)); + this.add(estimateButton, gbConst); + + } +} diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java new file mode 100644 index 0000000..76fc7fc --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -0,0 +1,188 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.Expense; +import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.account.User; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +public class ExpenseReportPanel extends JPanel { + + public static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + public static JScrollPane jScrollPane; + public static ArrayList Spending; + public static ArrayList filteredSpending = new ArrayList<>(); + Object[][] tableVals; + String[] columnHeadings; + public static JTable spendingTable; + JLabel expenseText; + JLabel totalExpenseLbl, totalFilteredExpenseLbl, filterTxt ; + public static JLabel totalExpenseAmtLbl, totalFilteredExpenseAmtLbl; + JButton exportReport, applyFilter; + ExpenserMain expenserMain; + GridBagConstraints gbConst; + JPanel upperPanel; + JComboBox monthSelector; + public static JComboBox typeSelector; + String[] frequency; + + public ExpenseReportPanel(User user) { + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + Spending = expenserMain.userAtHand.getSpending(); + + this.setLayout(new BorderLayout()); + + + expenseText = new JLabel("Expense Report"); + expenseText.setFont(new Font(null, Font.PLAIN, 40)); + expenseText.setHorizontalAlignment(JLabel.CENTER); + + gbConst = new GridBagConstraints(); + upperPanel = new JPanel(); + upperPanel.setLayout(new GridBagLayout()); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 4; + gbConst.insets = new Insets(20,0,20,0); + upperPanel.add(expenseText, gbConst); + + totalExpenseLbl = new JLabel("Expense"); + totalExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridwidth = 1; + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(totalExpenseLbl,gbConst); + + totalExpenseAmtLbl = new JLabel("0.00"); + totalExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalExpenseAmtLbl,gbConst); + + totalFilteredExpenseLbl = new JLabel("Expenses (Filtered)"); + totalFilteredExpenseLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 2; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalFilteredExpenseLbl,gbConst); + + totalFilteredExpenseAmtLbl = new JLabel("0.00"); + totalFilteredExpenseAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 3; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,20); + upperPanel.add(totalFilteredExpenseAmtLbl,gbConst); + + filterTxt = new JLabel("Apply a filter"); + filterTxt.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(filterTxt,gbConst); + + frequency = new String[]{"1", "12","24"}; + monthSelector = new JComboBox<>(frequency); + monthSelector.setFont(new Font(null, Font.PLAIN, 24)); + monthSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(monthSelector,gbConst); + + typeSelector = new JComboBox<>(expenserMain.getExpenseSources(Spending).toArray()); + typeSelector.setFont(new Font(null, Font.PLAIN, 24)); + typeSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 2; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(typeSelector,gbConst); + + applyFilter = new JButton("Filter"); + applyFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == applyFilter) { + filteredSpending = expenserMain.filterExpensesFreq + (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) + ,(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + model.setNumRows(filteredSpending.size()); + int i = 0; + double expenseSum = 0.00f; + for(Expense exp : filteredSpending) { + spendingTable.setValueAt(exp.getSource(), i, 0); + spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); + spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); + ++i; + expenseSum += exp.getAmount(); + } + totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); + } + } + }); + applyFilter.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 3; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(applyFilter,gbConst); + + this.add(upperPanel, BorderLayout.PAGE_START); + + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Source","Amount", "Frequency"}; + tableVals = new Object[Spending.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); + spendingTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { // restricting cell editing + return false; + } + }; + jScrollPane = new JScrollPane(spendingTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < spendingTable.getColumnCount(); i++) { + spendingTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + spendingTable.setDefaultRenderer(String.class, centerRenderer); + + spendingTable.setFont(new Font(null, Font.PLAIN, 24)); + spendingTable.setRowHeight(45); + spendingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + spendingTable.getTableHeader().setReorderingAllowed(false); + spendingTable.setFocusable(true); + spendingTable.setRowSelectionAllowed(true); + spendingTable.setCellSelectionEnabled(true); + spendingTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + spendingTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == exportReport) { + expenserMain.exportReport("main.java.seng210.Expense Report"); + } + } + }); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + + } +} diff --git a/src/main/java/edu/ferris/seng210/panels/HomePanel.java b/src/main/java/edu/ferris/seng210/panels/HomePanel.java new file mode 100644 index 0000000..c5908ff --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/HomePanel.java @@ -0,0 +1,68 @@ +package edu.ferris.seng210.panels; + +import javax.swing.*; +import java.awt.*; + +public class HomePanel extends JPanel { + + JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; + public static JLabel totalExpensesAmtLbl, totalSavingsAmtLbl, totalIncomeAmtLbl; + GridBagConstraints gbConst; + public HomePanel() { + + summaryTxt = new JLabel("User Summary"); + totalIncomeLbl = new JLabel("Total Income: "); + totalIncomeAmtLbl = new JLabel("$0.00"); + totalExpensesLbl = new JLabel("Total Expenses: "); + totalExpensesAmtLbl = new JLabel("$0.00"); + totalSavingsLbl = new JLabel("Total Savings: "); + totalSavingsAmtLbl = new JLabel("$0.00"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,20,60,20); + summaryTxt.setFont(new Font(null, Font.PLAIN, 44)); + this.add(summaryTxt, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(20,40,20,5); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalIncomeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(20,10,20,40); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalIncomeAmtLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,40,20,5); + totalExpensesLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalExpensesLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(20,10,20,40); + totalExpensesAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalExpensesAmtLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,40,40,5); + totalSavingsLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalSavingsLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 3; + gbConst.insets = new Insets(20,10,40,40); + totalSavingsAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + this.add(totalSavingsAmtLbl, gbConst); + } + +} diff --git a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java new file mode 100644 index 0000000..c1ddbde --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java @@ -0,0 +1,136 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.account.User; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +public class ImportPanel extends JPanel { + + ExpenserMain expenserMain; + GridBagConstraints gbConst; + JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; + JButton selectFileButton, importButton; + JFileChooser fileChooser; + String[] typesOfImports; + JComboBox options; + File userFile; + public ImportPanel(User user) { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + + fileChooser = new JFileChooser(); + + this.setLayout(new GridBagLayout()); + gbConst = new GridBagConstraints(); + typesOfImports = new String[] {"Income","main.java.seng210.Expense"}; + options = new JComboBox<>(typesOfImports); + options.setSelectedIndex(0); + + importLbl = new JLabel("Import From File"); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(10,30,20,30); + importLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(importLbl, gbConst); + + selectFileButton = new JButton("File"); + selectFileButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() == selectFileButton) { + int userDecision = fileChooser.showOpenDialog(null); + if(userDecision == JFileChooser.APPROVE_OPTION) { + userFile = fileChooser.getSelectedFile(); + if(!userFile.getAbsolutePath().endsWith(".csv")){ + JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); + System.out.println("main.java.seng210.User selected a non csv file!"); + } + System.out.println("The user selected: " + userFile.getAbsolutePath()); + } else if (userDecision == JFileChooser.CANCEL_OPTION) { + System.out.println("The user canceled the operation."); + } + } + } + }); + + selectFileLbl = new JLabel("Select File"); + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(30,30,20,0); + selectFileLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectFileLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(30,0,20,30); + selectFileButton.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectFileButton, gbConst); + + selectTypeLbl = new JLabel("Select Type"); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(30,30,20,0); + selectTypeLbl.setFont(new Font(null, Font.PLAIN, 24)); + this.add(selectTypeLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(30,0,20,30); + options.setFont(new Font(null, Font.PLAIN, 24)); + this.add(options, gbConst); + + descriptionLbl = new JLabel("Note: Only csv files are supported.

The format of the csv file matters.
The first line of the file needs to contain \"source,amount,month\" or
\"source,amount,frequency\", depending on the type

Once you select a file, click the import button."); + gbConst.gridwidth = 2; + gbConst.gridheight = 2; + gbConst.gridx = 0; + gbConst.gridy = 3; + gbConst.insets = new Insets(30,30,30,30); + descriptionLbl.setFont(new Font(null, Font.PLAIN, 20)); + this.add(descriptionLbl, gbConst); + + importButton = new JButton("Import"); + importButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { + System.out.println("Income Selected"); + if(userFile == null) { + JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); + } else { + expenserMain.loadIncomeFile(userFile.getAbsolutePath()); + expenserMain.updateIncomeTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateIncomeValues(); + } + } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { + System.out.println("main.java.seng210.Expense Selected"); + if(userFile == null) { + JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); + } else { + expenserMain.loadExpenseFile(userFile.getAbsolutePath()); + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateExpenseValues(); + } + } + + } + }); + gbConst.gridheight = 1; + gbConst.gridx = 0; + gbConst.gridy = 5; + gbConst.insets = new Insets(30,0,30,30); + importButton.setFont(new Font(null, Font.PLAIN, 24)); + this.add(importButton, gbConst); + + } + +} diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java new file mode 100644 index 0000000..ca3ddeb --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -0,0 +1,185 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.Wage; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +public class IncomeReportPanel extends JPanel { + + public static DefaultTableModel model; + DefaultTableCellRenderer centerRenderer; + public static JScrollPane jScrollPane; + public static ArrayList Income; + public static ArrayList filteredIncomeList = new ArrayList<>(); + Object[][] tableVals; // table values + String[] columnHeadings; + public static JTable incomeTable; + JLabel incomeText, filterTxt; + JLabel totalIncomeLbl, totalFilteredIncomeLbl; + public static JLabel totalIncomeAmtLbl, totalFilteredIncomeAmtLbl; + JButton exportReport, applyFilter; + ExpenserMain expenserMain; + GridBagConstraints gbConst; + JPanel upperPanel; + JComboBox monthSelector; + public static JComboBox typeSelector; + String[] months; + public IncomeReportPanel(User user) { + + expenserMain = new ExpenserMain(); + expenserMain.userAtHand = user; + Income = expenserMain.userAtHand.getIncome(); + + this.setLayout(new BorderLayout()); + + incomeText = new JLabel("Income Report"); + incomeText.setFont(new Font(null, Font.PLAIN, 40)); + incomeText.setHorizontalAlignment(JLabel.CENTER); + + gbConst = new GridBagConstraints(); + upperPanel = new JPanel(); + upperPanel.setLayout(new GridBagLayout()); + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 4; + gbConst.insets = new Insets(20,0,20,0); + upperPanel.add(incomeText, gbConst); + + totalIncomeLbl = new JLabel("Total Income"); + totalIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridwidth = 1; + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(totalIncomeLbl,gbConst); + + totalIncomeAmtLbl = new JLabel("0.00"); + totalIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalIncomeAmtLbl,gbConst); + + totalFilteredIncomeLbl = new JLabel("Income (Filtered)"); + totalFilteredIncomeLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 2; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,5); + upperPanel.add(totalFilteredIncomeLbl,gbConst); + + totalFilteredIncomeAmtLbl = new JLabel("0.00"); + totalFilteredIncomeAmtLbl.setFont(new Font(null, Font.PLAIN, 32)); + gbConst.gridx = 3; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,20); + upperPanel.add(totalFilteredIncomeAmtLbl,gbConst); + + filterTxt = new JLabel("Apply a filter"); + filterTxt.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,0); + upperPanel.add(filterTxt,gbConst); + + months = new String[]{"","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + monthSelector = new JComboBox<>(months); + monthSelector.setPreferredSize(new Dimension(200,50)); + monthSelector.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(monthSelector,gbConst); + + typeSelector = new JComboBox<>(expenserMain.getIncomeSources(Income).toArray()); + typeSelector.setFont(new Font(null, Font.PLAIN, 24)); + typeSelector.setPreferredSize(new Dimension(200,50)); + gbConst.gridx = 2; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(typeSelector,gbConst); + + applyFilter = new JButton("Filter"); + applyFilter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == applyFilter) { + filteredIncomeList = + expenserMain.filterIncomesMonth(expenserMain.filterIncomesSource(expenserMain.userAtHand.getIncome(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + model.setNumRows(filteredIncomeList.size()); + int i = 0; + double incomeSum = 0.00f; + for(Wage wage : filteredIncomeList) { + incomeTable.setValueAt(wage.getSource(), i, 0); + incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + incomeTable.setValueAt(wage.getMonth(), i, 2); + ++i; + incomeSum += wage.getAmount(); + } + totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); + } + } + }); + applyFilter.setFont(new Font(null, Font.PLAIN, 24)); + gbConst.gridx = 3; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,20,20,20); + upperPanel.add(applyFilter,gbConst); + + this.add(upperPanel, BorderLayout.PAGE_START); + + centerRenderer = new DefaultTableCellRenderer(); + columnHeadings = new String[]{"Source","Amount", "Month"}; + tableVals = new Object[Income.size()][3]; + model = new DefaultTableModel(tableVals, columnHeadings); + incomeTable = new JTable(model) { + public boolean isCellEditable(int row, int column) { // restricting cell editing + return false; + } + }; + jScrollPane = new JScrollPane(incomeTable); + + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + for (int i = 0; i < incomeTable.getColumnCount(); i++) { + incomeTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + incomeTable.setDefaultRenderer(String.class, centerRenderer); + + incomeTable.setFont(new Font(null, Font.PLAIN, 24)); + incomeTable.setRowHeight(45); + incomeTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + incomeTable.getTableHeader().setReorderingAllowed(false); + incomeTable.setFocusable(true); + incomeTable.setRowSelectionAllowed(true); + incomeTable.setCellSelectionEnabled(true); + incomeTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); + incomeTable.setShowVerticalLines(false); + + this.add(jScrollPane, BorderLayout.CENTER); + + exportReport = new JButton("Export to CSV"); + exportReport.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { // exports report to csv + expenserMain.exportReport("Income Report"); + } + }); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + + } + +} diff --git a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java new file mode 100644 index 0000000..70ca1b5 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java @@ -0,0 +1,93 @@ +package edu.ferris.seng210.panels; + +import edu.ferris.seng210.PasswordCheckerService; +import edu.ferris.seng210.UsernameChecker; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class LoginPanel extends JPanel { + + JLabel usernameLbl, passwordLbl, loginLbl; + GridBagConstraints gbConst; + JTextField usernameIncField, passwordIncField; + JButton loginBtn; + String username, password; + + public LoginPanel() { + loginLbl = new JLabel("LOGIN"); + usernameLbl = new JLabel("Username: "); + passwordLbl = new JLabel("Password: "); + loginBtn = new JButton("Login"); + gbConst = new GridBagConstraints(); + this.setLayout(new GridBagLayout()); + + passwordIncField = new JTextField(); + passwordIncField.setPreferredSize(new Dimension(200, 40)); + usernameIncField = new JTextField(); + usernameIncField.setPreferredSize(new Dimension(200, 40)); + + gbConst.gridx = 0; + gbConst.gridy = 0; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,10,20,40); + loginLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(loginLbl, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 2; + gbConst.gridwidth = 1; + gbConst.insets = new Insets(0,5,20,30); + passwordIncField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(passwordIncField, gbConst); + + gbConst.gridx = 1; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,5,20,30); + usernameIncField.setFont(new Font(null, Font.PLAIN, 28)); + this.add(usernameIncField, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 2; + gbConst.insets = new Insets(0,0,20,20); + passwordLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(passwordLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 1; + gbConst.insets = new Insets(0,0,20,20); + usernameLbl.setFont(new Font(null, Font.PLAIN, 44)); + this.add(usernameLbl, gbConst); + + gbConst.gridx = 0; + gbConst.gridy = 4; + gbConst.gridwidth = 2; + gbConst.insets = new Insets(20,30,30,30); + loginBtn.setFont(new Font(null, Font.PLAIN, 28)); + loginBtn.setPreferredSize(new Dimension(150,60)); + this.add(loginBtn, gbConst); + + loginBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + username = usernameIncField.getText(); + password = passwordIncField.getText(); + + UsernameChecker usernameChecker = new UsernameChecker(); + PasswordCheckerService passwordCheckerService = new PasswordCheckerService(); + + if(usernameChecker.check(username) && passwordCheckerService.check(username, password)) { + usernameIncField.setText(""); + passwordIncField.setText(""); + System.out.println("Login Successful"); + JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); + } else { + JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); + } + } + }); + + + } +} From d4c9398505b3168c5b9cb033ff639ef5e45e5f58 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:21:46 -0400 Subject: [PATCH 052/123] Switching from JPanel to JTabbedPane (original) --- src/main/java/edu/ferris/seng210/panels/AddItemPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 5bfe1b6..005ad5b 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -1,6 +1,6 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.Expense; +import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; import edu.ferris.seng210.Wage; @@ -10,7 +10,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -public class AddItemPanel extends JPanel{ +public class AddItemPanel extends JTabbedPane{ ExpenserMain expenserMain; int yearlyFrequency; From 547e48dcd38b10a4fc7ac19f1950430058ecba6d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:23:33 -0400 Subject: [PATCH 053/123] Relocating to different packages --- src/main/java/edu/ferris/seng210/Expenser.java | 2 ++ src/main/java/edu/ferris/seng210/UserCreationService.java | 2 ++ src/main/java/edu/ferris/seng210/account/User.java | 2 +- .../PasswordChecker.java} | 6 ++++-- .../seng210/{ => checker}/PasswordComplexityChecker.java | 2 +- .../edu/ferris/seng210/{ => checker}/UsernameChecker.java | 2 +- src/main/java/edu/ferris/seng210/{ => expense}/Expense.java | 2 +- .../java/edu/ferris/seng210/panels/CreateAccountPanel.java | 2 +- .../java/edu/ferris/seng210/panels/DetailedReportPanel.java | 2 +- .../java/edu/ferris/seng210/panels/ExpenseReportPanel.java | 2 +- 10 files changed, 15 insertions(+), 9 deletions(-) rename src/main/java/edu/ferris/seng210/{PasswordCheckerService.java => checker/PasswordChecker.java} (91%) rename src/main/java/edu/ferris/seng210/{ => checker}/PasswordComplexityChecker.java (87%) rename src/main/java/edu/ferris/seng210/{ => checker}/UsernameChecker.java (98%) rename src/main/java/edu/ferris/seng210/{ => expense}/Expense.java (93%) diff --git a/src/main/java/edu/ferris/seng210/Expenser.java b/src/main/java/edu/ferris/seng210/Expenser.java index ac43eeb..09ad18f 100644 --- a/src/main/java/edu/ferris/seng210/Expenser.java +++ b/src/main/java/edu/ferris/seng210/Expenser.java @@ -1,5 +1,7 @@ package edu.ferris.seng210; +import edu.ferris.seng210.expense.Expense; + public interface Expenser { void addExpense (Expense Ex); void addMonthlyIncome (Wage W); diff --git a/src/main/java/edu/ferris/seng210/UserCreationService.java b/src/main/java/edu/ferris/seng210/UserCreationService.java index 70ce8b9..c9e2c01 100644 --- a/src/main/java/edu/ferris/seng210/UserCreationService.java +++ b/src/main/java/edu/ferris/seng210/UserCreationService.java @@ -1,6 +1,8 @@ package edu.ferris.seng210; import edu.ferris.seng210.account.User; +import edu.ferris.seng210.checker.PasswordComplexityChecker; +import edu.ferris.seng210.checker.UsernameChecker; import java.io.FileNotFoundException; import java.io.FileOutputStream; diff --git a/src/main/java/edu/ferris/seng210/account/User.java b/src/main/java/edu/ferris/seng210/account/User.java index fd92726..8dc9214 100644 --- a/src/main/java/edu/ferris/seng210/account/User.java +++ b/src/main/java/edu/ferris/seng210/account/User.java @@ -1,7 +1,7 @@ package edu.ferris.seng210.account; import edu.ferris.seng210.Currency; -import edu.ferris.seng210.Expense; +import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.Wage; import java.util.ArrayList; diff --git a/src/main/java/edu/ferris/seng210/PasswordCheckerService.java b/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java similarity index 91% rename from src/main/java/edu/ferris/seng210/PasswordCheckerService.java rename to src/main/java/edu/ferris/seng210/checker/PasswordChecker.java index bb2af47..2512cbd 100644 --- a/src/main/java/edu/ferris/seng210/PasswordCheckerService.java +++ b/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java @@ -1,10 +1,12 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.checker; + +import edu.ferris.seng210.EWalletApp; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Scanner; -public class PasswordCheckerService { +public class PasswordChecker { public boolean check(String username,String password) { boolean flag = false; diff --git a/src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java b/src/main/java/edu/ferris/seng210/checker/PasswordComplexityChecker.java similarity index 87% rename from src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java rename to src/main/java/edu/ferris/seng210/checker/PasswordComplexityChecker.java index edec58a..e8c8e47 100644 --- a/src/main/java/edu/ferris/seng210/PasswordComplexityChecker.java +++ b/src/main/java/edu/ferris/seng210/checker/PasswordComplexityChecker.java @@ -1,4 +1,4 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.checker; public class PasswordComplexityChecker { diff --git a/src/main/java/edu/ferris/seng210/UsernameChecker.java b/src/main/java/edu/ferris/seng210/checker/UsernameChecker.java similarity index 98% rename from src/main/java/edu/ferris/seng210/UsernameChecker.java rename to src/main/java/edu/ferris/seng210/checker/UsernameChecker.java index daaac83..56aac40 100644 --- a/src/main/java/edu/ferris/seng210/UsernameChecker.java +++ b/src/main/java/edu/ferris/seng210/checker/UsernameChecker.java @@ -1,4 +1,4 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.checker; import java.io.FileInputStream; import java.io.FileNotFoundException; diff --git a/src/main/java/edu/ferris/seng210/Expense.java b/src/main/java/edu/ferris/seng210/expense/Expense.java similarity index 93% rename from src/main/java/edu/ferris/seng210/Expense.java rename to src/main/java/edu/ferris/seng210/expense/Expense.java index 99b170e..1b25a1d 100644 --- a/src/main/java/edu/ferris/seng210/Expense.java +++ b/src/main/java/edu/ferris/seng210/expense/Expense.java @@ -1,4 +1,4 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.expense; public class Expense { String source; diff --git a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java index 2362887..31815c1 100644 --- a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java @@ -1,7 +1,7 @@ package edu.ferris.seng210.panels; import edu.ferris.seng210.UserCreationService; -import edu.ferris.seng210.UsernameChecker; +import edu.ferris.seng210.checker.UsernameChecker; import javax.swing.*; import java.awt.*; diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java index 30ba13a..c3e9784 100644 --- a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -1,6 +1,6 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.Expense; +import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; import edu.ferris.seng210.Wage; diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index 76fc7fc..fd87e56 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -1,6 +1,6 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.Expense; +import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; From 90a44b96db34726982214bb619877cf537ca87b6 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:24:08 -0400 Subject: [PATCH 054/123] encapsulating variables in Wage --- src/main/java/edu/ferris/seng210/Wage.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/Wage.java b/src/main/java/edu/ferris/seng210/Wage.java index 839dfba..a94bce1 100644 --- a/src/main/java/edu/ferris/seng210/Wage.java +++ b/src/main/java/edu/ferris/seng210/Wage.java @@ -1,9 +1,9 @@ package edu.ferris.seng210; public class Wage { - String source; - double amount; - String Month; + private String source; + private double amount; + private String Month; public Wage(String source, double amount, String Month) { this.source = source; From d04619b7fa451a0d94a72470bcf0d178899f1eab Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:24:57 -0400 Subject: [PATCH 055/123] Renaming services used in LoginPanel for login action --- src/main/java/edu/ferris/seng210/panels/LoginPanel.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java index 70ca1b5..2df3da5 100644 --- a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java @@ -1,7 +1,7 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.PasswordCheckerService; -import edu.ferris.seng210.UsernameChecker; +import edu.ferris.seng210.checker.PasswordChecker; +import edu.ferris.seng210.checker.UsernameChecker; import javax.swing.*; import java.awt.*; @@ -75,9 +75,9 @@ public void actionPerformed(ActionEvent e) { password = passwordIncField.getText(); UsernameChecker usernameChecker = new UsernameChecker(); - PasswordCheckerService passwordCheckerService = new PasswordCheckerService(); + PasswordChecker passwordChecker = new PasswordChecker(); - if(usernameChecker.check(username) && passwordCheckerService.check(username, password)) { + if(usernameChecker.check(username) && passwordChecker.check(username, password)) { usernameIncField.setText(""); passwordIncField.setText(""); System.out.println("Login Successful"); From 6095b44998eb5f7c31706c2e8ed8e2bc8c4dfd28 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:25:48 -0400 Subject: [PATCH 056/123] Fixing incorrect naming due to incorrect renaming, and moving to new package for ExpenserMain --- .../java/edu/ferris/seng210/ExpenserMain.java | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java index 94ffbaf..06ad948 100644 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -1,6 +1,7 @@ package edu.ferris.seng210; import edu.ferris.seng210.account.User; +import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.panels.DetailedReportPanel; import edu.ferris.seng210.panels.ExpenseReportPanel; import edu.ferris.seng210.panels.HomePanel; @@ -48,25 +49,23 @@ public void PrintExpensebyType() { public void exportReport(String reportTitle) { try { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); - String filePath = ""; - String fileName = reportTitle + dateTimeFormatter.format(LocalDateTime.now()); // title + time & date - String fileType = "csv"; - File reportFile = new File(filePath + fileName + "." + fileType); + String dateTime = LocalDateTime.now().format(dateTimeFormatter); + File reportFile = new File(String.format("%s-%s.csv", reportTitle, dateTime)); FileOutputStream fileStream = new FileOutputStream(reportFile,true); PrintWriter printWriter = new PrintWriter(fileStream); reportFile.createNewFile(); - if (reportTitle.startsWith("main.java.seng210.Expense Report")) { + if (reportTitle.startsWith("Expense Report")) { printWriter.append("Total Income"); printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); printWriter.append("\n"); - printWriter.append("Total main.java.seng210.Expense"); + printWriter.append("Total Expense"); printWriter.append(","); printWriter.append("" + userAtHand.getExpenses()); printWriter.append("\n"); - printWriter.append("Filtered main.java.seng210.Expense"); + printWriter.append("Filtered Expense"); printWriter.append(","); printWriter.append("" + ExpenseReportPanel.totalFilteredExpenseAmtLbl.getText()); printWriter.append("\n"); @@ -86,7 +85,7 @@ public void exportReport(String reportTitle) { printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); printWriter.append("\n"); - printWriter.append("Total main.java.seng210.Expense"); + printWriter.append("Total Expense"); printWriter.append(","); printWriter.append("" + userAtHand.getExpenses()); printWriter.append("\n"); @@ -110,7 +109,7 @@ public void exportReport(String reportTitle) { printWriter.append(","); printWriter.append("" + userAtHand.getBalance()); printWriter.append("\n"); - printWriter.append("Total main.java.seng210.Expense"); + printWriter.append("Total Expense"); printWriter.append(","); printWriter.append("" + userAtHand.getExpenses()); printWriter.append("\n"); @@ -128,7 +127,7 @@ public void exportReport(String reportTitle) { } for (Expense exp : userAtHand.getSpending()) { - printWriter.append("main.java.seng210.Expense,"); + printWriter.append("Expense,"); printWriter.append("" + exp.getSource() + ","); printWriter.append("" + exp.getAmount() + ","); printWriter.append("" + exp.getFrequency() + "\n"); @@ -349,7 +348,7 @@ public void updateIncomeTable() { int i = 0; for(Wage wage : userAtHand.getIncome()) { - userAtHand.setBalance(userAtHand.getBalance() + wage.amount); + userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); IncomeReportPanel.incomeTable.setValueAt(wage.getSource(), i, 0); IncomeReportPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); IncomeReportPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); @@ -374,7 +373,7 @@ public void updateDetailedTable() { } for(Expense expense : userAtHand.getSpending()) { - DetailedReportPanel.detailedTable.setValueAt("main.java.seng210.Expense", i, 0); + DetailedReportPanel.detailedTable.setValueAt("Expense", i, 0); DetailedReportPanel.detailedTable.setValueAt(expense.getSource(), i, 1); DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); DetailedReportPanel.detailedTable.setValueAt(expense.getFrequency(), i, 3); @@ -394,7 +393,7 @@ public void updateExpenseTable() { userAtHand.setExpenses(0.00f); int i = 0; for(Expense expense : userAtHand.getSpending()) { - userAtHand.setExpenses(userAtHand.getExpenses() + expense.amount); + userAtHand.setExpenses(userAtHand.getExpenses() + expense.getAmount()); ExpenseReportPanel.spendingTable.setValueAt(expense.getSource(), i, 0); ExpenseReportPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); ExpenseReportPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); @@ -407,8 +406,8 @@ public void updateIncomeValues() { userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); updateMonthlySavings(); IncomeReportPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); - HomePanel.totalIncomeAmtLbl.setText("$" + String.format("%.2f",userAtHand.getBalance())); - HomePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); + HomePanel.totalIncomeAmtLbl.setText(String.format("$%.2f",userAtHand.getBalance())); + HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", userAtHand.getMonthlySavings())); } public void updateExpenseValues() { @@ -416,8 +415,8 @@ public void updateExpenseValues() { userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); updateMonthlySavings(); ExpenseReportPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); - HomePanel.totalExpensesAmtLbl.setText("$" + String.format("%.2f",getExpense(userAtHand.getSpending()))); - HomePanel.totalSavingsAmtLbl.setText("$" + String.format("%.2f", userAtHand.getMonthlySavings())); + HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); + HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", userAtHand.getMonthlySavings())); } public double getTotalIncome(ArrayList wage) { From 2a632e6bc742a7160d281613fcc525af27da7a36 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:26:07 -0400 Subject: [PATCH 057/123] adding target folder to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ae3c172..09e3bc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /bin/ +/target/ From 694f47971cf052482275e513d84356d575ab5ee8 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:46:51 -0400 Subject: [PATCH 058/123] Creating months enum --- .../edu/ferris/seng210/constants/Months.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/constants/Months.java diff --git a/src/main/java/edu/ferris/seng210/constants/Months.java b/src/main/java/edu/ferris/seng210/constants/Months.java new file mode 100644 index 0000000..e6440d0 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/constants/Months.java @@ -0,0 +1,36 @@ +package edu.ferris.seng210.constants; + +import java.util.Arrays; +import java.util.List; + +public enum Months { + +JANUARY("January"), + FEBRUARY("February"), + MARCH("March"), + APRIL("April"), + MAY("May"), + JUNE("June"), + JULY("July"), + AUGUST("August"), + SEPTEMBER("September"), + OCTOBER("October"), + NOVEMBER("November"), + DECEMBER("December"); + + private final String name; + + Months(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static List getNames() { + return Arrays.stream(Months.values()) + .map(Months::getName) + .toList(); + } +} From f1490a1dfab825693d6cfba6a82d8133df68439d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:47:22 -0400 Subject: [PATCH 059/123] replacing months array with constant --- src/main/java/edu/ferris/seng210/panels/AddItemPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 005ad5b..8bb4e63 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -1,5 +1,6 @@ package edu.ferris.seng210.panels; +import edu.ferris.seng210.constants.Months; import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; @@ -25,17 +26,15 @@ public class AddItemPanel extends JTabbedPane{ JTextField nameExpField, amountExpField; JButton addIncomeButton, addExpenseButton; JComboBox monthComboBox; - String[] months; public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel) { expenserMain = new ExpenserMain(); expenserMain.userAtHand = user; - months = new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; incomePane = new JPanel(); expensePane = new JPanel(); - monthComboBox = new JComboBox<>(months); + monthComboBox = new JComboBox<>(Months.getNames().toArray()); monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); monthComboBox.setSelectedIndex(0); From 3cff2b612739c4d2441e723c8c3d3d0467edb979 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:48:30 -0400 Subject: [PATCH 060/123] replacing months array with constant --- .../java/edu/ferris/seng210/panels/IncomeReportPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java index ca3ddeb..16e2389 100644 --- a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -3,6 +3,7 @@ import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; import edu.ferris.seng210.Wage; +import edu.ferris.seng210.constants.Months; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; @@ -31,7 +32,6 @@ public class IncomeReportPanel extends JPanel { JPanel upperPanel; JComboBox monthSelector; public static JComboBox typeSelector; - String[] months; public IncomeReportPanel(User user) { expenserMain = new ExpenserMain(); @@ -89,8 +89,7 @@ public IncomeReportPanel(User user) { gbConst.insets = new Insets(0,20,20,0); upperPanel.add(filterTxt,gbConst); - months = new String[]{"","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; - monthSelector = new JComboBox<>(months); + monthSelector = new JComboBox<>(Months.getNames().toArray()); monthSelector.setPreferredSize(new Dimension(200,50)); monthSelector.setFont(new Font(null, Font.PLAIN, 24)); gbConst.gridx = 1; From f5f0b5f5722620174658a809f3a137e27955e61a Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 13:54:04 -0400 Subject: [PATCH 061/123] switching out ArrayList type for List returns for greater flexibility --- .../java/edu/ferris/seng210/ExpenserMain.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java index 06ad948..d29e881 100644 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -11,6 +11,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.List; public class ExpenserMain implements Expenser { public User userAtHand = null; @@ -296,8 +297,8 @@ public void updateMonthlySavings() { userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); } - public static ArrayList filterExpensesFreq(ArrayList exp, String freq) { - ArrayList filteredExpensesFreq = new ArrayList<>(); + public static List filterExpensesFreq(ArrayList exp, String freq) { + List filteredExpensesFreq = new ArrayList<>(); for(Expense ex : exp) { if(String.valueOf(ex.getFrequency()).equals(freq)) { filteredExpensesFreq.add(ex); @@ -306,8 +307,8 @@ public static ArrayList filterExpensesFreq(ArrayList exp, Stri return filteredExpensesFreq; } - public static ArrayList filterExpensesSource(ArrayList exp, String source) { - ArrayList filteredExpensesSource = new ArrayList<>(); + public static List filterExpensesSource(ArrayList exp, String source) { + List filteredExpensesSource = new ArrayList<>(); for(Expense ex : exp) { if(ex.getSource().equals(source)) { filteredExpensesSource.add(ex); @@ -316,8 +317,8 @@ public static ArrayList filterExpensesSource(ArrayList exp, St return filteredExpensesSource; } - public static ArrayList filterIncomesMonth(ArrayList wage, String month) { - ArrayList filteredIncomesMonth = new ArrayList<>(); + public static List filterIncomesMonth(ArrayList wage, String month) { + List filteredIncomesMonth = new ArrayList<>(); for(Wage w : wage) { if(w.getMonth().equals(month)) { filteredIncomesMonth.add(w); @@ -326,8 +327,8 @@ public static ArrayList filterIncomesMonth(ArrayList wage, String mo return filteredIncomesMonth; } - public static ArrayList filterIncomesSource(ArrayList wage, String source) { - ArrayList filteredIncomesSource = new ArrayList<>(); + public static List filterIncomesSource(ArrayList wage, String source) { + List filteredIncomesSource = new ArrayList<>(); for(Wage w : wage) { if(w.getSource().equals(source)) { filteredIncomesSource.add(w); From ea4167fb8fed5411df42fb4624d090bbb98c96dc Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 14:03:46 -0400 Subject: [PATCH 062/123] Fixing renaming issue in CreateAccountPanel --- src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java index 31815c1..562ee9b 100644 --- a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java @@ -98,7 +98,7 @@ public void actionPerformed(ActionEvent e) { UserCreationService userCreationService = new UserCreationService(); userCreationService.create(username, password); - JOptionPane.showMessageDialog(null, "main.java.seng210.User created successfully."); + JOptionPane.showMessageDialog(null, "User created successfully."); usernameField.setText(""); passwordField.setText(""); confPasswordField.setText(""); From dc0bbd5a65c4219b011be0708d92dc789511e01d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:52:47 -0400 Subject: [PATCH 063/123] creating new constant for expense frequency --- .../seng210/constants/ExpenseFrequency.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/constants/ExpenseFrequency.java diff --git a/src/main/java/edu/ferris/seng210/constants/ExpenseFrequency.java b/src/main/java/edu/ferris/seng210/constants/ExpenseFrequency.java new file mode 100644 index 0000000..d473a74 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/constants/ExpenseFrequency.java @@ -0,0 +1,27 @@ +package edu.ferris.seng210.constants; + +import java.util.Arrays; +import java.util.List; + +public enum ExpenseFrequency { + + ONCE(1), + MONTHLY(12), + BIWEEKLY(24); + + private final int frequency; + + ExpenseFrequency(int frequency) { + this.frequency = frequency; + } + + public int getFrequency() { + return frequency; + } + + public static List getFrequencies() { + return Arrays.stream(ExpenseFrequency.values()) + .map(ExpenseFrequency::getFrequency) + .toList(); + } +} From 8fa46f283694f14354ed45781dd1b7b01ddb1ee2 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:53:14 -0400 Subject: [PATCH 064/123] creating new service for filtering --- .../edu/ferris/seng210/FilterService.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/FilterService.java diff --git a/src/main/java/edu/ferris/seng210/FilterService.java b/src/main/java/edu/ferris/seng210/FilterService.java new file mode 100644 index 0000000..f31e763 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/FilterService.java @@ -0,0 +1,35 @@ +package edu.ferris.seng210; + +import edu.ferris.seng210.transactions.Expense; +import edu.ferris.seng210.transactions.Transaction; +import edu.ferris.seng210.transactions.Wage; + +import java.util.List; + +public class FilterService { + + public List filterBySource(List transactions, String source) { + return transactions.stream() + .filter(transaction -> transaction.getSource().equalsIgnoreCase(source)) + .toList(); + } + + public List filterByFrequency(List transactions, int frequency) { + return transactions.stream() + .filter(transaction -> transaction.getFrequency() == frequency) + .toList(); + } + + public List filterByMonth(List transactions, String month) { + return transactions.stream() + .filter(transaction -> transaction.getMonth().equalsIgnoreCase(month)) + .toList(); + } + + public List getSources(List transactions) { + return transactions.stream() + .map(Transaction::getSource) + .distinct() + .toList(); + } +} From fbcee2fc656d8be04f3b47a2f8e1d03ba7365308 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:53:29 -0400 Subject: [PATCH 065/123] creating new service for report generation --- .../edu/ferris/seng210/ReportService.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/ReportService.java diff --git a/src/main/java/edu/ferris/seng210/ReportService.java b/src/main/java/edu/ferris/seng210/ReportService.java new file mode 100644 index 0000000..8053ea5 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/ReportService.java @@ -0,0 +1,86 @@ +package edu.ferris.seng210; + +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.transactions.Expense; +import edu.ferris.seng210.transactions.Wage; + +import java.io.*; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +public class ReportService { + + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); + + public void exportExpenseReport(User user, int frequency) throws IOException { + String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); + FilterService filterService = new FilterService<>(); + File file = new File(fileName); + + if (!file.exists()) { + file.createNewFile(); + } + + try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { + printWriter.printf("Total Income, %f\n", user.getBalance()); + printWriter.printf("Total Expense, %f\n", user.getExpenses()); + printWriter.printf("Filtered Expenses, %f\n", user.getExpenses()); + printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); + printWriter.println("Source,Amount,Frequency"); + + List filteredExpenses = filterService.filterByFrequency(user.getSpending(), frequency); + + for (Expense expense : filteredExpenses) { + printWriter.printf("%s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); + } + } + } + + public void exportIncomeReport(User user, String month) throws IOException { + String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); + FilterService filterService = new FilterService<>(); + File file = new File(fileName); + + if (!file.exists()) { + file.createNewFile(); + } + + try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { + printWriter.printf("Total Income, %f\n", user.getBalance()); + printWriter.printf("Total Expense, %f\n", user.getExpenses()); + printWriter.printf("Filtered Income, %f\n", user.getMonthlySavings()); + printWriter.println("Source,Amount,Frequency"); + + List filteredIncome = filterService.filterByMonth(user.getIncome(), month); + + for (Wage wage : filteredIncome) { + printWriter.printf("%s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.getMonth()); + } + } + } + + public void exportDetailedReport(User user) throws IOException { + String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); + File file = new File(fileName); + + if (!file.exists()) { + file.createNewFile(); + } + + try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { + printWriter.printf("Total Income, %f\n", user.getBalance()); + printWriter.printf("Total Expense, %f\n", user.getExpenses()); + printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); + printWriter.println("Type,Source,Amount,Frequency / Month"); + + for (Wage wage : user.getIncome()) { + printWriter.printf("Income, %s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.getMonth()); + } + + for (Expense expense : user.getSpending()) { + printWriter.printf("Income, %s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); + } + } + } +} From 65e3dff5eaf9254fc54ea46a94901e0b55659dfa Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:53:49 -0400 Subject: [PATCH 066/123] creating new service for totaling --- .../java/edu/ferris/seng210/TotalingService.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/TotalingService.java diff --git a/src/main/java/edu/ferris/seng210/TotalingService.java b/src/main/java/edu/ferris/seng210/TotalingService.java new file mode 100644 index 0000000..eea530a --- /dev/null +++ b/src/main/java/edu/ferris/seng210/TotalingService.java @@ -0,0 +1,14 @@ +package edu.ferris.seng210; + +import edu.ferris.seng210.transactions.Transaction; + +import java.util.List; + +public class TotalingService { + + public Double getTotal(List wage) { + return wage.stream() + .map(Transaction::getAmount) + .reduce(0D, Double::sum); + } +} From bccb8863d632fdd38c6fdc2ed53a39c640ce9364 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:54:41 -0400 Subject: [PATCH 067/123] creating new interface to make it easier to use data in expense and wage classes. --- .../java/edu/ferris/seng210/transactions/Transaction.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/transactions/Transaction.java diff --git a/src/main/java/edu/ferris/seng210/transactions/Transaction.java b/src/main/java/edu/ferris/seng210/transactions/Transaction.java new file mode 100644 index 0000000..696ebd2 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/transactions/Transaction.java @@ -0,0 +1,7 @@ +package edu.ferris.seng210.transactions; + +public interface Transaction { + + String getSource(); + double getAmount(); +} From 119c31a1c0f6f865f5506fed80a2f573a791175b Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:55:43 -0400 Subject: [PATCH 068/123] switching from hard-type to flexible list type, encapsulating variables, and making some lists final --- .../java/edu/ferris/seng210/account/User.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/account/User.java b/src/main/java/edu/ferris/seng210/account/User.java index 8dc9214..959ca9c 100644 --- a/src/main/java/edu/ferris/seng210/account/User.java +++ b/src/main/java/edu/ferris/seng210/account/User.java @@ -1,20 +1,21 @@ package edu.ferris.seng210.account; import edu.ferris.seng210.Currency; -import edu.ferris.seng210.expense.Expense; -import edu.ferris.seng210.Wage; +import edu.ferris.seng210.transactions.Expense; +import edu.ferris.seng210.transactions.Wage; import java.util.ArrayList; +import java.util.List; public class User { - private ArrayList currencyRates; - private ArrayList Income = new ArrayList<>(); - private ArrayList Spending = new ArrayList<>(); - String username; - String pwd; - double balance; - double monthlysavings; - double expenses; + private List currencyRates; + private final List Income = new ArrayList<>(); + private final List Spending = new ArrayList<>(); + private String username; + private String pwd; + private double balance; + private double monthlysavings; + private double expenses; public User(String username, String password){ this.username = username; @@ -45,11 +46,11 @@ public void addMonthlyIncome(Wage W) { Income.add(W); } - public ArrayList getIncome() { + public List getIncome() { return this.Income; } - public ArrayList getSpending() { + public List getSpending() { return this.Spending; } From 2742377745f87dd58107b56b50b33538460dbecf Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:56:06 -0400 Subject: [PATCH 069/123] implementing interface, making variables final --- .../edu/ferris/seng210/{ => transactions}/Wage.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) rename src/main/java/edu/ferris/seng210/{ => transactions}/Wage.java (60%) diff --git a/src/main/java/edu/ferris/seng210/Wage.java b/src/main/java/edu/ferris/seng210/transactions/Wage.java similarity index 60% rename from src/main/java/edu/ferris/seng210/Wage.java rename to src/main/java/edu/ferris/seng210/transactions/Wage.java index a94bce1..db4c90b 100644 --- a/src/main/java/edu/ferris/seng210/Wage.java +++ b/src/main/java/edu/ferris/seng210/transactions/Wage.java @@ -1,9 +1,9 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.transactions; -public class Wage { - private String source; - private double amount; - private String Month; +public class Wage implements Transaction { + private final String source; + private final double amount; + private final String Month; public Wage(String source, double amount, String Month) { this.source = source; @@ -11,10 +11,12 @@ public Wage(String source, double amount, String Month) { this.Month = Month; } + @Override public String getSource() { return this.source; } + @Override public double getAmount() { return this.amount; } From 429ede347cddc55b6bac99b84f012f4b43a2fef0 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:56:46 -0400 Subject: [PATCH 070/123] implementing interface, making variables final, applying camelCase to yearly frequency variable --- .../edu/ferris/seng210/expense/Expense.java | 26 ----------------- .../ferris/seng210/transactions/Expense.java | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 26 deletions(-) delete mode 100644 src/main/java/edu/ferris/seng210/expense/Expense.java create mode 100644 src/main/java/edu/ferris/seng210/transactions/Expense.java diff --git a/src/main/java/edu/ferris/seng210/expense/Expense.java b/src/main/java/edu/ferris/seng210/expense/Expense.java deleted file mode 100644 index 1b25a1d..0000000 --- a/src/main/java/edu/ferris/seng210/expense/Expense.java +++ /dev/null @@ -1,26 +0,0 @@ -package edu.ferris.seng210.expense; - -public class Expense { - String source; - double amount; - int yearlyfrequency; //1 for 1 time or once a year, 12 for monthly or or 24 for biweekly - - public Expense(String source, double amount, int yearlyfrequency) { - this.source = source; - this.amount = amount; - this.yearlyfrequency = yearlyfrequency; - } - - public String getSource() { - return this.source; - } - - public double getAmount() { - return this.amount; - } - - public int getFrequency() { - return this.yearlyfrequency; - } - -} diff --git a/src/main/java/edu/ferris/seng210/transactions/Expense.java b/src/main/java/edu/ferris/seng210/transactions/Expense.java new file mode 100644 index 0000000..a677024 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/transactions/Expense.java @@ -0,0 +1,28 @@ +package edu.ferris.seng210.transactions; + +public class Expense implements Transaction{ + private final String source; + private final double amount; + private final int yearlyFrequency; + + public Expense(String source, double amount, int yearlyFrequency) { + this.source = source; + this.amount = amount; + this.yearlyFrequency = yearlyFrequency; + } + + @Override + public String getSource() { + return this.source; + } + + @Override + public double getAmount() { + return this.amount; + } + + public int getFrequency() { + return this.yearlyFrequency; + } + +} From 45ac9b85a51a51446d56bc1b92093f9b7d8fd0bc Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:58:05 -0400 Subject: [PATCH 071/123] updating parameter names --- src/main/java/edu/ferris/seng210/Expenser.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/Expenser.java b/src/main/java/edu/ferris/seng210/Expenser.java index 09ad18f..4f6fc35 100644 --- a/src/main/java/edu/ferris/seng210/Expenser.java +++ b/src/main/java/edu/ferris/seng210/Expenser.java @@ -1,19 +1,20 @@ package edu.ferris.seng210; -import edu.ferris.seng210.expense.Expense; +import edu.ferris.seng210.transactions.Expense; +import edu.ferris.seng210.transactions.Wage; public interface Expenser { - void addExpense (Expense Ex); - void addMonthlyIncome (Wage W); + void addExpense (Expense expense); + void addMonthlyIncome (Wage wage); void PrintFullreport(); void PrintExpensereport(); void PrintIncomereport(); void PrintIncomereportbyTpe(); void PrintExpensebyType(); void exportReport(String reportTitle); - Currency convertForeignCurrency(Currency C, double amount); + Currency convertForeignCurrency(Currency currency, double amount); boolean loadExpenseFile(String filePath); boolean loadIncomeFile(String filePath); - int whenCanIBuy(String itemname,double price); + int whenCanIBuy(String itemName,double price); void updateMonthlySavings(); } From f642c3f34fe088c0f59fbb8c3ef41ea43274dc56 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:58:47 -0400 Subject: [PATCH 072/123] removing usage of user variable in expenserMain --- .../java/edu/ferris/seng210/panels/AddItemPanel.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 8bb4e63..67a8cce 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -1,10 +1,10 @@ package edu.ferris.seng210.panels; import edu.ferris.seng210.constants.Months; -import edu.ferris.seng210.expense.Expense; +import edu.ferris.seng210.transactions.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; -import edu.ferris.seng210.Wage; +import edu.ferris.seng210.transactions.Wage; import javax.swing.*; import java.awt.*; @@ -28,8 +28,7 @@ public class AddItemPanel extends JTabbedPane{ JComboBox monthComboBox; public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel) { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; + expenserMain = new ExpenserMain(user); incomePane = new JPanel(); expensePane = new JPanel(); @@ -136,7 +135,7 @@ public void actionPerformed(ActionEvent e) { source = nameIncField.getText(); month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); Wage w = new Wage(source, amount, month); - expenserMain.userAtHand.addMonthlyIncome(w); + user.addMonthlyIncome(w); if(incomeReportPanel.typeSelector.getItemCount() > 0) { boolean contains = false; From 2406988d9083da05c853a7c8984cd7047ef869a0 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:58:58 -0400 Subject: [PATCH 073/123] removing usage of user variable in expenserMain --- src/main/java/edu/ferris/seng210/AppFrame.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/AppFrame.java b/src/main/java/edu/ferris/seng210/AppFrame.java index 3c7c461..4509c79 100644 --- a/src/main/java/edu/ferris/seng210/AppFrame.java +++ b/src/main/java/edu/ferris/seng210/AppFrame.java @@ -21,8 +21,7 @@ public class AppFrame extends JFrame { this.setTitle("EWallet Application"); User user = new User("Default", "TempPassword!123"); - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; + expenserMain = new ExpenserMain(user); LoginPanel loginPanel = new LoginPanel(); CreateAccountPanel createAccountPanel = new CreateAccountPanel(); From 1b9f473893a6365a6639b368a5007cbff91fc532 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 15:59:40 -0400 Subject: [PATCH 074/123] removing usage of user variable in expenserMain, removing storing of lists needlessly --- .../ferris/seng210/panels/DetailedReportPanel.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java index c3e9784..0e95ace 100644 --- a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -1,9 +1,7 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; -import edu.ferris.seng210.Wage; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; @@ -11,15 +9,12 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; public class DetailedReportPanel extends JPanel { public static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; public static JScrollPane jScrollPane; - ArrayList Spending; - ArrayList Income; Object[][] tableVals; String[] columnHeadings; public static JTable detailedTable; @@ -28,8 +23,7 @@ public class DetailedReportPanel extends JPanel { ExpenserMain expenserMain; public DetailedReportPanel(User user) { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; + expenserMain = new ExpenserMain(user); this.setLayout(new BorderLayout()); detaileReportTxt = new JLabel("Detailed Report"); @@ -38,9 +32,7 @@ public DetailedReportPanel(User user) { this.add(detaileReportTxt, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; - Spending = expenserMain.userAtHand.getSpending(); - Income = expenserMain.userAtHand.getIncome(); - tableVals = new Object[Spending.size()+Income.size()][4]; + tableVals = new Object[user.getIncome().size() + user.getSpending().size()][4]; model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model detailedTable = new JTable(model) { public boolean isCellEditable(int row, int column) { // restricting cell editing From 2d39ec6947b4e21daca18c151185b2392ca1eba8 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:02:23 -0400 Subject: [PATCH 075/123] removing storing of lists, removing usage of expenserMain --- .../seng210/panels/ExpenseReportPanel.java | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index fd87e56..1dd7dc9 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -1,7 +1,9 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.expense.Expense; -import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.FilterService; +import edu.ferris.seng210.ReportService; +import edu.ferris.seng210.constants.ExpenseFrequency; +import edu.ferris.seng210.transactions.Expense; import edu.ferris.seng210.account.User; import javax.swing.*; @@ -10,15 +12,14 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; +import java.io.IOException; +import java.util.List; public class ExpenseReportPanel extends JPanel { public static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; public static JScrollPane jScrollPane; - public static ArrayList Spending; - public static ArrayList filteredSpending = new ArrayList<>(); Object[][] tableVals; String[] columnHeadings; public static JTable spendingTable; @@ -26,18 +27,12 @@ public class ExpenseReportPanel extends JPanel { JLabel totalExpenseLbl, totalFilteredExpenseLbl, filterTxt ; public static JLabel totalExpenseAmtLbl, totalFilteredExpenseAmtLbl; JButton exportReport, applyFilter; - ExpenserMain expenserMain; GridBagConstraints gbConst; JPanel upperPanel; JComboBox monthSelector; public static JComboBox typeSelector; - String[] frequency; public ExpenseReportPanel(User user) { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; - Spending = expenserMain.userAtHand.getSpending(); - this.setLayout(new BorderLayout()); @@ -90,8 +85,7 @@ public ExpenseReportPanel(User user) { gbConst.insets = new Insets(0,20,20,0); upperPanel.add(filterTxt,gbConst); - frequency = new String[]{"1", "12","24"}; - monthSelector = new JComboBox<>(frequency); + monthSelector = new JComboBox<>(ExpenseFrequency.getFrequencies().toArray()); monthSelector.setFont(new Font(null, Font.PLAIN, 24)); monthSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 1; @@ -99,7 +93,8 @@ public ExpenseReportPanel(User user) { gbConst.insets = new Insets(0,20,20,20); upperPanel.add(monthSelector,gbConst); - typeSelector = new JComboBox<>(expenserMain.getExpenseSources(Spending).toArray()); + FilterService filterService = new FilterService<>(); + typeSelector = new JComboBox<>(filterService.getSources(user.getSpending()).toArray()); typeSelector.setFont(new Font(null, Font.PLAIN, 24)); typeSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 2; @@ -112,9 +107,8 @@ public ExpenseReportPanel(User user) { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == applyFilter) { - filteredSpending = expenserMain.filterExpensesFreq - (expenserMain.filterExpensesSource(expenserMain.userAtHand.getSpending(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())) - ,(String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + List filteredSpending = filterService.filterByFrequency(user.getSpending(), Integer.parseInt(monthSelector.getSelectedItem().toString())); + filteredSpending = filterService.filterBySource(filteredSpending, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); model.setNumRows(filteredSpending.size()); int i = 0; double expenseSum = 0.00f; @@ -139,7 +133,7 @@ public void actionPerformed(ActionEvent e) { centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Frequency"}; - tableVals = new Object[Spending.size()][3]; + tableVals = new Object[user.getSpending().size()][3]; model = new DefaultTableModel(tableVals, columnHeadings); spendingTable = new JTable(model) { public boolean isCellEditable(int row, int column) { // restricting cell editing @@ -171,7 +165,12 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == exportReport) { - expenserMain.exportReport("main.java.seng210.Expense Report"); + ReportService reportService = new ReportService(); + try { + reportService.exportExpenseReport(user, Integer.parseInt(monthSelector.getSelectedItem().toString())); + } catch (IOException ex) { + throw new RuntimeException(ex); + } } } }); From b3ff73229b13a221cc2070258c09e1db433ae6c1 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:03:36 -0400 Subject: [PATCH 076/123] removing userAtHand variable. Replacing with one passed by constructor. Removing exportReport, cleaning up updating methods --- .../java/edu/ferris/seng210/ExpenserMain.java | 245 ++++-------------- 1 file changed, 47 insertions(+), 198 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java index d29e881..fd4b9c7 100644 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -1,29 +1,31 @@ package edu.ferris.seng210; import edu.ferris.seng210.account.User; -import edu.ferris.seng210.expense.Expense; import edu.ferris.seng210.panels.DetailedReportPanel; import edu.ferris.seng210.panels.ExpenseReportPanel; import edu.ferris.seng210.panels.HomePanel; import edu.ferris.seng210.panels.IncomeReportPanel; +import edu.ferris.seng210.transactions.Expense; +import edu.ferris.seng210.transactions.Wage; import java.io.*; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; public class ExpenserMain implements Expenser { - public User userAtHand = null; + + private final User user; + + public ExpenserMain(User user) { + this.user = user; + } @Override - public void addExpense (Expense Ex) { - userAtHand.addExpense(Ex); + public void addExpense (Expense expense) { + user.addExpense(expense); } @Override - public void addMonthlyIncome (Wage W) { - userAtHand.addMonthlyIncome(W); + public void addMonthlyIncome (Wage wage) { + user.addMonthlyIncome(wage); } @Override @@ -48,99 +50,7 @@ public void PrintExpensebyType() { @Override public void exportReport(String reportTitle) { - try { - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); - String dateTime = LocalDateTime.now().format(dateTimeFormatter); - File reportFile = new File(String.format("%s-%s.csv", reportTitle, dateTime)); - FileOutputStream fileStream = new FileOutputStream(reportFile,true); - PrintWriter printWriter = new PrintWriter(fileStream); - - reportFile.createNewFile(); - - if (reportTitle.startsWith("Expense Report")) { - printWriter.append("Total Income"); - printWriter.append(","); - printWriter.append("" + userAtHand.getBalance()); - printWriter.append("\n"); - printWriter.append("Total Expense"); - printWriter.append(","); - printWriter.append("" + userAtHand.getExpenses()); - printWriter.append("\n"); - printWriter.append("Filtered Expense"); - printWriter.append(","); - printWriter.append("" + ExpenseReportPanel.totalFilteredExpenseAmtLbl.getText()); - printWriter.append("\n"); - printWriter.append("Total Savings"); - printWriter.append(","); - printWriter.append("" + userAtHand.getMonthlySavings()); - printWriter.append("\n"); - printWriter.append("Source,Amount,Frequency\n"); - - for (Expense exp : ExpenseReportPanel.filteredSpending) { - printWriter.append("" + exp.getSource() + ","); - printWriter.append("" + exp.getAmount() + ","); - printWriter.append("" + exp.getFrequency() + "\n"); - } - } else if (reportTitle.startsWith("Income Report")) { - printWriter.append("Total Income"); - printWriter.append(","); - printWriter.append("" + userAtHand.getBalance()); - printWriter.append("\n"); - printWriter.append("Total Expense"); - printWriter.append(","); - printWriter.append("" + userAtHand.getExpenses()); - printWriter.append("\n"); - printWriter.append("Filtered Income"); - printWriter.append(","); - printWriter.append("" + IncomeReportPanel.totalFilteredIncomeAmtLbl.getText()); - printWriter.append("\n"); - printWriter.append("Total Savings"); - printWriter.append(","); - printWriter.append("" + userAtHand.getMonthlySavings()); - printWriter.append("\n"); - printWriter.append("Source,Amount,Frequency\n"); - - for (Wage wage : IncomeReportPanel.filteredIncomeList) { - printWriter.append("" + wage.getSource() + ","); - printWriter.append("" + wage.getAmount() + ","); - printWriter.append("" + wage.getMonth() + "\n"); - } - } else if (reportTitle.startsWith("Detailed Report")) { - printWriter.append("Total Income"); - printWriter.append(","); - printWriter.append("" + userAtHand.getBalance()); - printWriter.append("\n"); - printWriter.append("Total Expense"); - printWriter.append(","); - printWriter.append("" + userAtHand.getExpenses()); - printWriter.append("\n"); - printWriter.append("Total Savings"); - printWriter.append(","); - printWriter.append("" + userAtHand.getMonthlySavings()); - printWriter.append("\n"); - printWriter.append("Type,Source,Amount,Frequency / Month\n"); - - for (Wage wage : userAtHand.getIncome()) { - printWriter.append("Income,"); - printWriter.append("" + wage.getSource() + ","); - printWriter.append("" + wage.getAmount() + ","); - printWriter.append("" + wage.getMonth() + "\n"); - } - - for (Expense exp : userAtHand.getSpending()) { - printWriter.append("Expense,"); - printWriter.append("" + exp.getSource() + ","); - printWriter.append("" + exp.getAmount() + ","); - printWriter.append("" + exp.getFrequency() + "\n"); - } - } - printWriter.close(); - - - } catch (IOException exception) { - exception.printStackTrace(); - } } @Override @@ -189,7 +99,7 @@ else if (lineIndex > 0){ expense = new Expense(source,Double.parseDouble(amount),Integer.valueOf(frequency)); - userAtHand.setExpenses(userAtHand.getExpenses() + expense.getAmount()); + user.setExpenses(user.getExpenses() + expense.getAmount()); addExpense(expense); if(ExpenseReportPanel.typeSelector.getItemCount() > 0) { @@ -260,7 +170,7 @@ public boolean loadIncomeFile(String filePath) { wage = new Wage(source,Double.parseDouble(amount),month); - userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); + user.setBalance(user.getBalance() + wage.getAmount()); addMonthlyIncome(wage); if(IncomeReportPanel.typeSelector.getItemCount() > 0) { @@ -294,62 +204,22 @@ public int whenCanIBuy(String itemname, double price) { @Override public void updateMonthlySavings() { - userAtHand.setMonthlySavings(userAtHand.getBalance() - userAtHand.getExpenses()); - } - - public static List filterExpensesFreq(ArrayList exp, String freq) { - List filteredExpensesFreq = new ArrayList<>(); - for(Expense ex : exp) { - if(String.valueOf(ex.getFrequency()).equals(freq)) { - filteredExpensesFreq.add(ex); - } - } - return filteredExpensesFreq; - } - - public static List filterExpensesSource(ArrayList exp, String source) { - List filteredExpensesSource = new ArrayList<>(); - for(Expense ex : exp) { - if(ex.getSource().equals(source)) { - filteredExpensesSource.add(ex); - } - } - return filteredExpensesSource; - } - - public static List filterIncomesMonth(ArrayList wage, String month) { - List filteredIncomesMonth = new ArrayList<>(); - for(Wage w : wage) { - if(w.getMonth().equals(month)) { - filteredIncomesMonth.add(w); - } - } - return filteredIncomesMonth; - } - - public static List filterIncomesSource(ArrayList wage, String source) { - List filteredIncomesSource = new ArrayList<>(); - for(Wage w : wage) { - if(w.getSource().equals(source)) { - filteredIncomesSource.add(w); - } - } - return filteredIncomesSource; + user.setMonthlySavings(user.getBalance() - user.getExpenses()); } public void updateIncomeTable() { IncomeReportPanel.model.setNumRows(0); - for(int j = 0; j < userAtHand.getIncome().size(); j++ ) { + for(int j = 0; j < user.getIncome().size(); j++ ) { IncomeReportPanel.model.addRow(new Object[]{}); } - userAtHand.setBalance(0.00f); + user.setBalance(0.00f); int i = 0; - for(Wage wage : userAtHand.getIncome()) { - userAtHand.setBalance(userAtHand.getBalance() + wage.getAmount()); + for(Wage wage : user.getIncome()) { + user.setBalance(user.getBalance() + wage.getAmount()); IncomeReportPanel.incomeTable.setValueAt(wage.getSource(), i, 0); IncomeReportPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); IncomeReportPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); @@ -360,12 +230,12 @@ public void updateIncomeTable() { public void updateDetailedTable() { DetailedReportPanel.model.setNumRows(0); - for(int j = 0; j < userAtHand.getIncome().size() + userAtHand.getSpending().size(); j++ ) { + for(int j = 0; j < user.getIncome().size() + user.getSpending().size(); j++ ) { DetailedReportPanel.model.addRow(new Object[]{}); } int i = 0; - for(Wage wage : userAtHand.getIncome()) { + for(Wage wage : user.getIncome()) { DetailedReportPanel.detailedTable.setValueAt("Income", i, 0); DetailedReportPanel.detailedTable.setValueAt(wage.getSource(), i, 1); DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); @@ -373,7 +243,7 @@ public void updateDetailedTable() { ++i; } - for(Expense expense : userAtHand.getSpending()) { + for(Expense expense : user.getSpending()) { DetailedReportPanel.detailedTable.setValueAt("Expense", i, 0); DetailedReportPanel.detailedTable.setValueAt(expense.getSource(), i, 1); DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); @@ -387,14 +257,14 @@ public void updateExpenseTable() { ExpenseReportPanel.model.setNumRows(0); - for(int j = 0; j < userAtHand.getSpending().size(); j++ ) { + for(int j = 0; j < user.getSpending().size(); j++ ) { ExpenseReportPanel.model.addRow(new Object[]{}); } - userAtHand.setExpenses(0.00f); + user.setExpenses(0.00f); int i = 0; - for(Expense expense : userAtHand.getSpending()) { - userAtHand.setExpenses(userAtHand.getExpenses() + expense.getAmount()); + for(Expense expense : user.getSpending()) { + user.setExpenses(user.getExpenses() + expense.getAmount()); ExpenseReportPanel.spendingTable.setValueAt(expense.getSource(), i, 0); ExpenseReportPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); ExpenseReportPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); @@ -403,54 +273,33 @@ public void updateExpenseTable() { } public void updateIncomeValues() { - userAtHand.setExpenses(getExpense(userAtHand.getSpending())); - userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); - updateMonthlySavings(); - IncomeReportPanel.totalIncomeAmtLbl.setText(String.format("$%.2f",getTotalIncome(userAtHand.getIncome()))); - HomePanel.totalIncomeAmtLbl.setText(String.format("$%.2f",userAtHand.getBalance())); - HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", userAtHand.getMonthlySavings())); - } + TotalingService expenseTotalingService = new TotalingService<>(); + TotalingService wageTotalingService = new TotalingService<>(); - public void updateExpenseValues() { - userAtHand.setExpenses(getExpense(userAtHand.getSpending())); - userAtHand.setBalance(getTotalIncome(userAtHand.getIncome())); - updateMonthlySavings(); - ExpenseReportPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); - HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f",getExpense(userAtHand.getSpending()))); - HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", userAtHand.getMonthlySavings())); - } + double expenseTotal = expenseTotalingService.getTotal(user.getSpending()); + double wageTotal = wageTotalingService.getTotal(user.getIncome()); - public double getTotalIncome(ArrayList wage) { - double sum = 0.00f; - for(Wage userWage : wage) { - sum += userWage.getAmount(); - } - return sum; + user.setExpenses(expenseTotal); + user.setBalance(wageTotal); + updateMonthlySavings(); + IncomeReportPanel.totalIncomeAmtLbl.setText(String.format("$%.2f", wageTotal)); + HomePanel.totalIncomeAmtLbl.setText(String.format("$%.2f",user.getBalance())); + HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", user.getMonthlySavings())); } - public ArrayList getIncomeSources(ArrayList updatedWage) { - ArrayList sources = new ArrayList<>(); - - for(Wage wage : updatedWage) { - sources.add(wage.getSource()); - } - return sources; - } + public void updateExpenseValues() { + TotalingService expenseTotalingService = new TotalingService<>(); + TotalingService wageTotalingService = new TotalingService<>(); - public ArrayList getExpenseSources(ArrayList expenses) { - ArrayList sources = new ArrayList<>(); - for(Expense exp : expenses) { - sources.add(exp.getSource()); - } - return sources; - } + double expenseTotal = expenseTotalingService.getTotal(user.getSpending()); + double wageTotal = wageTotalingService.getTotal(user.getIncome()); + user.setExpenses(expenseTotal); + user.setBalance(wageTotal); - public double getExpense(ArrayList Ex) { - double sum = 0.00f; - for(Expense ex : Ex) { - sum += ex.getAmount(); - } - return sum; + updateMonthlySavings(); + ExpenseReportPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",expenseTotal)); + HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f",expenseTotal)); + HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", user.getMonthlySavings())); } } From 9375995e8176dc2c6078e949e8a4d0a85b0add21 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:05:43 -0400 Subject: [PATCH 077/123] misc cleanup in ImportPanel --- .../edu/ferris/seng210/panels/ImportPanel.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java index c1ddbde..73979c8 100644 --- a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java @@ -16,19 +16,17 @@ public class ImportPanel extends JPanel { JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; JButton selectFileButton, importButton; JFileChooser fileChooser; - String[] typesOfImports; + String[] typesOfImports = {"Income", "Expense"}; JComboBox options; File userFile; public ImportPanel(User user) { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; + expenserMain = new ExpenserMain(user); fileChooser = new JFileChooser(); this.setLayout(new GridBagLayout()); gbConst = new GridBagConstraints(); - typesOfImports = new String[] {"Income","main.java.seng210.Expense"}; options = new JComboBox<>(typesOfImports); options.setSelectedIndex(0); @@ -50,7 +48,7 @@ public void actionPerformed(ActionEvent e) { userFile = fileChooser.getSelectedFile(); if(!userFile.getAbsolutePath().endsWith(".csv")){ JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); - System.out.println("main.java.seng210.User selected a non csv file!"); + System.out.println("User selected a non csv file!"); } System.out.println("The user selected: " + userFile.getAbsolutePath()); } else if (userDecision == JFileChooser.CANCEL_OPTION) { @@ -103,7 +101,7 @@ public void actionPerformed(ActionEvent e) { if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { System.out.println("Income Selected"); if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); } else { expenserMain.loadIncomeFile(userFile.getAbsolutePath()); expenserMain.updateIncomeTable(); @@ -111,9 +109,9 @@ public void actionPerformed(ActionEvent e) { expenserMain.updateIncomeValues(); } } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { - System.out.println("main.java.seng210.Expense Selected"); + System.out.println("Expense Selected"); if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning main.java.seng210.User!", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); } else { expenserMain.loadExpenseFile(userFile.getAbsolutePath()); expenserMain.updateExpenseTable(); From 39bda458dcab44d2838a5446bbe5d62b9a406c78 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:08:51 -0400 Subject: [PATCH 078/123] removing unnecessary lists and instantiation, misc cleanup --- .../seng210/panels/IncomeReportPanel.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java index 16e2389..917e654 100644 --- a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -1,9 +1,10 @@ package edu.ferris.seng210.panels; import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.FilterService; import edu.ferris.seng210.account.User; -import edu.ferris.seng210.Wage; import edu.ferris.seng210.constants.Months; +import edu.ferris.seng210.transactions.Wage; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; @@ -11,17 +12,15 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; +import java.util.List; public class IncomeReportPanel extends JPanel { public static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; public static JScrollPane jScrollPane; - public static ArrayList Income; - public static ArrayList filteredIncomeList = new ArrayList<>(); - Object[][] tableVals; // table values - String[] columnHeadings; + Object[][] tableVals; + String[] columnHeadings = {"Source","Amount", "Month"}; public static JTable incomeTable; JLabel incomeText, filterTxt; JLabel totalIncomeLbl, totalFilteredIncomeLbl; @@ -34,9 +33,7 @@ public class IncomeReportPanel extends JPanel { public static JComboBox typeSelector; public IncomeReportPanel(User user) { - expenserMain = new ExpenserMain(); - expenserMain.userAtHand = user; - Income = expenserMain.userAtHand.getIncome(); + expenserMain = new ExpenserMain(user); this.setLayout(new BorderLayout()); @@ -97,7 +94,8 @@ public IncomeReportPanel(User user) { gbConst.insets = new Insets(0,20,20,20); upperPanel.add(monthSelector,gbConst); - typeSelector = new JComboBox<>(expenserMain.getIncomeSources(Income).toArray()); + FilterService filterService = new FilterService<>(); + typeSelector = new JComboBox<>(filterService.getSources(user.getIncome()).toArray()); typeSelector.setFont(new Font(null, Font.PLAIN, 24)); typeSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 2; @@ -110,12 +108,14 @@ public IncomeReportPanel(User user) { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == applyFilter) { - filteredIncomeList = - expenserMain.filterIncomesMonth(expenserMain.filterIncomesSource(expenserMain.userAtHand.getIncome(),(String)typeSelector.getItemAt(typeSelector.getSelectedIndex())), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); - model.setNumRows(filteredIncomeList.size()); + + List filteredIncome = filterService.filterByMonth(user.getIncome(), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + filteredIncome = filterService.filterBySource(filteredIncome, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); + + model.setNumRows(filteredIncome.size()); int i = 0; double incomeSum = 0.00f; - for(Wage wage : filteredIncomeList) { + for(Wage wage : filteredIncome) { incomeTable.setValueAt(wage.getSource(), i, 0); incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); incomeTable.setValueAt(wage.getMonth(), i, 2); @@ -135,11 +135,10 @@ public void actionPerformed(ActionEvent e) { this.add(upperPanel, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); - columnHeadings = new String[]{"Source","Amount", "Month"}; - tableVals = new Object[Income.size()][3]; + tableVals = new Object[user.getIncome().size()][3]; model = new DefaultTableModel(tableVals, columnHeadings); incomeTable = new JTable(model) { - public boolean isCellEditable(int row, int column) { // restricting cell editing + public boolean isCellEditable(int row, int column) { return false; } }; @@ -166,7 +165,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing exportReport = new JButton("Export to CSV"); exportReport.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { // exports report to csv + public void actionPerformed(ActionEvent e) { expenserMain.exportReport("Income Report"); } }); From c23860ce6c5084608f3dae5ad78643f79b1f6f4c Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:09:15 -0400 Subject: [PATCH 079/123] making username and password temp rather than global --- src/main/java/edu/ferris/seng210/panels/LoginPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java index 2df3da5..9dd4fda 100644 --- a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java @@ -14,7 +14,6 @@ public class LoginPanel extends JPanel { GridBagConstraints gbConst; JTextField usernameIncField, passwordIncField; JButton loginBtn; - String username, password; public LoginPanel() { loginLbl = new JLabel("LOGIN"); @@ -71,8 +70,8 @@ public LoginPanel() { loginBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - username = usernameIncField.getText(); - password = passwordIncField.getText(); + String username = usernameIncField.getText(); + String password = passwordIncField.getText(); UsernameChecker usernameChecker = new UsernameChecker(); PasswordChecker passwordChecker = new PasswordChecker(); From 5bde8d6f6f9dcec63ebbcf0107cfcc1970dd3544 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:12:23 -0400 Subject: [PATCH 080/123] consolidating getting expenses and wages in update methods --- src/main/java/edu/ferris/seng210/ExpenserMain.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java index fd4b9c7..8a3d1cc 100644 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -273,14 +273,12 @@ public void updateExpenseTable() { } public void updateIncomeValues() { - TotalingService expenseTotalingService = new TotalingService<>(); - TotalingService wageTotalingService = new TotalingService<>(); - - double expenseTotal = expenseTotalingService.getTotal(user.getSpending()); - double wageTotal = wageTotalingService.getTotal(user.getIncome()); + double expenseTotal = new TotalingService().getTotal(user.getSpending()); + double wageTotal = new TotalingService().getTotal(user.getIncome()); user.setExpenses(expenseTotal); user.setBalance(wageTotal); + updateMonthlySavings(); IncomeReportPanel.totalIncomeAmtLbl.setText(String.format("$%.2f", wageTotal)); HomePanel.totalIncomeAmtLbl.setText(String.format("$%.2f",user.getBalance())); @@ -288,11 +286,9 @@ public void updateIncomeValues() { } public void updateExpenseValues() { - TotalingService expenseTotalingService = new TotalingService<>(); - TotalingService wageTotalingService = new TotalingService<>(); + double expenseTotal = new TotalingService().getTotal(user.getSpending()); + double wageTotal = new TotalingService().getTotal(user.getIncome()); - double expenseTotal = expenseTotalingService.getTotal(user.getSpending()); - double wageTotal = wageTotalingService.getTotal(user.getIncome()); user.setExpenses(expenseTotal); user.setBalance(wageTotal); From 239b85522aa1e7adf0638cc380b07dd0dc37c4de Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:32:32 -0400 Subject: [PATCH 081/123] fixing incorrect file path in UserCreationService --- src/main/java/edu/ferris/seng210/UserCreationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ferris/seng210/UserCreationService.java b/src/main/java/edu/ferris/seng210/UserCreationService.java index c9e2c01..3ba8e65 100644 --- a/src/main/java/edu/ferris/seng210/UserCreationService.java +++ b/src/main/java/edu/ferris/seng210/UserCreationService.java @@ -20,7 +20,7 @@ public void create(String username, String password) { EWalletApp.users.add(user); try { - FileOutputStream fileOutputStream = new FileOutputStream("src//UserCredentials.csv", true); + FileOutputStream fileOutputStream = new FileOutputStream("UserCredentials.csv", true); PrintWriter printWriter = new PrintWriter(fileOutputStream); printWriter.append(username); printWriter.append(","); From 7ded3b05a052c1b88370c635ea7b07c40f6bb53d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:54:16 -0400 Subject: [PATCH 082/123] updating method and variable names for better readability --- .../java/edu/ferris/seng210/account/User.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/account/User.java b/src/main/java/edu/ferris/seng210/account/User.java index 959ca9c..2c24d4e 100644 --- a/src/main/java/edu/ferris/seng210/account/User.java +++ b/src/main/java/edu/ferris/seng210/account/User.java @@ -9,13 +9,13 @@ public class User { private List currencyRates; - private final List Income = new ArrayList<>(); - private final List Spending = new ArrayList<>(); + private final List income = new ArrayList<>(); + private final List expenses = new ArrayList<>(); private String username; private String pwd; private double balance; - private double monthlysavings; - private double expenses; + private double monthlySavings; + private double totalExpenses; public User(String username, String password){ this.username = username; @@ -39,19 +39,19 @@ public void setPwd(String password) { } public void addExpense(Expense Ex) { - Spending.add(Ex); + expenses.add(Ex); } public void addMonthlyIncome(Wage W) { - Income.add(W); + income.add(W); } public List getIncome() { - return this.Income; + return this.income; } - public List getSpending() { - return this.Spending; + public List getExpenses() { + return this.expenses; } public void setBalance(double balance) { @@ -62,20 +62,20 @@ public double getBalance(){ return this.balance; } - public void setExpenses(double expenses) { - this.expenses = expenses; + public void setTotalExpenses(double totalExpenses) { + this.totalExpenses = totalExpenses; } - public double getExpenses() { - return this.expenses; + public double getTotalExpenses() { + return this.totalExpenses; } public double getMonthlySavings() { - return this.monthlysavings; + return this.monthlySavings; } public void setMonthlySavings(double monthlySavings) { - this.monthlysavings = monthlySavings; + this.monthlySavings = monthlySavings; } } From e7c9adb0e579a23ff95a31b41967b60f4342ed49 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:54:46 -0400 Subject: [PATCH 083/123] updating method calls --- .../java/edu/ferris/seng210/ExpenserMain.java | 26 +++++++++---------- .../edu/ferris/seng210/ReportService.java | 12 ++++----- .../seng210/panels/DetailedReportPanel.java | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java index 8a3d1cc..493f112 100644 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ b/src/main/java/edu/ferris/seng210/ExpenserMain.java @@ -99,7 +99,7 @@ else if (lineIndex > 0){ expense = new Expense(source,Double.parseDouble(amount),Integer.valueOf(frequency)); - user.setExpenses(user.getExpenses() + expense.getAmount()); + user.setTotalExpenses(user.getTotalExpenses() + expense.getAmount()); addExpense(expense); if(ExpenseReportPanel.typeSelector.getItemCount() > 0) { @@ -204,7 +204,7 @@ public int whenCanIBuy(String itemname, double price) { @Override public void updateMonthlySavings() { - user.setMonthlySavings(user.getBalance() - user.getExpenses()); + user.setMonthlySavings(user.getBalance() - user.getTotalExpenses()); } public void updateIncomeTable() { @@ -230,7 +230,7 @@ public void updateIncomeTable() { public void updateDetailedTable() { DetailedReportPanel.model.setNumRows(0); - for(int j = 0; j < user.getIncome().size() + user.getSpending().size(); j++ ) { + for(int j = 0; j < user.getIncome().size() + user.getExpenses().size(); j++ ) { DetailedReportPanel.model.addRow(new Object[]{}); } @@ -243,7 +243,7 @@ public void updateDetailedTable() { ++i; } - for(Expense expense : user.getSpending()) { + for(Expense expense : user.getExpenses()) { DetailedReportPanel.detailedTable.setValueAt("Expense", i, 0); DetailedReportPanel.detailedTable.setValueAt(expense.getSource(), i, 1); DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); @@ -257,14 +257,14 @@ public void updateExpenseTable() { ExpenseReportPanel.model.setNumRows(0); - for(int j = 0; j < user.getSpending().size(); j++ ) { + for(int j = 0; j < user.getExpenses().size(); j++ ) { ExpenseReportPanel.model.addRow(new Object[]{}); } - user.setExpenses(0.00f); + user.setTotalExpenses(0.00f); int i = 0; - for(Expense expense : user.getSpending()) { - user.setExpenses(user.getExpenses() + expense.getAmount()); + for(Expense expense : user.getExpenses()) { + user.setTotalExpenses(user.getTotalExpenses() + expense.getAmount()); ExpenseReportPanel.spendingTable.setValueAt(expense.getSource(), i, 0); ExpenseReportPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); ExpenseReportPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); @@ -273,10 +273,10 @@ public void updateExpenseTable() { } public void updateIncomeValues() { - double expenseTotal = new TotalingService().getTotal(user.getSpending()); + double expenseTotal = new TotalingService().getTotal(user.getExpenses()); double wageTotal = new TotalingService().getTotal(user.getIncome()); - user.setExpenses(expenseTotal); + user.setTotalExpenses(expenseTotal); user.setBalance(wageTotal); updateMonthlySavings(); @@ -286,15 +286,15 @@ public void updateIncomeValues() { } public void updateExpenseValues() { - double expenseTotal = new TotalingService().getTotal(user.getSpending()); + double expenseTotal = new TotalingService().getTotal(user.getExpenses()); double wageTotal = new TotalingService().getTotal(user.getIncome()); - user.setExpenses(expenseTotal); + user.setTotalExpenses(expenseTotal); user.setBalance(wageTotal); updateMonthlySavings(); ExpenseReportPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",expenseTotal)); - HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f",expenseTotal)); + HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f", expenseTotal)); HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", user.getMonthlySavings())); } diff --git a/src/main/java/edu/ferris/seng210/ReportService.java b/src/main/java/edu/ferris/seng210/ReportService.java index 8053ea5..a9163e3 100644 --- a/src/main/java/edu/ferris/seng210/ReportService.java +++ b/src/main/java/edu/ferris/seng210/ReportService.java @@ -24,12 +24,12 @@ public void exportExpenseReport(User user, int frequency) throws IOException { try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { printWriter.printf("Total Income, %f\n", user.getBalance()); - printWriter.printf("Total Expense, %f\n", user.getExpenses()); - printWriter.printf("Filtered Expenses, %f\n", user.getExpenses()); + printWriter.printf("Total Expense, %f\n", user.getTotalExpenses()); + printWriter.printf("Filtered Expenses, %f\n", user.getTotalExpenses()); printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); printWriter.println("Source,Amount,Frequency"); - List filteredExpenses = filterService.filterByFrequency(user.getSpending(), frequency); + List filteredExpenses = filterService.filterByFrequency(user.getExpenses(), frequency); for (Expense expense : filteredExpenses) { printWriter.printf("%s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); @@ -48,7 +48,7 @@ public void exportIncomeReport(User user, String month) throws IOException { try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { printWriter.printf("Total Income, %f\n", user.getBalance()); - printWriter.printf("Total Expense, %f\n", user.getExpenses()); + printWriter.printf("Total Expense, %f\n", user.getTotalExpenses()); printWriter.printf("Filtered Income, %f\n", user.getMonthlySavings()); printWriter.println("Source,Amount,Frequency"); @@ -70,7 +70,7 @@ public void exportDetailedReport(User user) throws IOException { try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { printWriter.printf("Total Income, %f\n", user.getBalance()); - printWriter.printf("Total Expense, %f\n", user.getExpenses()); + printWriter.printf("Total Expense, %f\n", user.getTotalExpenses()); printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); printWriter.println("Type,Source,Amount,Frequency / Month"); @@ -78,7 +78,7 @@ public void exportDetailedReport(User user) throws IOException { printWriter.printf("Income, %s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.getMonth()); } - for (Expense expense : user.getSpending()) { + for (Expense expense : user.getExpenses()) { printWriter.printf("Income, %s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); } } diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java index 0e95ace..63df45b 100644 --- a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -32,7 +32,7 @@ public DetailedReportPanel(User user) { this.add(detaileReportTxt, BorderLayout.PAGE_START); centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Type","Source","Amount", "Month / Freq"}; - tableVals = new Object[user.getIncome().size() + user.getSpending().size()][4]; + tableVals = new Object[user.getIncome().size() + user.getExpenses().size()][4]; model = new DefaultTableModel(tableVals, columnHeadings); // setting up table model detailedTable = new JTable(model) { public boolean isCellEditable(int row, int column) { // restricting cell editing From b87d87283746e91ecf1a74307291dbb0d8268d7c Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:56:17 -0400 Subject: [PATCH 084/123] removing excessive logic chains and coupling when not necessary for adding transactions --- .../ferris/seng210/panels/AddItemPanel.java | 97 ++++--------------- 1 file changed, 21 insertions(+), 76 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 67a8cce..6bfd93e 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -14,9 +14,6 @@ public class AddItemPanel extends JTabbedPane{ ExpenserMain expenserMain; - int yearlyFrequency; - double amount; - String month, source; GridBagConstraints gbConst; JPanel incomePane, expensePane; JLabel addIncomeItemLbl, addExpenseItemLbl; @@ -25,8 +22,8 @@ public class AddItemPanel extends JTabbedPane{ JTextField nameIncField, amountIncField, frequencyExpField; JTextField nameExpField, amountExpField; JButton addIncomeButton, addExpenseButton; - JComboBox monthComboBox; - public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel) { + JComboBox monthComboBox; + public AddItemPanel(User user) { expenserMain = new ExpenserMain(user); @@ -125,42 +122,16 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == addIncomeButton) { - if(nameIncField.getText().length() > 0 && amountIncField.getText().length() > 0) { - try { - amount = Double.parseDouble(amountIncField.getText()); - } catch (NumberFormatException n) { - System.out.println(n.getMessage()); - amount = 0.00f; - } - source = nameIncField.getText(); - month = String.valueOf(monthComboBox.getItemAt(monthComboBox.getSelectedIndex())); - Wage w = new Wage(source, amount, month); - user.addMonthlyIncome(w); - - if(incomeReportPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < incomeReportPanel.typeSelector.getItemCount(); i++) { - if (incomeReportPanel.typeSelector.getItemAt(i).equals(w.getSource())) { - contains = true; - } - } - if (!contains) { - incomeReportPanel.typeSelector.addItem(w.getSource()); - } - } else { - incomeReportPanel.typeSelector.addItem(w.getSource()); - } - - expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(); - expenserMain.updateDetailedTable(); - - nameIncField.setText(""); - monthComboBox.setSelectedItem(0); - amountIncField.setText(""); - - } + user.addMonthlyIncome(new Wage(nameIncField.getText(), Double.parseDouble(amountIncField.getText()), monthComboBox.getSelectedItem().toString())); + + expenserMain.updateIncomeTable(); + expenserMain.updateIncomeValues(); + expenserMain.updateDetailedTable(); + + nameIncField.setText(""); + monthComboBox.setSelectedItem(0); + amountIncField.setText(""); } } }); @@ -224,42 +195,16 @@ public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == addExpenseButton) { - if(nameExpField.getText().length() > 0 && amountExpField.getText().length() > 0 & frequencyExpField.getText().length() > 0) { - try { - amount = Double.parseDouble(amountExpField.getText()); - yearlyFrequency = Integer.parseInt(frequencyExpField.getText()); - - } catch (NumberFormatException n) { - System.out.println(n.getMessage()); - amount = 0.00f; - } - source = nameExpField.getText(); - Expense Ex = new Expense(source, amount, yearlyFrequency); - expenserMain.addExpense(Ex); - expenserMain.updateExpenseValues(); - - if(expenseReportPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < expenseReportPanel.typeSelector.getItemCount(); i++) { - if (expenseReportPanel.typeSelector.getItemAt(i).equals(Ex.getSource())) { - contains = true; - } - } - if (!contains) { - expenseReportPanel.typeSelector.addItem(Ex.getSource()); - } - } else { - expenseReportPanel.typeSelector.addItem(Ex.getSource()); - } - - - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - - nameExpField.setText(""); - frequencyExpField.setText(""); - amountExpField.setText(""); - } + + user.addExpense(new Expense(nameExpField.getText(), Double.parseDouble(amountExpField.getText()), Integer.parseInt(frequencyExpField.getText()))); + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateExpenseValues(); + + nameExpField.setText(""); + frequencyExpField.setText(""); + amountExpField.setText(""); + } } }); From fe2d2f66a433d59381df8328d58028baad0bd8d3 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 16:56:41 -0400 Subject: [PATCH 085/123] moving button action logic to new methods --- .../seng210/panels/ExpenseReportPanel.java | 72 ++++++++++--------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index 1dd7dc9..4e19562 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -94,7 +94,7 @@ public ExpenseReportPanel(User user) { upperPanel.add(monthSelector,gbConst); FilterService filterService = new FilterService<>(); - typeSelector = new JComboBox<>(filterService.getSources(user.getSpending()).toArray()); + typeSelector = new JComboBox<>(filterService.getSources(user.getExpenses()).toArray()); typeSelector.setFont(new Font(null, Font.PLAIN, 24)); typeSelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 2; @@ -103,26 +103,7 @@ public ExpenseReportPanel(User user) { upperPanel.add(typeSelector,gbConst); applyFilter = new JButton("Filter"); - applyFilter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - List filteredSpending = filterService.filterByFrequency(user.getSpending(), Integer.parseInt(monthSelector.getSelectedItem().toString())); - filteredSpending = filterService.filterBySource(filteredSpending, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); - model.setNumRows(filteredSpending.size()); - int i = 0; - double expenseSum = 0.00f; - for(Expense exp : filteredSpending) { - spendingTable.setValueAt(exp.getSource(), i, 0); - spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); - spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); - ++i; - expenseSum += exp.getAmount(); - } - totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); - } - } - }); + applyFilter.addActionListener(filterAction(user, filterService)); applyFilter.setFont(new Font(null, Font.PLAIN, 24)); gbConst.gridx = 3; gbConst.gridy = 2; @@ -133,7 +114,7 @@ public void actionPerformed(ActionEvent e) { centerRenderer = new DefaultTableCellRenderer(); columnHeadings = new String[]{"Source","Amount", "Frequency"}; - tableVals = new Object[user.getSpending().size()][3]; + tableVals = new Object[user.getExpenses().size()][3]; model = new DefaultTableModel(tableVals, columnHeadings); spendingTable = new JTable(model) { public boolean isCellEditable(int row, int column) { // restricting cell editing @@ -161,7 +142,20 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { + exportReport.addActionListener(exportToCsvAction(user)); + exportReport.setSize(new Dimension(200,60)); + exportReport.setFont(new Font(null, Font.PLAIN, 24)); + + JPanel lowerPanel = new JPanel(); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + lowerPanel.add(exportReport, BorderLayout.CENTER); + lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); + this.add(lowerPanel, BorderLayout.SOUTH); + + } + + public ActionListener exportToCsvAction(User user) { + return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == exportReport) { @@ -173,15 +167,29 @@ public void actionPerformed(ActionEvent e) { } } } - }); - exportReport.setSize(new Dimension(200,60)); - exportReport.setFont(new Font(null, Font.PLAIN, 24)); - - JPanel lowerPanel = new JPanel(); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - lowerPanel.add(exportReport, BorderLayout.CENTER); - lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); - this.add(lowerPanel, BorderLayout.SOUTH); + }; + } + public ActionListener filterAction(User user, FilterService filterService) { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == applyFilter) { + List filteredSpending = filterService.filterByFrequency(user.getExpenses(), Integer.parseInt(monthSelector.getSelectedItem().toString())); + filteredSpending = filterService.filterBySource(filteredSpending, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); + model.setNumRows(filteredSpending.size()); + int i = 0; + double expenseSum = 0.00f; + for(Expense exp : filteredSpending) { + spendingTable.setValueAt(exp.getSource(), i, 0); + spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); + spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); + ++i; + expenseSum += exp.getAmount(); + } + totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); + } + } + }; } } From 944da7b17f496562823a196e37c7dbf8b44f53b5 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:31:43 -0400 Subject: [PATCH 086/123] fixing report file names --- src/main/java/edu/ferris/seng210/ReportService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ReportService.java b/src/main/java/edu/ferris/seng210/ReportService.java index a9163e3..604d5a6 100644 --- a/src/main/java/edu/ferris/seng210/ReportService.java +++ b/src/main/java/edu/ferris/seng210/ReportService.java @@ -38,7 +38,7 @@ public void exportExpenseReport(User user, int frequency) throws IOException { } public void exportIncomeReport(User user, String month) throws IOException { - String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); + String fileName = String.format("income-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); FilterService filterService = new FilterService<>(); File file = new File(fileName); @@ -61,7 +61,7 @@ public void exportIncomeReport(User user, String month) throws IOException { } public void exportDetailedReport(User user) throws IOException { - String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); + String fileName = String.format("detailed-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); File file = new File(fileName); if (!file.exists()) { From 1e7c02fffb33f4ddec0e22aca79fb644995bbdb0 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:32:34 -0400 Subject: [PATCH 087/123] moving button actions to new methods --- .../ferris/seng210/panels/AddItemPanel.java | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 6bfd93e..35ec8c8 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -13,6 +13,7 @@ public class AddItemPanel extends JTabbedPane{ + private final User user; ExpenserMain expenserMain; GridBagConstraints gbConst; JPanel incomePane, expensePane; @@ -23,8 +24,8 @@ public class AddItemPanel extends JTabbedPane{ JTextField nameExpField, amountExpField; JButton addIncomeButton, addExpenseButton; JComboBox monthComboBox; - public AddItemPanel(User user) { - + public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel) { + this.user = user; expenserMain = new ExpenserMain(user); incomePane = new JPanel(); @@ -118,23 +119,7 @@ public AddItemPanel(User user) { addIncomeButton.setPreferredSize(new Dimension(150,60)); incomePane.add(addIncomeButton, gbConst); - addIncomeButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == addIncomeButton) { - - user.addMonthlyIncome(new Wage(nameIncField.getText(), Double.parseDouble(amountIncField.getText()), monthComboBox.getSelectedItem().toString())); - - expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(); - expenserMain.updateDetailedTable(); - - nameIncField.setText(""); - monthComboBox.setSelectedItem(0); - amountIncField.setText(""); - } - } - }); + addIncomeButton.addActionListener(addIncomeAction(incomeReportPanel)); this.add("Add Income", incomePane); @@ -191,26 +176,46 @@ public void actionPerformed(ActionEvent e) { addExpenseButton.setPreferredSize(new Dimension(150,60)); expensePane.add(addExpenseButton, gbConst); - addExpenseButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == addExpenseButton) { + addExpenseButton.addActionListener(addExpenseAction(expenseReportPanel)); + + this.add("Add expense", expensePane); + this.setFont(new Font(null, Font.PLAIN, 24)); + } - user.addExpense(new Expense(nameExpField.getText(), Double.parseDouble(amountExpField.getText()), Integer.parseInt(frequencyExpField.getText()))); - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateExpenseValues(); + public ActionListener addIncomeAction(IncomeReportPanel incomeReportPanel) { + return e -> { + if(e.getSource() == addIncomeButton) { - nameExpField.setText(""); - frequencyExpField.setText(""); - amountExpField.setText(""); + user.addMonthlyIncome(new Wage(nameIncField.getText(), Double.parseDouble(amountIncField.getText()), monthComboBox.getSelectedItem().toString())); - } + expenserMain.updateIncomeTable(); + expenserMain.updateIncomeValues(); + expenserMain.updateDetailedTable(); + + incomeReportPanel.updateSources(); + nameIncField.setText(""); + monthComboBox.setSelectedItem(0); + amountIncField.setText(""); } - }); + }; + } - this.add("Add expense", expensePane); - this.setFont(new Font(null, Font.PLAIN, 24)); + public ActionListener addExpenseAction(ExpenseReportPanel expenseReportPanel) { + return e -> { + if(e.getSource() == addExpenseButton) { + + user.addExpense(new Expense(nameExpField.getText(), Double.parseDouble(amountExpField.getText()), Integer.parseInt(frequencyExpField.getText()))); + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateExpenseValues(); + expenseReportPanel.updateSources(); + + nameExpField.setText(""); + frequencyExpField.setText(""); + amountExpField.setText(""); + + } + }; } } From a35568a7e0f7505936962ae9496d5c1a96601360 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:37:55 -0400 Subject: [PATCH 088/123] reorganizing imports --- src/main/java/edu/ferris/seng210/panels/AddItemPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 35ec8c8..8f3cce0 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -1,14 +1,13 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.constants.Months; -import edu.ferris.seng210.transactions.Expense; import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.account.User; +import edu.ferris.seng210.constants.Months; +import edu.ferris.seng210.transactions.Expense; import edu.ferris.seng210.transactions.Wage; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class AddItemPanel extends JTabbedPane{ From cc7618ebab1e6c825283b078b6676891ecd4c9d3 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:38:26 -0400 Subject: [PATCH 089/123] moving button actions into new methods --- .../seng210/panels/DetailedReportPanel.java | 23 ++++-- .../seng210/panels/ExpenseReportPanel.java | 81 ++++++++++--------- .../seng210/panels/IncomeReportPanel.java | 81 ++++++++++++------- 3 files changed, 107 insertions(+), 78 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java index 63df45b..bc089ce 100644 --- a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -1,17 +1,18 @@ package edu.ferris.seng210.panels; import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.ReportService; import edu.ferris.seng210.account.User; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class DetailedReportPanel extends JPanel { + private final User user; public static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; public static JScrollPane jScrollPane; @@ -22,7 +23,7 @@ public class DetailedReportPanel extends JPanel { JButton exportReport; ExpenserMain expenserMain; public DetailedReportPanel(User user) { - + this.user = user; expenserMain = new ExpenserMain(user); this.setLayout(new BorderLayout()); @@ -60,12 +61,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - expenserMain.exportReport("Detailed Report"); - } - }); + exportReport.addActionListener(exportReportAction()); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -75,4 +71,15 @@ public void actionPerformed(ActionEvent e) { lowerPanel.add(Box.createRigidArea(new Dimension(25,50))); this.add(lowerPanel, BorderLayout.SOUTH); } + + public ActionListener exportReportAction() { + return e -> { + ReportService reportService = new ReportService(); + try { + reportService.exportDetailedReport(user); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }; + } } diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index 4e19562..61fb27c 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -10,13 +10,12 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.List; public class ExpenseReportPanel extends JPanel { - + private final User user; public static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; public static JScrollPane jScrollPane; @@ -29,12 +28,12 @@ public class ExpenseReportPanel extends JPanel { JButton exportReport, applyFilter; GridBagConstraints gbConst; JPanel upperPanel; - JComboBox monthSelector; - public static JComboBox typeSelector; + JComboBox frequencySelector; + public static JComboBox typeSelector; public ExpenseReportPanel(User user) { this.setLayout(new BorderLayout()); - + this.user = user; expenseText = new JLabel("Expense Report"); expenseText.setFont(new Font(null, Font.PLAIN, 40)); @@ -85,13 +84,13 @@ public ExpenseReportPanel(User user) { gbConst.insets = new Insets(0,20,20,0); upperPanel.add(filterTxt,gbConst); - monthSelector = new JComboBox<>(ExpenseFrequency.getFrequencies().toArray()); - monthSelector.setFont(new Font(null, Font.PLAIN, 24)); - monthSelector.setPreferredSize(new Dimension(200,50)); + frequencySelector = new JComboBox<>(ExpenseFrequency.getFrequencies().toArray()); + frequencySelector.setFont(new Font(null, Font.PLAIN, 24)); + frequencySelector.setPreferredSize(new Dimension(200,50)); gbConst.gridx = 1; gbConst.gridy = 2; gbConst.insets = new Insets(0,20,20,20); - upperPanel.add(monthSelector,gbConst); + upperPanel.add(frequencySelector,gbConst); FilterService filterService = new FilterService<>(); typeSelector = new JComboBox<>(filterService.getSources(user.getExpenses()).toArray()); @@ -103,7 +102,7 @@ public ExpenseReportPanel(User user) { upperPanel.add(typeSelector,gbConst); applyFilter = new JButton("Filter"); - applyFilter.addActionListener(filterAction(user, filterService)); + applyFilter.addActionListener(filterAction(filterService)); applyFilter.setFont(new Font(null, Font.PLAIN, 24)); gbConst.gridx = 3; gbConst.gridy = 2; @@ -142,7 +141,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(exportToCsvAction(user)); + exportReport.addActionListener(exportToCsvAction()); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -154,41 +153,43 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing } - public ActionListener exportToCsvAction(User user) { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == exportReport) { - ReportService reportService = new ReportService(); - try { - reportService.exportExpenseReport(user, Integer.parseInt(monthSelector.getSelectedItem().toString())); - } catch (IOException ex) { - throw new RuntimeException(ex); - } + public void updateSources() { + typeSelector.removeAllItems(); + + for(Object source : new FilterService().getSources(user.getExpenses())){ + typeSelector.addItem(source); + } + } + + public ActionListener exportToCsvAction() { + return e -> { + if(e.getSource() == exportReport) { + ReportService reportService = new ReportService(); + try { + reportService.exportExpenseReport(user, Integer.parseInt(frequencySelector.getSelectedItem().toString())); + } catch (IOException ex) { + throw new RuntimeException(ex); } } }; } - public ActionListener filterAction(User user, FilterService filterService) { - return new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - List filteredSpending = filterService.filterByFrequency(user.getExpenses(), Integer.parseInt(monthSelector.getSelectedItem().toString())); - filteredSpending = filterService.filterBySource(filteredSpending, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); - model.setNumRows(filteredSpending.size()); - int i = 0; - double expenseSum = 0.00f; - for(Expense exp : filteredSpending) { - spendingTable.setValueAt(exp.getSource(), i, 0); - spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); - spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); - ++i; - expenseSum += exp.getAmount(); - } - totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); + public ActionListener filterAction(FilterService filterService) { + return e -> { + if(e.getSource() == applyFilter) { + List filteredSpending = filterService.filterByFrequency(user.getExpenses(), Integer.parseInt(frequencySelector.getSelectedItem().toString())); + filteredSpending = filterService.filterBySource(filteredSpending, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); + model.setNumRows(filteredSpending.size()); + int i = 0; + double expenseSum = 0.00f; + for(Expense exp : filteredSpending) { + spendingTable.setValueAt(exp.getSource(), i, 0); + spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); + spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); + ++i; + expenseSum += exp.getAmount(); } + totalFilteredExpenseAmtLbl.setText(String.format("$%.2f",expenseSum)); } }; } diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java index 917e654..be11118 100644 --- a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -2,6 +2,7 @@ import edu.ferris.seng210.ExpenserMain; import edu.ferris.seng210.FilterService; +import edu.ferris.seng210.ReportService; import edu.ferris.seng210.account.User; import edu.ferris.seng210.constants.Months; import edu.ferris.seng210.transactions.Wage; @@ -12,10 +13,12 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.IOException; import java.util.List; public class IncomeReportPanel extends JPanel { + private final User user; public static DefaultTableModel model; DefaultTableCellRenderer centerRenderer; public static JScrollPane jScrollPane; @@ -29,9 +32,11 @@ public class IncomeReportPanel extends JPanel { ExpenserMain expenserMain; GridBagConstraints gbConst; JPanel upperPanel; - JComboBox monthSelector; - public static JComboBox typeSelector; + JComboBox monthSelector; + public static JComboBox typeSelector; + public IncomeReportPanel(User user) { + this.user = user; expenserMain = new ExpenserMain(user); @@ -104,28 +109,7 @@ public IncomeReportPanel(User user) { upperPanel.add(typeSelector,gbConst); applyFilter = new JButton("Filter"); - applyFilter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == applyFilter) { - - List filteredIncome = filterService.filterByMonth(user.getIncome(), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); - filteredIncome = filterService.filterBySource(filteredIncome, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); - - model.setNumRows(filteredIncome.size()); - int i = 0; - double incomeSum = 0.00f; - for(Wage wage : filteredIncome) { - incomeTable.setValueAt(wage.getSource(), i, 0); - incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - incomeTable.setValueAt(wage.getMonth(), i, 2); - ++i; - incomeSum += wage.getAmount(); - } - totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); - } - } - }); + applyFilter.addActionListener(applyFilterAction(filterService)); applyFilter.setFont(new Font(null, Font.PLAIN, 24)); gbConst.gridx = 3; gbConst.gridy = 2; @@ -163,12 +147,7 @@ public boolean isCellEditable(int row, int column) { this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - expenserMain.exportReport("Income Report"); - } - }); + exportReport.addActionListener(exportReportAction()); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -180,4 +159,46 @@ public void actionPerformed(ActionEvent e) { } + public ActionListener exportReportAction() { + return e -> { + ReportService reportService = new ReportService(); + try { + reportService.exportIncomeReport(user, monthSelector.getSelectedItem().toString()); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + }; + } + + public ActionListener applyFilterAction(FilterService filterService) { + return e -> { + if(e.getSource() == applyFilter) { + + List filteredIncome = filterService.filterByMonth(user.getIncome(), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + filteredIncome = filterService.filterBySource(filteredIncome, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); + + model.setNumRows(filteredIncome.size()); + int i = 0; + double incomeSum = 0.00f; + for(Wage wage : filteredIncome) { + incomeTable.setValueAt(wage.getSource(), i, 0); + incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + incomeTable.setValueAt(wage.getMonth(), i, 2); + ++i; + incomeSum += wage.getAmount(); + } + totalFilteredIncomeAmtLbl.setText(String.format("$%.2f",incomeSum)); + } + }; + } + + public void updateSources() { + typeSelector.removeAllItems(); + + for(Object source : new FilterService().getSources(user.getIncome())){ + typeSelector.addItem(source); + } + + } + } From 86daf5ec0a0c427bd7f1e0ba13b8798abfadb041 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:40:04 -0400 Subject: [PATCH 090/123] moving button action into new method --- .../seng210/panels/CreateAccountPanel.java | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java index 562ee9b..7cebdba 100644 --- a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java @@ -5,7 +5,6 @@ import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class CreateAccountPanel extends JPanel { @@ -83,34 +82,36 @@ public CreateAccountPanel() { createAccBtn.setFont(new Font(null, Font.PLAIN, 14)); this.add(createAccBtn, gbConst); - createAccBtn.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (e.getSource() == createAccBtn) { - username = usernameField.getText(); - password = passwordField.getText(); - confPassword = confPasswordField.getText(); - if (!usernameField.getText().isEmpty() && !passwordField.getText().isEmpty() && !confPasswordField.getText().isEmpty()) { - if (confPassword.equals(password)) { - UsernameChecker usernameChecker = new UsernameChecker(); - if (usernameChecker.hasRepeat(usernameField.getText())) { - JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); - } else { - UserCreationService userCreationService = new UserCreationService(); - - userCreationService.create(username, password); - JOptionPane.showMessageDialog(null, "User created successfully."); - usernameField.setText(""); - passwordField.setText(""); - confPasswordField.setText(""); - } + createAccBtn.addActionListener(createAccountAction()); + } + + public ActionListener createAccountAction() { + return e -> { + if (e.getSource() == createAccBtn) { + username = usernameField.getText(); + password = passwordField.getText(); + confPassword = confPasswordField.getText(); + if (!usernameField.getText().isEmpty() && !passwordField.getText().isEmpty() && !confPasswordField.getText().isEmpty()) { + if (confPassword.equals(password)) { + UsernameChecker usernameChecker = new UsernameChecker(); + if (usernameChecker.hasRepeat(usernameField.getText())) { + JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); } else { - JOptionPane.showMessageDialog(null, "Passwords do not match!"); + UserCreationService userCreationService = new UserCreationService(); + + userCreationService.create(username, password); + JOptionPane.showMessageDialog(null, "User created successfully."); + usernameField.setText(""); + passwordField.setText(""); + confPasswordField.setText(""); } } else { - JOptionPane.showMessageDialog(null, "Not all fields filled out. Please fill them out."); + JOptionPane.showMessageDialog(null, "Passwords do not match!"); } + } else { + JOptionPane.showMessageDialog(null, "Not all fields filled out. Please fill them out."); } } - }); + }; } } From 6ff58f007675146f497e484be77258413c0eb89f Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:41:17 -0400 Subject: [PATCH 091/123] moving button action into new method --- .../ferris/seng210/panels/EstimatePanel.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java b/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java index 3814234..1f207b9 100644 --- a/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java +++ b/src/main/java/edu/ferris/seng210/panels/EstimatePanel.java @@ -2,7 +2,6 @@ import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class EstimatePanel extends JPanel { @@ -69,16 +68,7 @@ public EstimatePanel() { this.add(priceField, gbConst); estimateButton = new JButton("Get Estimate"); - estimateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(e.getSource() == estimateButton) { - System.out.println("Get Estimate Button Clicked."); - nameField.setText(""); - priceField.setText(""); - } - } - }); + estimateButton.addActionListener(estimateAction()); estimateButton.setPreferredSize(new Dimension(220, 60)); gbConst.gridx = 0; gbConst.gridy = 4; @@ -88,4 +78,14 @@ public void actionPerformed(ActionEvent e) { this.add(estimateButton, gbConst); } + + public ActionListener estimateAction() { + return e -> { + if(e.getSource() == estimateButton) { + System.out.println("Get Estimate Button Clicked."); + nameField.setText(""); + priceField.setText(""); + } + }; + } } From ce862d1a6f46ccdc88a77ce4b7498e68b148bdb8 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:43:20 -0400 Subject: [PATCH 092/123] moving button actions into new methods --- .../ferris/seng210/panels/ImportPanel.java | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java index 73979c8..8669d79 100644 --- a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java @@ -5,7 +5,6 @@ import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; @@ -39,24 +38,7 @@ public ImportPanel(User user) { this.add(importLbl, gbConst); selectFileButton = new JButton("File"); - selectFileButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() == selectFileButton) { - int userDecision = fileChooser.showOpenDialog(null); - if(userDecision == JFileChooser.APPROVE_OPTION) { - userFile = fileChooser.getSelectedFile(); - if(!userFile.getAbsolutePath().endsWith(".csv")){ - JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); - System.out.println("User selected a non csv file!"); - } - System.out.println("The user selected: " + userFile.getAbsolutePath()); - } else if (userDecision == JFileChooser.CANCEL_OPTION) { - System.out.println("The user canceled the operation."); - } - } - } - }); + selectFileButton.addActionListener(selectFileAction()); selectFileLbl = new JLabel("Select File"); gbConst.gridx = 0; @@ -95,33 +77,7 @@ public void actionPerformed(ActionEvent e) { this.add(descriptionLbl, gbConst); importButton = new JButton("Import"); - importButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { - System.out.println("Income Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadIncomeFile(userFile.getAbsolutePath()); - expenserMain.updateIncomeTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateIncomeValues(); - } - } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { - System.out.println("Expense Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadExpenseFile(userFile.getAbsolutePath()); - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateExpenseValues(); - } - } - - } - }); + importButton.addActionListener(importAction()); gbConst.gridheight = 1; gbConst.gridx = 0; gbConst.gridy = 5; @@ -131,4 +87,48 @@ public void actionPerformed(ActionEvent e) { } + public ActionListener importAction() { + return e -> { + if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { + System.out.println("Income Selected"); + if(userFile == null) { + JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); + } else { + expenserMain.loadIncomeFile(userFile.getAbsolutePath()); + expenserMain.updateIncomeTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateIncomeValues(); + } + } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { + System.out.println("Expense Selected"); + if(userFile == null) { + JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); + } else { + expenserMain.loadExpenseFile(userFile.getAbsolutePath()); + expenserMain.updateExpenseTable(); + expenserMain.updateDetailedTable(); + expenserMain.updateExpenseValues(); + } + } + }; + } + + public ActionListener selectFileAction() { + return e -> { + if (e.getSource() == selectFileButton) { + int userDecision = fileChooser.showOpenDialog(null); + if(userDecision == JFileChooser.APPROVE_OPTION) { + userFile = fileChooser.getSelectedFile(); + if(!userFile.getAbsolutePath().endsWith(".csv")){ + JOptionPane.showMessageDialog(null,"Warning. Only csv files are supported. Select something else.", "Warning!", JOptionPane.ERROR_MESSAGE); + System.out.println("User selected a non csv file!"); + } + System.out.println("The user selected: " + userFile.getAbsolutePath()); + } else if (userDecision == JFileChooser.CANCEL_OPTION) { + System.out.println("The user canceled the operation."); + } + } + }; + } + } From e1b55c02106d264e0244edd514d1da4bc558ce22 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:44:31 -0400 Subject: [PATCH 093/123] moving button action into new method --- .../edu/ferris/seng210/panels/LoginPanel.java | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java index 9dd4fda..20a59e9 100644 --- a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java @@ -5,7 +5,6 @@ import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class LoginPanel extends JPanel { @@ -68,25 +67,27 @@ public LoginPanel() { loginBtn.setPreferredSize(new Dimension(150,60)); this.add(loginBtn, gbConst); - loginBtn.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - String username = usernameIncField.getText(); - String password = passwordIncField.getText(); - - UsernameChecker usernameChecker = new UsernameChecker(); - PasswordChecker passwordChecker = new PasswordChecker(); - - if(usernameChecker.check(username) && passwordChecker.check(username, password)) { - usernameIncField.setText(""); - passwordIncField.setText(""); - System.out.println("Login Successful"); - JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); - } else { - JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); - } - } - }); + loginBtn.addActionListener(loginAction()); + + } + public ActionListener loginAction() { + return e -> { + String username = usernameIncField.getText(); + String password = passwordIncField.getText(); + + UsernameChecker usernameChecker = new UsernameChecker(); + PasswordChecker passwordChecker = new PasswordChecker(); + + if(usernameChecker.check(username) && passwordChecker.check(username, password)) { + usernameIncField.setText(""); + passwordIncField.setText(""); + System.out.println("Login Successful"); + JOptionPane.showMessageDialog(null,"Login Successful. Welcome " + username + "."); + } else { + JOptionPane.showMessageDialog(null,"Incorrect Credentials!"); + } + }; } } From 75c9861a46a11c4c47ed85bc9404567d089382a5 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 17:56:19 -0400 Subject: [PATCH 094/123] making income and expense reports show correct filtered details --- src/main/java/edu/ferris/seng210/ReportService.java | 8 ++------ .../edu/ferris/seng210/panels/ExpenseReportPanel.java | 9 ++++++--- .../edu/ferris/seng210/panels/IncomeReportPanel.java | 9 ++++++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ReportService.java b/src/main/java/edu/ferris/seng210/ReportService.java index 604d5a6..c6a811a 100644 --- a/src/main/java/edu/ferris/seng210/ReportService.java +++ b/src/main/java/edu/ferris/seng210/ReportService.java @@ -13,7 +13,7 @@ public class ReportService { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss-MM-dd-yyyy"); - public void exportExpenseReport(User user, int frequency) throws IOException { + public void exportExpenseReport(User user, List filteredExpenses) throws IOException { String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); FilterService filterService = new FilterService<>(); File file = new File(fileName); @@ -29,15 +29,13 @@ public void exportExpenseReport(User user, int frequency) throws IOException { printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); printWriter.println("Source,Amount,Frequency"); - List filteredExpenses = filterService.filterByFrequency(user.getExpenses(), frequency); - for (Expense expense : filteredExpenses) { printWriter.printf("%s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); } } } - public void exportIncomeReport(User user, String month) throws IOException { + public void exportIncomeReport(User user, List filteredIncome) throws IOException { String fileName = String.format("income-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); FilterService filterService = new FilterService<>(); File file = new File(fileName); @@ -52,8 +50,6 @@ public void exportIncomeReport(User user, String month) throws IOException { printWriter.printf("Filtered Income, %f\n", user.getMonthlySavings()); printWriter.println("Source,Amount,Frequency"); - List filteredIncome = filterService.filterByMonth(user.getIncome(), month); - for (Wage wage : filteredIncome) { printWriter.printf("%s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.getMonth()); } diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index 61fb27c..e7bf7e1 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -141,7 +141,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(exportToCsvAction()); + exportReport.addActionListener(exportToCsvAction(filterService)); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -161,12 +161,15 @@ public void updateSources() { } } - public ActionListener exportToCsvAction() { + public ActionListener exportToCsvAction(FilterService filterService) { return e -> { if(e.getSource() == exportReport) { ReportService reportService = new ReportService(); try { - reportService.exportExpenseReport(user, Integer.parseInt(frequencySelector.getSelectedItem().toString())); + List filteredSpending = filterService.filterByFrequency(user.getExpenses(), Integer.parseInt(frequencySelector.getSelectedItem().toString())); + filteredSpending = filterService.filterBySource(filteredSpending, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); + + reportService.exportExpenseReport(user, filteredSpending); } catch (IOException ex) { throw new RuntimeException(ex); } diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java index be11118..b05e231 100644 --- a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -147,7 +147,7 @@ public boolean isCellEditable(int row, int column) { this.add(jScrollPane, BorderLayout.CENTER); exportReport = new JButton("Export to CSV"); - exportReport.addActionListener(exportReportAction()); + exportReport.addActionListener(exportReportAction(filterService)); exportReport.setSize(new Dimension(200,60)); exportReport.setFont(new Font(null, Font.PLAIN, 24)); @@ -159,11 +159,14 @@ public boolean isCellEditable(int row, int column) { } - public ActionListener exportReportAction() { + public ActionListener exportReportAction(FilterService filterService) { return e -> { ReportService reportService = new ReportService(); try { - reportService.exportIncomeReport(user, monthSelector.getSelectedItem().toString()); + List filteredIncome = filterService.filterByMonth(user.getIncome(), (String)monthSelector.getItemAt(monthSelector.getSelectedIndex())); + filteredIncome = filterService.filterBySource(filteredIncome, (String)typeSelector.getItemAt(typeSelector.getSelectedIndex())); + + reportService.exportIncomeReport(user, filteredIncome); } catch (IOException ex) { throw new RuntimeException(ex); } From efb2767abc184915e233dd8febc21e5fb98b039d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 18:16:55 -0400 Subject: [PATCH 095/123] reduced menu action handling to one extensible method --- .../java/edu/ferris/seng210/AppFrame.java | 189 +++--------------- 1 file changed, 31 insertions(+), 158 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/AppFrame.java b/src/main/java/edu/ferris/seng210/AppFrame.java index 4509c79..00abab2 100644 --- a/src/main/java/edu/ferris/seng210/AppFrame.java +++ b/src/main/java/edu/ferris/seng210/AppFrame.java @@ -25,7 +25,7 @@ public class AppFrame extends JFrame { LoginPanel loginPanel = new LoginPanel(); CreateAccountPanel createAccountPanel = new CreateAccountPanel(); - HomePanel homePanel = new HomePanel(); + HomePanel homePanel = new HomePanel(user); ImportPanel importPanel = new ImportPanel(user); EstimatePanel estimatePanel = new EstimatePanel(); IncomeReportPanel incomeReportPanel = new IncomeReportPanel(user); @@ -36,179 +36,31 @@ public class AppFrame extends JFrame { navMenuBar = new JMenuBar(); navMenu = new JMenu("

Menu"); // Menu homeNav = new JMenuItem("

Home"); // Home Page - homeNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(homePanel); - revalidate(); - repaint(); - } + homeNav.addMouseListener(handleMenuClickAction(homePanel)); - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); addItemNav = new JMenuItem("

Add Item"); // Add Items Page - addItemNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(addItemPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); + addItemNav.addMouseListener(handleMenuClickAction(addItemPanel)); importNav = new JMenuItem("

Import Tool"); // Import Page - importNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - super.mouseClicked(e); - getContentPane().removeAll(); - revalidate(); - repaint(); - getContentPane().add(importPanel); - } + importNav.addMouseListener(handleMenuClickAction(importPanel)); - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page - estimateNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { + estimateNav.addMouseListener(handleMenuClickAction(estimatePanel)); - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(estimatePanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); incomeReportNav = new JMenuItem("

Income Report"); - incomeReportNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { + incomeReportNav.addMouseListener(handleMenuClickAction(incomeReportPanel)); - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(incomeReportPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); expenseReportNav = new JMenuItem("

Expense Report"); - expenseReportNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { + expenseReportNav.addMouseListener(handleMenuClickAction(expenseReportPanel)); - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(expenseReportPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); detailedReportNav = new JMenuItem("

Detailed Report"); - detailedReportNav.addMouseListener(new MouseAdapter() { - - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(detailedReportPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); + detailedReportNav.addMouseListener(handleMenuClickAction(detailedReportPanel)); loginNav = new JMenuItem("

Login"); // Add Items Page - loginNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(loginPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); + loginNav.addMouseListener(handleMenuClickAction(loginPanel)); createAccNav = new JMenuItem("

Create Account"); // Add Items Page - createAccNav.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - - super.mouseClicked(e); - getContentPane().removeAll(); - getContentPane().add(createAccountPanel); - revalidate(); - repaint(); - } - - @Override - public void mouseReleased(MouseEvent e) { - super.mouseReleased(e); - revalidate(); - repaint(); - } - }); + createAccNav.addMouseListener(handleMenuClickAction(createAccountPanel)); navMenu.setFont(new Font(null, Font.PLAIN, 24)); homeNav.setFont(new Font(null, Font.PLAIN, 20)); @@ -239,4 +91,25 @@ public void mouseReleased(MouseEvent e) { this.setVisible(true); } + public MouseAdapter handleMenuClickAction(JComponent component) { + return new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + + super.mouseClicked(e); + getContentPane().removeAll(); + getContentPane().add(component); + revalidate(); + repaint(); + } + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + revalidate(); + repaint(); + } + }; + } + } From 45b84416f074fd5856af08b785c130484d19cc8d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 18:17:47 -0400 Subject: [PATCH 096/123] renaming monthlySavings to totalIncome to reflect usage better. --- .../java/edu/ferris/seng210/account/User.java | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/account/User.java b/src/main/java/edu/ferris/seng210/account/User.java index 2c24d4e..954f1c7 100644 --- a/src/main/java/edu/ferris/seng210/account/User.java +++ b/src/main/java/edu/ferris/seng210/account/User.java @@ -14,7 +14,7 @@ public class User { private String username; private String pwd; private double balance; - private double monthlySavings; + private double totalIncome; private double totalExpenses; public User(String username, String password){ @@ -70,12 +70,24 @@ public double getTotalExpenses() { return this.totalExpenses; } - public double getMonthlySavings() { - return this.monthlySavings; + public double getTotalIncome() { + return this.totalIncome; } - public void setMonthlySavings(double monthlySavings) { - this.monthlySavings = monthlySavings; + public void setTotalIncome(double totalIncome) { + this.totalIncome = totalIncome; + } + + public void updateIncomeTotal() { + totalIncome = income.stream().map(Wage::getAmount).reduce(0D, Double::sum); + } + + public void updateExpenseTotal() { + totalExpenses = expenses.stream().map(Expense::getAmount).reduce(0D, Double::sum); + } + + public void updateBalance() { + balance = totalIncome - totalExpenses; } } From 906dd187a2e24b3b87603e65102d4fe94e1bffcc Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 18:23:05 -0400 Subject: [PATCH 097/123] fixing reporting user method calls and filtered balance display --- .../java/edu/ferris/seng210/ReportService.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/ReportService.java b/src/main/java/edu/ferris/seng210/ReportService.java index c6a811a..88a8e3e 100644 --- a/src/main/java/edu/ferris/seng210/ReportService.java +++ b/src/main/java/edu/ferris/seng210/ReportService.java @@ -15,18 +15,19 @@ public class ReportService { public void exportExpenseReport(User user, List filteredExpenses) throws IOException { String fileName = String.format("expense-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); - FilterService filterService = new FilterService<>(); File file = new File(fileName); + double filteredTotal = new TotalingService().getTotal(filteredExpenses); + if (!file.exists()) { file.createNewFile(); } try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { - printWriter.printf("Total Income, %f\n", user.getBalance()); + printWriter.printf("Total Income, %f\n", user.getTotalIncome()); printWriter.printf("Total Expense, %f\n", user.getTotalExpenses()); - printWriter.printf("Filtered Expenses, %f\n", user.getTotalExpenses()); - printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); + printWriter.printf("Filtered Expenses, %f\n", filteredTotal); + printWriter.printf("Total Savings, %f\n", user.getBalance()); printWriter.println("Source,Amount,Frequency"); for (Expense expense : filteredExpenses) { @@ -37,17 +38,18 @@ public void exportExpenseReport(User user, List filteredExpenses) throw public void exportIncomeReport(User user, List filteredIncome) throws IOException { String fileName = String.format("income-report-%s.csv", LocalDateTime.now().format(dateTimeFormatter)); - FilterService filterService = new FilterService<>(); File file = new File(fileName); + double filteredTotal = new TotalingService().getTotal(filteredIncome); + if (!file.exists()) { file.createNewFile(); } try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { - printWriter.printf("Total Income, %f\n", user.getBalance()); + printWriter.printf("Total Income, %f\n", user.getTotalIncome()); printWriter.printf("Total Expense, %f\n", user.getTotalExpenses()); - printWriter.printf("Filtered Income, %f\n", user.getMonthlySavings()); + printWriter.printf("Filtered Income, %f\n", filteredTotal); printWriter.println("Source,Amount,Frequency"); for (Wage wage : filteredIncome) { @@ -67,7 +69,7 @@ public void exportDetailedReport(User user) throws IOException { try (PrintWriter printWriter = new PrintWriter(new FileOutputStream(file))) { printWriter.printf("Total Income, %f\n", user.getBalance()); printWriter.printf("Total Expense, %f\n", user.getTotalExpenses()); - printWriter.printf("Total Savings, %f\n", user.getMonthlySavings()); + printWriter.printf("Total Savings, %f\n", user.getTotalIncome()); printWriter.println("Type,Source,Amount,Frequency / Month"); for (Wage wage : user.getIncome()) { From 61af891aa722a3bac8a0533a95de0f46c5f464cb Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:13:02 -0400 Subject: [PATCH 098/123] converting to a record --- .../java/edu/ferris/seng210/Currency.java | 7 ----- .../edu/ferris/seng210/records/Currency.java | 4 +++ .../edu/ferris/seng210/records/Expense.java | 16 +++++++++++ .../java/edu/ferris/seng210/records/Wage.java | 16 +++++++++++ .../ferris/seng210/transactions/Expense.java | 28 ------------------- .../edu/ferris/seng210/transactions/Wage.java | 27 ------------------ 6 files changed, 36 insertions(+), 62 deletions(-) delete mode 100644 src/main/java/edu/ferris/seng210/Currency.java create mode 100644 src/main/java/edu/ferris/seng210/records/Currency.java create mode 100644 src/main/java/edu/ferris/seng210/records/Expense.java create mode 100644 src/main/java/edu/ferris/seng210/records/Wage.java delete mode 100644 src/main/java/edu/ferris/seng210/transactions/Expense.java delete mode 100644 src/main/java/edu/ferris/seng210/transactions/Wage.java diff --git a/src/main/java/edu/ferris/seng210/Currency.java b/src/main/java/edu/ferris/seng210/Currency.java deleted file mode 100644 index c98f091..0000000 --- a/src/main/java/edu/ferris/seng210/Currency.java +++ /dev/null @@ -1,7 +0,0 @@ -package edu.ferris.seng210; - -public class Currency { - public double rate; - public String name; - -} diff --git a/src/main/java/edu/ferris/seng210/records/Currency.java b/src/main/java/edu/ferris/seng210/records/Currency.java new file mode 100644 index 0000000..4d14226 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/records/Currency.java @@ -0,0 +1,4 @@ +package edu.ferris.seng210.records; + +public record Currency(double rate, String name) { +} diff --git a/src/main/java/edu/ferris/seng210/records/Expense.java b/src/main/java/edu/ferris/seng210/records/Expense.java new file mode 100644 index 0000000..2f9b3dd --- /dev/null +++ b/src/main/java/edu/ferris/seng210/records/Expense.java @@ -0,0 +1,16 @@ +package edu.ferris.seng210.records; + +import edu.ferris.seng210.interfaces.Transaction; + +public record Expense(String source, double amount, int yearlyFrequency) implements Transaction { + + @Override + public String getSource() { + return this.source; + } + + @Override + public double getAmount() { + return this.amount; + } +} diff --git a/src/main/java/edu/ferris/seng210/records/Wage.java b/src/main/java/edu/ferris/seng210/records/Wage.java new file mode 100644 index 0000000..ed056b1 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/records/Wage.java @@ -0,0 +1,16 @@ +package edu.ferris.seng210.records; + +import edu.ferris.seng210.interfaces.Transaction; + +public record Wage(String source, double amount, String month) implements Transaction { + + @Override + public String getSource() { + return this.source; + } + + @Override + public double getAmount() { + return this.amount; + } +} diff --git a/src/main/java/edu/ferris/seng210/transactions/Expense.java b/src/main/java/edu/ferris/seng210/transactions/Expense.java deleted file mode 100644 index a677024..0000000 --- a/src/main/java/edu/ferris/seng210/transactions/Expense.java +++ /dev/null @@ -1,28 +0,0 @@ -package edu.ferris.seng210.transactions; - -public class Expense implements Transaction{ - private final String source; - private final double amount; - private final int yearlyFrequency; - - public Expense(String source, double amount, int yearlyFrequency) { - this.source = source; - this.amount = amount; - this.yearlyFrequency = yearlyFrequency; - } - - @Override - public String getSource() { - return this.source; - } - - @Override - public double getAmount() { - return this.amount; - } - - public int getFrequency() { - return this.yearlyFrequency; - } - -} diff --git a/src/main/java/edu/ferris/seng210/transactions/Wage.java b/src/main/java/edu/ferris/seng210/transactions/Wage.java deleted file mode 100644 index db4c90b..0000000 --- a/src/main/java/edu/ferris/seng210/transactions/Wage.java +++ /dev/null @@ -1,27 +0,0 @@ -package edu.ferris.seng210.transactions; - -public class Wage implements Transaction { - private final String source; - private final double amount; - private final String Month; - - public Wage(String source, double amount, String Month) { - this.source = source; - this.amount = amount; - this.Month = Month; - } - - @Override - public String getSource() { - return this.source; - } - - @Override - public double getAmount() { - return this.amount; - } - - public String getMonth() { - return this.Month; - } -} From 8387c9248ee5ef263ca8556e418911fbc3f9d979 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:13:38 -0400 Subject: [PATCH 099/123] adjusting to use records for Currency, Wage, and Expense --- src/main/java/edu/ferris/seng210/account/User.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/account/User.java b/src/main/java/edu/ferris/seng210/account/User.java index 954f1c7..d9af3c9 100644 --- a/src/main/java/edu/ferris/seng210/account/User.java +++ b/src/main/java/edu/ferris/seng210/account/User.java @@ -1,8 +1,8 @@ package edu.ferris.seng210.account; -import edu.ferris.seng210.Currency; -import edu.ferris.seng210.transactions.Expense; -import edu.ferris.seng210.transactions.Wage; +import edu.ferris.seng210.records.Currency; +import edu.ferris.seng210.records.Expense; +import edu.ferris.seng210.records.Wage; import java.util.ArrayList; import java.util.List; From 15d522ac737a980a963f1c1d45eeecd383acdd68 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:14:18 -0400 Subject: [PATCH 100/123] moving files and adjusting to use records --- .../{transactions => interfaces}/Transaction.java | 3 +-- .../seng210/{ => services}/FilterService.java | 12 ++++++------ .../seng210/{ => services}/ReportService.java | 14 +++++++------- .../seng210/{ => services}/TotalingService.java | 4 ++-- .../{ => services}/UserCreationService.java | 3 ++- 5 files changed, 18 insertions(+), 18 deletions(-) rename src/main/java/edu/ferris/seng210/{transactions => interfaces}/Transaction.java (66%) rename src/main/java/edu/ferris/seng210/{ => services}/FilterService.java (70%) rename src/main/java/edu/ferris/seng210/{ => services}/ReportService.java (90%) rename src/main/java/edu/ferris/seng210/{ => services}/TotalingService.java (74%) rename src/main/java/edu/ferris/seng210/{ => services}/UserCreationService.java (94%) diff --git a/src/main/java/edu/ferris/seng210/transactions/Transaction.java b/src/main/java/edu/ferris/seng210/interfaces/Transaction.java similarity index 66% rename from src/main/java/edu/ferris/seng210/transactions/Transaction.java rename to src/main/java/edu/ferris/seng210/interfaces/Transaction.java index 696ebd2..596867f 100644 --- a/src/main/java/edu/ferris/seng210/transactions/Transaction.java +++ b/src/main/java/edu/ferris/seng210/interfaces/Transaction.java @@ -1,7 +1,6 @@ -package edu.ferris.seng210.transactions; +package edu.ferris.seng210.interfaces; public interface Transaction { - String getSource(); double getAmount(); } diff --git a/src/main/java/edu/ferris/seng210/FilterService.java b/src/main/java/edu/ferris/seng210/services/FilterService.java similarity index 70% rename from src/main/java/edu/ferris/seng210/FilterService.java rename to src/main/java/edu/ferris/seng210/services/FilterService.java index f31e763..8c4b641 100644 --- a/src/main/java/edu/ferris/seng210/FilterService.java +++ b/src/main/java/edu/ferris/seng210/services/FilterService.java @@ -1,8 +1,8 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.services; -import edu.ferris.seng210.transactions.Expense; -import edu.ferris.seng210.transactions.Transaction; -import edu.ferris.seng210.transactions.Wage; +import edu.ferris.seng210.records.Expense; +import edu.ferris.seng210.interfaces.Transaction; +import edu.ferris.seng210.records.Wage; import java.util.List; @@ -16,13 +16,13 @@ public List filterBySource(List transactions, String source) { public List filterByFrequency(List transactions, int frequency) { return transactions.stream() - .filter(transaction -> transaction.getFrequency() == frequency) + .filter(transaction -> transaction.yearlyFrequency() == frequency) .toList(); } public List filterByMonth(List transactions, String month) { return transactions.stream() - .filter(transaction -> transaction.getMonth().equalsIgnoreCase(month)) + .filter(transaction -> transaction.month().equalsIgnoreCase(month)) .toList(); } diff --git a/src/main/java/edu/ferris/seng210/ReportService.java b/src/main/java/edu/ferris/seng210/services/ReportService.java similarity index 90% rename from src/main/java/edu/ferris/seng210/ReportService.java rename to src/main/java/edu/ferris/seng210/services/ReportService.java index 88a8e3e..05cc914 100644 --- a/src/main/java/edu/ferris/seng210/ReportService.java +++ b/src/main/java/edu/ferris/seng210/services/ReportService.java @@ -1,8 +1,8 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.services; import edu.ferris.seng210.account.User; -import edu.ferris.seng210.transactions.Expense; -import edu.ferris.seng210.transactions.Wage; +import edu.ferris.seng210.records.Expense; +import edu.ferris.seng210.records.Wage; import java.io.*; import java.time.LocalDateTime; @@ -31,7 +31,7 @@ public void exportExpenseReport(User user, List filteredExpenses) throw printWriter.println("Source,Amount,Frequency"); for (Expense expense : filteredExpenses) { - printWriter.printf("%s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); + printWriter.printf("%s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.yearlyFrequency()); } } } @@ -53,7 +53,7 @@ public void exportIncomeReport(User user, List filteredIncome) throws IOEx printWriter.println("Source,Amount,Frequency"); for (Wage wage : filteredIncome) { - printWriter.printf("%s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.getMonth()); + printWriter.printf("%s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.month()); } } } @@ -73,11 +73,11 @@ public void exportDetailedReport(User user) throws IOException { printWriter.println("Type,Source,Amount,Frequency / Month"); for (Wage wage : user.getIncome()) { - printWriter.printf("Income, %s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.getMonth()); + printWriter.printf("Income, %s, %f, %s\n", wage.getSource(), wage.getAmount(), wage.month()); } for (Expense expense : user.getExpenses()) { - printWriter.printf("Income, %s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.getFrequency()); + printWriter.printf("Income, %s, %f, %d\n", expense.getSource(), expense.getAmount(), expense.yearlyFrequency()); } } } diff --git a/src/main/java/edu/ferris/seng210/TotalingService.java b/src/main/java/edu/ferris/seng210/services/TotalingService.java similarity index 74% rename from src/main/java/edu/ferris/seng210/TotalingService.java rename to src/main/java/edu/ferris/seng210/services/TotalingService.java index eea530a..46c26dd 100644 --- a/src/main/java/edu/ferris/seng210/TotalingService.java +++ b/src/main/java/edu/ferris/seng210/services/TotalingService.java @@ -1,6 +1,6 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.services; -import edu.ferris.seng210.transactions.Transaction; +import edu.ferris.seng210.interfaces.Transaction; import java.util.List; diff --git a/src/main/java/edu/ferris/seng210/UserCreationService.java b/src/main/java/edu/ferris/seng210/services/UserCreationService.java similarity index 94% rename from src/main/java/edu/ferris/seng210/UserCreationService.java rename to src/main/java/edu/ferris/seng210/services/UserCreationService.java index 3ba8e65..b432305 100644 --- a/src/main/java/edu/ferris/seng210/UserCreationService.java +++ b/src/main/java/edu/ferris/seng210/services/UserCreationService.java @@ -1,5 +1,6 @@ -package edu.ferris.seng210; +package edu.ferris.seng210.services; +import edu.ferris.seng210.EWalletApp; import edu.ferris.seng210.account.User; import edu.ferris.seng210.checker.PasswordComplexityChecker; import edu.ferris.seng210.checker.UsernameChecker; From e3341d2559245b8ac1c926fb188ebb2439d486bd Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:14:59 -0400 Subject: [PATCH 101/123] renaming and moving methods from ExpenserMain --- .../java/edu/ferris/seng210/ExpenserMain.java | 301 ------------------ .../services/DisplayUpdateService.java | 82 +++++ 2 files changed, 82 insertions(+), 301 deletions(-) delete mode 100644 src/main/java/edu/ferris/seng210/ExpenserMain.java create mode 100644 src/main/java/edu/ferris/seng210/services/DisplayUpdateService.java diff --git a/src/main/java/edu/ferris/seng210/ExpenserMain.java b/src/main/java/edu/ferris/seng210/ExpenserMain.java deleted file mode 100644 index 493f112..0000000 --- a/src/main/java/edu/ferris/seng210/ExpenserMain.java +++ /dev/null @@ -1,301 +0,0 @@ -package edu.ferris.seng210; - -import edu.ferris.seng210.account.User; -import edu.ferris.seng210.panels.DetailedReportPanel; -import edu.ferris.seng210.panels.ExpenseReportPanel; -import edu.ferris.seng210.panels.HomePanel; -import edu.ferris.seng210.panels.IncomeReportPanel; -import edu.ferris.seng210.transactions.Expense; -import edu.ferris.seng210.transactions.Wage; - -import java.io.*; - -public class ExpenserMain implements Expenser { - - private final User user; - - public ExpenserMain(User user) { - this.user = user; - } - - @Override - public void addExpense (Expense expense) { - user.addExpense(expense); - } - - @Override - public void addMonthlyIncome (Wage wage) { - user.addMonthlyIncome(wage); - } - - @Override - public void PrintFullreport() { - } - - @Override - public void PrintExpensereport() { - } - - @Override - public void PrintIncomereport() { - } - - @Override - public void PrintIncomereportbyTpe() { - } - - @Override - public void PrintExpensebyType() { - } - - @Override - public void exportReport(String reportTitle) { - - } - - @Override - public Currency convertForeignCurrency(Currency C, double amount) { - return null; - } - - @Override - public boolean loadExpenseFile(String filePath) { - // Initialization - String lineText = ""; - BufferedReader bufferedLineReader = null; - BufferedReader bufferedTextReader = null; - File userFile = new File(filePath); - String source = "", frequency = "", amount = ""; - - try { - int linesInFile = 0; - bufferedLineReader = new BufferedReader(new FileReader(userFile)); - bufferedTextReader = new BufferedReader(new FileReader(userFile)); - while (bufferedLineReader.readLine() != null) { // count lines in file - linesInFile++; - } - Expense expense; - for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { - lineText = bufferedTextReader.readLine(); - if(lineIndex == 0 && lineText.trim().equals("source,amount,frequency")) { - System.out.println("File start setup correctly."); - } - else if (lineIndex > 0){ - source = ""; - frequency = ""; - amount = ""; - - for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { - source += lineText.charAt(sourceIndex); - } - for(int amountIndex = lineText.indexOf(',') + 1; amountIndex < lineText.lastIndexOf(','); amountIndex++) { - amount += lineText.charAt(amountIndex); - } - for(int freqIndex = lineText.lastIndexOf(',') + 1; freqIndex < lineText.length(); freqIndex++) { - frequency += lineText.charAt(freqIndex); - } - - System.out.println("Text read: " + source + "," + amount + "," + frequency); - - expense = new Expense(source,Double.parseDouble(amount),Integer.valueOf(frequency)); - - user.setTotalExpenses(user.getTotalExpenses() + expense.getAmount()); - addExpense(expense); - - if(ExpenseReportPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < ExpenseReportPanel.typeSelector.getItemCount(); i++) { - if (ExpenseReportPanel.typeSelector.getItemAt(i).equals(expense.getSource())) { - contains = true; - } - } - if (!contains) { - ExpenseReportPanel.typeSelector.addItem(expense.getSource()); - } - } else { - ExpenseReportPanel.typeSelector.addItem(expense.getSource()); - } - - } - } - } catch (FileNotFoundException e) { - return false; - } catch (IOException e) { - return false; - } - return true; - } - - @Override - public boolean loadIncomeFile(String filePath) { - - // Initialization - String lineText = ""; - BufferedReader bufferedLineReader = null; - BufferedReader bufferedTextReader = null; - File userFile = new File(filePath); - String source = "", month = "", amount = ""; - - - try { - int linesInFile = 0; - bufferedLineReader = new BufferedReader(new FileReader(userFile)); - bufferedTextReader = new BufferedReader(new FileReader(userFile)); - while (bufferedLineReader.readLine() != null) { // count lines in file - linesInFile++; - } - Wage wage; - for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { - lineText = bufferedTextReader.readLine(); - if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { - System.out.println("File start setup correctly."); - } - else { - source = ""; - month = ""; - amount = ""; - - for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { - source += lineText.charAt(sourceIndex); - } - - for(int amountindex = lineText.indexOf(',') + 1; amountindex < lineText.lastIndexOf(','); amountindex++) { - amount += lineText.charAt(amountindex); - } - for(int monthIndex = lineText.lastIndexOf(',') + 1; monthIndex < lineText.length(); monthIndex++) { - month += lineText.charAt(monthIndex); - } - - System.out.println("Text read: " + source + "," + amount + "," + month); - - wage = new Wage(source,Double.parseDouble(amount),month); - - user.setBalance(user.getBalance() + wage.getAmount()); - addMonthlyIncome(wage); - - if(IncomeReportPanel.typeSelector.getItemCount() > 0) { - boolean contains = false; - for (int i = 0; i < IncomeReportPanel.typeSelector.getItemCount(); i++) { - if (IncomeReportPanel.typeSelector.getItemAt(i).equals(wage.getSource())) { - contains = true; - } - } - if (!contains) { - IncomeReportPanel.typeSelector.addItem(wage.getSource()); - } - } else { - IncomeReportPanel.typeSelector.addItem(wage.getSource()); - } - - } - } - } catch (FileNotFoundException e) { - return false; - } catch (IOException e) { - return false; - } - return true; - } - - @Override - public int whenCanIBuy(String itemname, double price) { - return 0; - } - - @Override - public void updateMonthlySavings() { - user.setMonthlySavings(user.getBalance() - user.getTotalExpenses()); - } - - public void updateIncomeTable() { - - IncomeReportPanel.model.setNumRows(0); - - for(int j = 0; j < user.getIncome().size(); j++ ) { - IncomeReportPanel.model.addRow(new Object[]{}); - } - - user.setBalance(0.00f); - - int i = 0; - for(Wage wage : user.getIncome()) { - user.setBalance(user.getBalance() + wage.getAmount()); - IncomeReportPanel.incomeTable.setValueAt(wage.getSource(), i, 0); - IncomeReportPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - IncomeReportPanel.incomeTable.setValueAt(wage.getMonth(), i, 2); - ++i; - } - } - - public void updateDetailedTable() { - DetailedReportPanel.model.setNumRows(0); - - for(int j = 0; j < user.getIncome().size() + user.getExpenses().size(); j++ ) { - DetailedReportPanel.model.addRow(new Object[]{}); - } - - int i = 0; - for(Wage wage : user.getIncome()) { - DetailedReportPanel.detailedTable.setValueAt("Income", i, 0); - DetailedReportPanel.detailedTable.setValueAt(wage.getSource(), i, 1); - DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); - DetailedReportPanel.detailedTable.setValueAt(wage.getMonth(), i, 3); - ++i; - } - - for(Expense expense : user.getExpenses()) { - DetailedReportPanel.detailedTable.setValueAt("Expense", i, 0); - DetailedReportPanel.detailedTable.setValueAt(expense.getSource(), i, 1); - DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); - DetailedReportPanel.detailedTable.setValueAt(expense.getFrequency(), i, 3); - ++i; - } - - } - - public void updateExpenseTable() { - - ExpenseReportPanel.model.setNumRows(0); - - for(int j = 0; j < user.getExpenses().size(); j++ ) { - ExpenseReportPanel.model.addRow(new Object[]{}); - } - - user.setTotalExpenses(0.00f); - int i = 0; - for(Expense expense : user.getExpenses()) { - user.setTotalExpenses(user.getTotalExpenses() + expense.getAmount()); - ExpenseReportPanel.spendingTable.setValueAt(expense.getSource(), i, 0); - ExpenseReportPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); - ExpenseReportPanel.spendingTable.setValueAt(expense.getFrequency(), i, 2); - ++i; - } - } - - public void updateIncomeValues() { - double expenseTotal = new TotalingService().getTotal(user.getExpenses()); - double wageTotal = new TotalingService().getTotal(user.getIncome()); - - user.setTotalExpenses(expenseTotal); - user.setBalance(wageTotal); - - updateMonthlySavings(); - IncomeReportPanel.totalIncomeAmtLbl.setText(String.format("$%.2f", wageTotal)); - HomePanel.totalIncomeAmtLbl.setText(String.format("$%.2f",user.getBalance())); - HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", user.getMonthlySavings())); - } - - public void updateExpenseValues() { - double expenseTotal = new TotalingService().getTotal(user.getExpenses()); - double wageTotal = new TotalingService().getTotal(user.getIncome()); - - user.setTotalExpenses(expenseTotal); - user.setBalance(wageTotal); - - updateMonthlySavings(); - ExpenseReportPanel.totalExpenseAmtLbl.setText(String.format("$%.2f",expenseTotal)); - HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f", expenseTotal)); - HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", user.getMonthlySavings())); - } - -} diff --git a/src/main/java/edu/ferris/seng210/services/DisplayUpdateService.java b/src/main/java/edu/ferris/seng210/services/DisplayUpdateService.java new file mode 100644 index 0000000..0998d3a --- /dev/null +++ b/src/main/java/edu/ferris/seng210/services/DisplayUpdateService.java @@ -0,0 +1,82 @@ +package edu.ferris.seng210.services; + +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.panels.DetailedReportPanel; +import edu.ferris.seng210.panels.ExpenseReportPanel; +import edu.ferris.seng210.panels.IncomeReportPanel; +import edu.ferris.seng210.records.Expense; +import edu.ferris.seng210.records.Wage; + +public class DisplayUpdateService { + + private final User user; + + public DisplayUpdateService(User user) { + this.user = user; + } + + public void updateIncomeTable() { + + IncomeReportPanel.model.setNumRows(0); + + for(int j = 0; j < user.getIncome().size(); j++ ) { + IncomeReportPanel.model.addRow(new Object[]{}); + } + + user.setBalance(0.00f); + + int i = 0; + for(Wage wage : user.getIncome()) { + user.setBalance(user.getBalance() + wage.getAmount()); + IncomeReportPanel.incomeTable.setValueAt(wage.getSource(), i, 0); + IncomeReportPanel.incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); + IncomeReportPanel.incomeTable.setValueAt(wage.month(), i, 2); + ++i; + } + } + + public void updateDetailedTable() { + DetailedReportPanel.model.setNumRows(0); + + for(int j = 0; j < user.getIncome().size() + user.getExpenses().size(); j++ ) { + DetailedReportPanel.model.addRow(new Object[]{}); + } + + int i = 0; + for(Wage wage : user.getIncome()) { + DetailedReportPanel.detailedTable.setValueAt("Income", i, 0); + DetailedReportPanel.detailedTable.setValueAt(wage.getSource(), i, 1); + DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 2); + DetailedReportPanel.detailedTable.setValueAt(wage.month(), i, 3); + ++i; + } + + for(Expense expense : user.getExpenses()) { + DetailedReportPanel.detailedTable.setValueAt("Expense", i, 0); + DetailedReportPanel.detailedTable.setValueAt(expense.getSource(), i, 1); + DetailedReportPanel.detailedTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 2); + DetailedReportPanel.detailedTable.setValueAt(expense.yearlyFrequency(), i, 3); + ++i; + } + + } + + public void updateExpenseTable() { + + ExpenseReportPanel.model.setNumRows(0); + + for(int j = 0; j < user.getExpenses().size(); j++ ) { + ExpenseReportPanel.model.addRow(new Object[]{}); + } + + user.setTotalExpenses(0.00f); + int i = 0; + for(Expense expense : user.getExpenses()) { + user.setTotalExpenses(user.getTotalExpenses() + expense.getAmount()); + ExpenseReportPanel.spendingTable.setValueAt(expense.getSource(), i, 0); + ExpenseReportPanel.spendingTable.setValueAt(String.format("$%.2f",expense.getAmount()), i, 1); + ExpenseReportPanel.spendingTable.setValueAt(expense.yearlyFrequency(), i, 2); + ++i; + } + } +} From 2c6edd6ebb5646d938f0f8f9d57139371b9f92b2 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:15:24 -0400 Subject: [PATCH 102/123] Removing unused interface Expenser --- .../java/edu/ferris/seng210/Expenser.java | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/main/java/edu/ferris/seng210/Expenser.java diff --git a/src/main/java/edu/ferris/seng210/Expenser.java b/src/main/java/edu/ferris/seng210/Expenser.java deleted file mode 100644 index 4f6fc35..0000000 --- a/src/main/java/edu/ferris/seng210/Expenser.java +++ /dev/null @@ -1,20 +0,0 @@ -package edu.ferris.seng210; - -import edu.ferris.seng210.transactions.Expense; -import edu.ferris.seng210.transactions.Wage; - -public interface Expenser { - void addExpense (Expense expense); - void addMonthlyIncome (Wage wage); - void PrintFullreport(); - void PrintExpensereport(); - void PrintIncomereport(); - void PrintIncomereportbyTpe(); - void PrintExpensebyType(); - void exportReport(String reportTitle); - Currency convertForeignCurrency(Currency currency, double amount); - boolean loadExpenseFile(String filePath); - boolean loadIncomeFile(String filePath); - int whenCanIBuy(String itemName,double price); - void updateMonthlySavings(); -} From ec2208df0e7ebeeae81dedefef1578206ba6a4af Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:15:40 -0400 Subject: [PATCH 103/123] adding method to update home panel totals --- .../java/edu/ferris/seng210/panels/HomePanel.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/HomePanel.java b/src/main/java/edu/ferris/seng210/panels/HomePanel.java index c5908ff..e57d5a9 100644 --- a/src/main/java/edu/ferris/seng210/panels/HomePanel.java +++ b/src/main/java/edu/ferris/seng210/panels/HomePanel.java @@ -1,15 +1,17 @@ package edu.ferris.seng210.panels; +import edu.ferris.seng210.account.User; + import javax.swing.*; import java.awt.*; public class HomePanel extends JPanel { - + private final User user; JLabel summaryTxt, totalIncomeLbl ,totalExpensesLbl, totalSavingsLbl; public static JLabel totalExpensesAmtLbl, totalSavingsAmtLbl, totalIncomeAmtLbl; GridBagConstraints gbConst; - public HomePanel() { - + public HomePanel(User user) { + this.user = user; summaryTxt = new JLabel("User Summary"); totalIncomeLbl = new JLabel("Total Income: "); totalIncomeAmtLbl = new JLabel("$0.00"); @@ -65,4 +67,10 @@ public HomePanel() { this.add(totalSavingsAmtLbl, gbConst); } + public void updateTotals() { + HomePanel.totalExpensesAmtLbl.setText(String.format("$%.2f", user.getTotalExpenses())); + HomePanel.totalIncomeAmtLbl.setText(String.format("$%.2f", user.getTotalIncome())); + HomePanel.totalSavingsAmtLbl.setText(String.format("$%.2f", user.getBalance())); + } + } From 36b80fa0a8a21f6eae7c6729c08bbcfde1497e02 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:16:15 -0400 Subject: [PATCH 104/123] passing home panel to import panel, renaming expenser --- src/main/java/edu/ferris/seng210/AppFrame.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/AppFrame.java b/src/main/java/edu/ferris/seng210/AppFrame.java index 00abab2..232b6d8 100644 --- a/src/main/java/edu/ferris/seng210/AppFrame.java +++ b/src/main/java/edu/ferris/seng210/AppFrame.java @@ -2,6 +2,7 @@ import edu.ferris.seng210.account.User; import edu.ferris.seng210.panels.*; +import edu.ferris.seng210.services.DisplayUpdateService; import javax.swing.*; import java.awt.*; @@ -10,7 +11,7 @@ public class AppFrame extends JFrame { - ExpenserMain expenserMain; + DisplayUpdateService displayUpdateService; JMenuBar navMenuBar; JMenu navMenu; JMenuItem homeNav, addItemNav, importNav, estimateNav, incomeReportNav, expenseReportNav, detailedReportNav, loginNav, createAccNav; @@ -21,17 +22,17 @@ public class AppFrame extends JFrame { this.setTitle("EWallet Application"); User user = new User("Default", "TempPassword!123"); - expenserMain = new ExpenserMain(user); + displayUpdateService = new DisplayUpdateService(user); LoginPanel loginPanel = new LoginPanel(); CreateAccountPanel createAccountPanel = new CreateAccountPanel(); HomePanel homePanel = new HomePanel(user); - ImportPanel importPanel = new ImportPanel(user); + ImportPanel importPanel = new ImportPanel(user, homePanel); EstimatePanel estimatePanel = new EstimatePanel(); IncomeReportPanel incomeReportPanel = new IncomeReportPanel(user); ExpenseReportPanel expenseReportPanel = new ExpenseReportPanel(user); DetailedReportPanel detailedReportPanel = new DetailedReportPanel(user); - AddItemPanel addItemPanel = new AddItemPanel(user, expenseReportPanel, incomeReportPanel); + AddItemPanel addItemPanel = new AddItemPanel(user, expenseReportPanel, incomeReportPanel, homePanel); getContentPane().add(homePanel); navMenuBar = new JMenuBar(); navMenu = new JMenu("

Menu"); // Menu From dbd3e87cdda24607dd013f548ef131a7668c2e54 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:17:44 -0400 Subject: [PATCH 105/123] passing home panel to calls, adding calls to update totals in various areas. --- .../ferris/seng210/panels/AddItemPanel.java | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 8f3cce0..8457d0c 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -1,10 +1,10 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.services.DisplayUpdateService; import edu.ferris.seng210.account.User; import edu.ferris.seng210.constants.Months; -import edu.ferris.seng210.transactions.Expense; -import edu.ferris.seng210.transactions.Wage; +import edu.ferris.seng210.records.Expense; +import edu.ferris.seng210.records.Wage; import javax.swing.*; import java.awt.*; @@ -13,7 +13,7 @@ public class AddItemPanel extends JTabbedPane{ private final User user; - ExpenserMain expenserMain; + DisplayUpdateService displayUpdateService; GridBagConstraints gbConst; JPanel incomePane, expensePane; JLabel addIncomeItemLbl, addExpenseItemLbl; @@ -23,9 +23,9 @@ public class AddItemPanel extends JTabbedPane{ JTextField nameExpField, amountExpField; JButton addIncomeButton, addExpenseButton; JComboBox monthComboBox; - public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel) { + public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeReportPanel incomeReportPanel, HomePanel homePanel) { this.user = user; - expenserMain = new ExpenserMain(user); + displayUpdateService = new DisplayUpdateService(user); incomePane = new JPanel(); expensePane = new JPanel(); @@ -118,7 +118,7 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo addIncomeButton.setPreferredSize(new Dimension(150,60)); incomePane.add(addIncomeButton, gbConst); - addIncomeButton.addActionListener(addIncomeAction(incomeReportPanel)); + addIncomeButton.addActionListener(addIncomeAction(incomeReportPanel, homePanel)); this.add("Add Income", incomePane); @@ -175,23 +175,28 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo addExpenseButton.setPreferredSize(new Dimension(150,60)); expensePane.add(addExpenseButton, gbConst); - addExpenseButton.addActionListener(addExpenseAction(expenseReportPanel)); + addExpenseButton.addActionListener(addExpenseAction(expenseReportPanel, homePanel)); this.add("Add expense", expensePane); this.setFont(new Font(null, Font.PLAIN, 24)); } - public ActionListener addIncomeAction(IncomeReportPanel incomeReportPanel) { + public ActionListener addIncomeAction(IncomeReportPanel incomeReportPanel, HomePanel homePanel) { return e -> { if(e.getSource() == addIncomeButton) { user.addMonthlyIncome(new Wage(nameIncField.getText(), Double.parseDouble(amountIncField.getText()), monthComboBox.getSelectedItem().toString())); + user.updateIncomeTotal(); + user.updateBalance(); - expenserMain.updateIncomeTable(); - expenserMain.updateIncomeValues(); - expenserMain.updateDetailedTable(); + displayUpdateService.updateIncomeTable(); + displayUpdateService.updateDetailedTable(); + + homePanel.updateTotals(); incomeReportPanel.updateSources(); + incomeReportPanel.updateIncome(); + nameIncField.setText(""); monthComboBox.setSelectedItem(0); amountIncField.setText(""); @@ -199,15 +204,21 @@ public ActionListener addIncomeAction(IncomeReportPanel incomeReportPanel) { }; } - public ActionListener addExpenseAction(ExpenseReportPanel expenseReportPanel) { + public ActionListener addExpenseAction(ExpenseReportPanel expenseReportPanel, HomePanel homePanel) { return e -> { if(e.getSource() == addExpenseButton) { user.addExpense(new Expense(nameExpField.getText(), Double.parseDouble(amountExpField.getText()), Integer.parseInt(frequencyExpField.getText()))); - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateExpenseValues(); + displayUpdateService.updateExpenseTable(); + displayUpdateService.updateDetailedTable(); + + user.updateExpenseTotal(); + user.updateBalance(); + + homePanel.updateTotals(); + expenseReportPanel.updateSources(); + expenseReportPanel.updateTotalExpense(); nameExpField.setText(""); frequencyExpField.setText(""); From c0a920e86bf512984a2e159b1860354bafeb6111 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:18:30 -0400 Subject: [PATCH 106/123] moving classes --- .../edu/ferris/seng210/panels/CreateAccountPanel.java | 2 +- .../edu/ferris/seng210/panels/DetailedReportPanel.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java index 7cebdba..55abec7 100644 --- a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java @@ -1,6 +1,6 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.UserCreationService; +import edu.ferris.seng210.services.UserCreationService; import edu.ferris.seng210.checker.UsernameChecker; import javax.swing.*; diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java index bc089ce..6e587c6 100644 --- a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -1,7 +1,7 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.ExpenserMain; -import edu.ferris.seng210.ReportService; +import edu.ferris.seng210.services.DisplayUpdateService; +import edu.ferris.seng210.services.ReportService; import edu.ferris.seng210.account.User; import javax.swing.*; @@ -21,10 +21,10 @@ public class DetailedReportPanel extends JPanel { public static JTable detailedTable; JLabel detaileReportTxt; JButton exportReport; - ExpenserMain expenserMain; + DisplayUpdateService displayUpdateService; public DetailedReportPanel(User user) { this.user = user; - expenserMain = new ExpenserMain(user); + displayUpdateService = new DisplayUpdateService(user); this.setLayout(new BorderLayout()); detaileReportTxt = new JLabel("Detailed Report"); From e47614c3281e1d9eb24e080637c55c97fce3cabb Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:19:02 -0400 Subject: [PATCH 107/123] adding method to update amount label --- .../seng210/panels/ExpenseReportPanel.java | 12 ++++++++---- .../seng210/panels/IncomeReportPanel.java | 19 +++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index e7bf7e1..18d1d29 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -1,9 +1,9 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.FilterService; -import edu.ferris.seng210.ReportService; +import edu.ferris.seng210.services.FilterService; +import edu.ferris.seng210.services.ReportService; import edu.ferris.seng210.constants.ExpenseFrequency; -import edu.ferris.seng210.transactions.Expense; +import edu.ferris.seng210.records.Expense; import edu.ferris.seng210.account.User; import javax.swing.*; @@ -153,6 +153,10 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing } + public void updateTotalExpense() { + totalExpenseAmtLbl.setText(String.format("$%.2f", user.getTotalExpenses())); + } + public void updateSources() { typeSelector.removeAllItems(); @@ -188,7 +192,7 @@ public ActionListener filterAction(FilterService filterService) { for(Expense exp : filteredSpending) { spendingTable.setValueAt(exp.getSource(), i, 0); spendingTable.setValueAt(String.format("$%.2f",exp.getAmount()), i, 1); - spendingTable.setValueAt(String.valueOf(exp.getFrequency()), i, 2); + spendingTable.setValueAt(String.valueOf(exp.yearlyFrequency()), i, 2); ++i; expenseSum += exp.getAmount(); } diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java index b05e231..72489c5 100644 --- a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -1,17 +1,16 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.ExpenserMain; -import edu.ferris.seng210.FilterService; -import edu.ferris.seng210.ReportService; +import edu.ferris.seng210.services.DisplayUpdateService; +import edu.ferris.seng210.services.FilterService; +import edu.ferris.seng210.services.ReportService; import edu.ferris.seng210.account.User; import edu.ferris.seng210.constants.Months; -import edu.ferris.seng210.transactions.Wage; +import edu.ferris.seng210.records.Wage; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.List; @@ -29,7 +28,7 @@ public class IncomeReportPanel extends JPanel { JLabel totalIncomeLbl, totalFilteredIncomeLbl; public static JLabel totalIncomeAmtLbl, totalFilteredIncomeAmtLbl; JButton exportReport, applyFilter; - ExpenserMain expenserMain; + DisplayUpdateService displayUpdateService; GridBagConstraints gbConst; JPanel upperPanel; JComboBox monthSelector; @@ -38,7 +37,7 @@ public class IncomeReportPanel extends JPanel { public IncomeReportPanel(User user) { this.user = user; - expenserMain = new ExpenserMain(user); + displayUpdateService = new DisplayUpdateService(user); this.setLayout(new BorderLayout()); @@ -186,7 +185,7 @@ public ActionListener applyFilterAction(FilterService filterService) { for(Wage wage : filteredIncome) { incomeTable.setValueAt(wage.getSource(), i, 0); incomeTable.setValueAt(String.format("$%.2f",wage.getAmount()), i, 1); - incomeTable.setValueAt(wage.getMonth(), i, 2); + incomeTable.setValueAt(wage.month(), i, 2); ++i; incomeSum += wage.getAmount(); } @@ -195,6 +194,10 @@ public ActionListener applyFilterAction(FilterService filterService) { }; } + public void updateIncome() { + totalIncomeAmtLbl.setText(String.format("$%.2f",user.getTotalIncome())); + } + public void updateSources() { typeSelector.removeAllItems(); From 2176ecfe2de623f11e89eee3ef4eb8e1a9525f00 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:19:23 -0400 Subject: [PATCH 108/123] adding class to handle importing data --- .../seng210/services/ImportService.java | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/services/ImportService.java diff --git a/src/main/java/edu/ferris/seng210/services/ImportService.java b/src/main/java/edu/ferris/seng210/services/ImportService.java new file mode 100644 index 0000000..8717fe8 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/services/ImportService.java @@ -0,0 +1,147 @@ +package edu.ferris.seng210.services; + +import edu.ferris.seng210.account.User; +import edu.ferris.seng210.panels.ExpenseReportPanel; +import edu.ferris.seng210.panels.IncomeReportPanel; +import edu.ferris.seng210.records.Expense; +import edu.ferris.seng210.records.Wage; + +import java.io.*; + +public class ImportService { + + public boolean incomeFromCsv(String filePath, User user) { + + String lineText = ""; + BufferedReader bufferedLineReader = null; + BufferedReader bufferedTextReader = null; + File userFile = new File(filePath); + String source = "", month = "", amount = ""; + + + try { + int linesInFile = 0; + bufferedLineReader = new BufferedReader(new FileReader(userFile)); + bufferedTextReader = new BufferedReader(new FileReader(userFile)); + while (bufferedLineReader.readLine() != null) { // count lines in file + linesInFile++; + } + Wage wage; + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { + lineText = bufferedTextReader.readLine(); + if( lineIndex == 0 && lineText.equalsIgnoreCase("source,amount,month")) { + System.out.println("File start setup correctly."); + } + else { + source = ""; + month = ""; + amount = ""; + + for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { + source += lineText.charAt(sourceIndex); + } + + for(int amountindex = lineText.indexOf(',') + 1; amountindex < lineText.lastIndexOf(','); amountindex++) { + amount += lineText.charAt(amountindex); + } + for(int monthIndex = lineText.lastIndexOf(',') + 1; monthIndex < lineText.length(); monthIndex++) { + month += lineText.charAt(monthIndex); + } + + System.out.println("Text read: " + source + "," + amount + "," + month); + + wage = new Wage(source,Double.parseDouble(amount),month); + + user.setBalance(user.getBalance() + wage.getAmount()); + user.addMonthlyIncome(wage); + + if(IncomeReportPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < IncomeReportPanel.typeSelector.getItemCount(); i++) { + if (IncomeReportPanel.typeSelector.getItemAt(i).equals(wage.getSource())) { + contains = true; + } + } + if (!contains) { + IncomeReportPanel.typeSelector.addItem(wage.getSource()); + } + } else { + IncomeReportPanel.typeSelector.addItem(wage.getSource()); + } + + } + } + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + return false; + } + return true; + } + + public boolean expenseFromCsv(String filePath, User user) { + String lineText = ""; + BufferedReader bufferedLineReader = null; + BufferedReader bufferedTextReader = null; + File userFile = new File(filePath); + String source = "", frequency = "", amount = ""; + + try { + int linesInFile = 0; + bufferedLineReader = new BufferedReader(new FileReader(userFile)); + bufferedTextReader = new BufferedReader(new FileReader(userFile)); + while (bufferedLineReader.readLine() != null) { // count lines in file + linesInFile++; + } + Expense expense; + for (int lineIndex = 0; lineIndex < linesInFile; lineIndex++) { + lineText = bufferedTextReader.readLine(); + if(lineIndex == 0 && lineText.trim().equals("source,amount,frequency")) { + System.out.println("File start setup correctly."); + } + else if (lineIndex > 0){ + source = ""; + frequency = ""; + amount = ""; + + for(int sourceIndex = 0; sourceIndex < lineText.indexOf(',', 0); sourceIndex++) { + source += lineText.charAt(sourceIndex); + } + for(int amountIndex = lineText.indexOf(',') + 1; amountIndex < lineText.lastIndexOf(','); amountIndex++) { + amount += lineText.charAt(amountIndex); + } + for(int freqIndex = lineText.lastIndexOf(',') + 1; freqIndex < lineText.length(); freqIndex++) { + frequency += lineText.charAt(freqIndex); + } + + System.out.println("Text read: " + source + "," + amount + "," + frequency); + + expense = new Expense(source,Double.parseDouble(amount),Integer.valueOf(frequency)); + + user.setTotalExpenses(user.getTotalExpenses() + expense.getAmount()); + user.addExpense(expense); + + if(ExpenseReportPanel.typeSelector.getItemCount() > 0) { + boolean contains = false; + for (int i = 0; i < ExpenseReportPanel.typeSelector.getItemCount(); i++) { + if (ExpenseReportPanel.typeSelector.getItemAt(i).equals(expense.getSource())) { + contains = true; + } + } + if (!contains) { + ExpenseReportPanel.typeSelector.addItem(expense.getSource()); + } + } else { + ExpenseReportPanel.typeSelector.addItem(expense.getSource()); + } + + } + } + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + return false; + } + return true; + } +} From 2f45953e9156c16acdc8ff4b5f076b3fa1a0861b Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:20:17 -0400 Subject: [PATCH 109/123] cleaning up importing action --- .../ferris/seng210/panels/ImportPanel.java | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java index 8669d79..fa6b461 100644 --- a/src/main/java/edu/ferris/seng210/panels/ImportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ImportPanel.java @@ -1,6 +1,7 @@ package edu.ferris.seng210.panels; -import edu.ferris.seng210.ExpenserMain; +import edu.ferris.seng210.services.DisplayUpdateService; +import edu.ferris.seng210.services.ImportService; import edu.ferris.seng210.account.User; import javax.swing.*; @@ -10,7 +11,8 @@ public class ImportPanel extends JPanel { - ExpenserMain expenserMain; + private final User user; + DisplayUpdateService displayUpdateService; GridBagConstraints gbConst; JLabel importLbl, selectFileLbl, selectTypeLbl, descriptionLbl; JButton selectFileButton, importButton; @@ -18,9 +20,11 @@ public class ImportPanel extends JPanel { String[] typesOfImports = {"Income", "Expense"}; JComboBox options; File userFile; - public ImportPanel(User user) { + public ImportPanel(User user, HomePanel homePanel) { - expenserMain = new ExpenserMain(user); + this.user = user; + + displayUpdateService = new DisplayUpdateService(user); fileChooser = new JFileChooser(); @@ -77,7 +81,7 @@ public ImportPanel(User user) { this.add(descriptionLbl, gbConst); importButton = new JButton("Import"); - importButton.addActionListener(importAction()); + importButton.addActionListener(importAction(homePanel)); gbConst.gridheight = 1; gbConst.gridx = 0; gbConst.gridy = 5; @@ -87,29 +91,31 @@ public ImportPanel(User user) { } - public ActionListener importAction() { + public ActionListener importAction(HomePanel homePanel) { return e -> { + + if(userFile == null) JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); + + ImportService importService = new ImportService(); + if(options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("income")) { - System.out.println("Income Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadIncomeFile(userFile.getAbsolutePath()); - expenserMain.updateIncomeTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateIncomeValues(); - } + + importService.incomeFromCsv(userFile.getAbsolutePath(), user); + displayUpdateService.updateIncomeTable(); + } else if (options.getItemAt(options.getSelectedIndex()).equalsIgnoreCase("expense")) { - System.out.println("Expense Selected"); - if(userFile == null) { - JOptionPane.showMessageDialog(null,"No file selected!", "Warning User!", JOptionPane.ERROR_MESSAGE); - } else { - expenserMain.loadExpenseFile(userFile.getAbsolutePath()); - expenserMain.updateExpenseTable(); - expenserMain.updateDetailedTable(); - expenserMain.updateExpenseValues(); - } + + importService.expenseFromCsv(userFile.getAbsolutePath(), user); + displayUpdateService.updateExpenseTable(); } + + user.updateExpenseTotal(); + user.updateIncomeTotal(); + user.updateBalance(); + + displayUpdateService.updateDetailedTable(); + + homePanel.updateTotals(); }; } From 310659922f0db9ad04fd3816e6a7c7e118a60a23 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 19:26:56 -0400 Subject: [PATCH 110/123] fixing file path issue with checking passwords from the csv. --- src/main/java/edu/ferris/seng210/checker/PasswordChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java b/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java index 2512cbd..7c19d1b 100644 --- a/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java +++ b/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java @@ -13,7 +13,7 @@ public boolean check(String username,String password) { String lineTxt; try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); + FileInputStream fileInputStream = new FileInputStream("UserCredentials.csv"); Scanner scnr = new Scanner(fileInputStream); while(scnr.hasNextLine()) { From 8a90cf12242a6f9b25568728c4a6a09f33b645ae Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Mon, 17 Mar 2025 23:03:14 -0400 Subject: [PATCH 111/123] removing comments --- src/main/java/edu/ferris/seng210/AppFrame.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/AppFrame.java b/src/main/java/edu/ferris/seng210/AppFrame.java index 232b6d8..6633581 100644 --- a/src/main/java/edu/ferris/seng210/AppFrame.java +++ b/src/main/java/edu/ferris/seng210/AppFrame.java @@ -35,17 +35,17 @@ public class AppFrame extends JFrame { AddItemPanel addItemPanel = new AddItemPanel(user, expenseReportPanel, incomeReportPanel, homePanel); getContentPane().add(homePanel); navMenuBar = new JMenuBar(); - navMenu = new JMenu("

Menu"); // Menu - homeNav = new JMenuItem("

Home"); // Home Page + navMenu = new JMenu("

Menu"); + homeNav = new JMenuItem("

Home"); homeNav.addMouseListener(handleMenuClickAction(homePanel)); - addItemNav = new JMenuItem("

Add Item"); // Add Items Page + addItemNav = new JMenuItem("

Add Item"); addItemNav.addMouseListener(handleMenuClickAction(addItemPanel)); - importNav = new JMenuItem("

Import Tool"); // Import Page + importNav = new JMenuItem("

Import Tool"); importNav.addMouseListener(handleMenuClickAction(importPanel)); - estimateNav = new JMenuItem("

Estimate Tool"); // Estimate Page + estimateNav = new JMenuItem("

Estimate Tool"); estimateNav.addMouseListener(handleMenuClickAction(estimatePanel)); incomeReportNav = new JMenuItem("

Income Report"); @@ -57,10 +57,10 @@ public class AppFrame extends JFrame { detailedReportNav = new JMenuItem("

Detailed Report"); detailedReportNav.addMouseListener(handleMenuClickAction(detailedReportPanel)); - loginNav = new JMenuItem("

Login"); // Add Items Page + loginNav = new JMenuItem("

Login"); loginNav.addMouseListener(handleMenuClickAction(loginPanel)); - createAccNav = new JMenuItem("

Create Account"); // Add Items Page + createAccNav = new JMenuItem("

Create Account"); createAccNav.addMouseListener(handleMenuClickAction(createAccountPanel)); navMenu.setFont(new Font(null, Font.PLAIN, 24)); From 98229bc490729dca70e959110a15993e9582d5d1 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 17:39:19 -0400 Subject: [PATCH 112/123] adding junit5 and assertj-swing as dependencies --- pom.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pom.xml b/pom.xml index 4971557..b293a5e 100644 --- a/pom.xml +++ b/pom.xml @@ -14,4 +14,22 @@ UTF-8 + + + + org.assertj + assertj-swing + 3.17.1 + + + + + org.junit.jupiter + junit-jupiter + 5.12.1 + test + + + + \ No newline at end of file From b018f555db2779959db1499751e04acd05dff260 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 19:02:10 -0400 Subject: [PATCH 113/123] Adding names for gui items to run tests on --- src/main/java/edu/ferris/seng210/AppFrame.java | 10 ++++++++++ .../edu/ferris/seng210/panels/AddItemPanel.java | 13 +++++++++++-- .../ferris/seng210/panels/DetailedReportPanel.java | 1 + .../ferris/seng210/panels/ExpenseReportPanel.java | 1 + .../java/edu/ferris/seng210/panels/HomePanel.java | 3 +++ .../ferris/seng210/panels/IncomeReportPanel.java | 1 + 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/AppFrame.java b/src/main/java/edu/ferris/seng210/AppFrame.java index 6633581..9efb0d4 100644 --- a/src/main/java/edu/ferris/seng210/AppFrame.java +++ b/src/main/java/edu/ferris/seng210/AppFrame.java @@ -33,34 +33,44 @@ public class AppFrame extends JFrame { ExpenseReportPanel expenseReportPanel = new ExpenseReportPanel(user); DetailedReportPanel detailedReportPanel = new DetailedReportPanel(user); AddItemPanel addItemPanel = new AddItemPanel(user, expenseReportPanel, incomeReportPanel, homePanel); + addItemPanel.setName("Add Item Pane"); getContentPane().add(homePanel); navMenuBar = new JMenuBar(); navMenu = new JMenu("

Menu"); homeNav = new JMenuItem("

Home"); + homeNav.setName("Home"); homeNav.addMouseListener(handleMenuClickAction(homePanel)); addItemNav = new JMenuItem("

Add Item"); + addItemNav.setName("Add Item"); addItemNav.addMouseListener(handleMenuClickAction(addItemPanel)); importNav = new JMenuItem("

Import Tool"); + importNav.setName("Import Tool"); importNav.addMouseListener(handleMenuClickAction(importPanel)); estimateNav = new JMenuItem("

Estimate Tool"); + estimateNav.setName("Estimate Tool"); estimateNav.addMouseListener(handleMenuClickAction(estimatePanel)); incomeReportNav = new JMenuItem("

Income Report"); + incomeReportNav.setName("Income Report"); incomeReportNav.addMouseListener(handleMenuClickAction(incomeReportPanel)); expenseReportNav = new JMenuItem("

Expense Report"); + expenseReportNav.setName("Expense Report"); expenseReportNav.addMouseListener(handleMenuClickAction(expenseReportPanel)); detailedReportNav = new JMenuItem("

Detailed Report"); + detailedReportNav.setName("Detailed Report"); detailedReportNav.addMouseListener(handleMenuClickAction(detailedReportPanel)); loginNav = new JMenuItem("

Login"); + loginNav.setName("Login"); loginNav.addMouseListener(handleMenuClickAction(loginPanel)); createAccNav = new JMenuItem("

Create Account"); + createAccNav.setName("Create Account"); createAccNav.addMouseListener(handleMenuClickAction(createAccountPanel)); navMenu.setFont(new Font(null, Font.PLAIN, 24)); diff --git a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java index 8457d0c..9e93e20 100644 --- a/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/AddItemPanel.java @@ -29,8 +29,10 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo incomePane = new JPanel(); expensePane = new JPanel(); + expensePane.setName("Expense Pane"); monthComboBox = new JComboBox<>(Months.getNames().toArray()); + monthComboBox.setName("Month"); monthComboBox.setFont(new Font(null,Font.PLAIN, 24)); monthComboBox.setSelectedIndex(0); @@ -52,15 +54,20 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo frequencyExpLbl = new JLabel("Freq."); nameIncField = new JTextField(); + nameIncField.setName("Income Name"); nameIncField.setPreferredSize(new Dimension(280, 50)); amountIncField = new JTextField(); + amountIncField.setName("Income Amount"); amountIncField.setPreferredSize(new Dimension(280, 50)); frequencyExpField = new JTextField(); + frequencyExpField.setName("Expense Frequency"); frequencyExpField.setPreferredSize(new Dimension(280, 50)); nameExpField = new JTextField(); + nameExpField.setName("Expense Name"); nameExpField.setPreferredSize(new Dimension(280, 50)); amountExpField = new JTextField(); + amountExpField.setName("Expense Amount"); amountExpField.setPreferredSize(new Dimension(280, 50)); monthComboBox.setPreferredSize(new Dimension(280, 50)); @@ -116,11 +123,12 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo gbConst.insets = new Insets(20,30,30,30); addIncomeButton.setFont(new Font(null, Font.PLAIN, 28)); addIncomeButton.setPreferredSize(new Dimension(150,60)); + addIncomeButton.setName("Add Income"); incomePane.add(addIncomeButton, gbConst); addIncomeButton.addActionListener(addIncomeAction(incomeReportPanel, homePanel)); - this.add("Add Income", incomePane); + this.addTab("Add Income", incomePane); gbConst.gridx = 0; gbConst.gridy = 0; @@ -172,12 +180,13 @@ public AddItemPanel(User user, ExpenseReportPanel expenseReportPanel, IncomeRepo gbConst.gridwidth = 2; gbConst.insets = new Insets(20,30,30,30); addExpenseButton.setFont(new Font(null, Font.PLAIN, 28)); + addExpenseButton.setName("Add Expense"); addExpenseButton.setPreferredSize(new Dimension(150,60)); expensePane.add(addExpenseButton, gbConst); addExpenseButton.addActionListener(addExpenseAction(expenseReportPanel, homePanel)); - this.add("Add expense", expensePane); + this.addTab("Add expense", expensePane); this.setFont(new Font(null, Font.PLAIN, 24)); } diff --git a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java index 6e587c6..aee5f06 100644 --- a/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/DetailedReportPanel.java @@ -40,6 +40,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing return false; } }; + detailedTable.setName("Detailed Report Table"); jScrollPane = new JScrollPane(detailedTable); centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); diff --git a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java index 18d1d29..4e6aaa6 100644 --- a/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/ExpenseReportPanel.java @@ -137,6 +137,7 @@ public boolean isCellEditable(int row, int column) { // restricting cell editing spendingTable.setCellSelectionEnabled(true); spendingTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); spendingTable.setShowVerticalLines(false); + spendingTable.setName("Expense Table"); this.add(jScrollPane, BorderLayout.CENTER); diff --git a/src/main/java/edu/ferris/seng210/panels/HomePanel.java b/src/main/java/edu/ferris/seng210/panels/HomePanel.java index e57d5a9..3b3421c 100644 --- a/src/main/java/edu/ferris/seng210/panels/HomePanel.java +++ b/src/main/java/edu/ferris/seng210/panels/HomePanel.java @@ -15,10 +15,13 @@ public HomePanel(User user) { summaryTxt = new JLabel("User Summary"); totalIncomeLbl = new JLabel("Total Income: "); totalIncomeAmtLbl = new JLabel("$0.00"); + totalIncomeAmtLbl.setName("Total Income Amount"); totalExpensesLbl = new JLabel("Total Expenses: "); totalExpensesAmtLbl = new JLabel("$0.00"); + totalExpensesAmtLbl.setName("Total Expenses Amount"); totalSavingsLbl = new JLabel("Total Savings: "); totalSavingsAmtLbl = new JLabel("$0.00"); + totalSavingsAmtLbl.setName("Total Savings Amount"); gbConst = new GridBagConstraints(); this.setLayout(new GridBagLayout()); diff --git a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java index 72489c5..aca7fc0 100644 --- a/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/IncomeReportPanel.java @@ -142,6 +142,7 @@ public boolean isCellEditable(int row, int column) { incomeTable.setCellSelectionEnabled(true); incomeTable.getTableHeader().setFont(new Font(null, Font.PLAIN, 32)); incomeTable.setShowVerticalLines(false); + incomeTable.setName("Income Table"); this.add(jScrollPane, BorderLayout.CENTER); From c12ccd35ba501ea9e9321ea0fa92b40707fd0efb Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 19:02:36 -0400 Subject: [PATCH 114/123] Creating tests for adding income and expenses --- src/test/java/edu/ferris/seng210/GUITest.java | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 src/test/java/edu/ferris/seng210/GUITest.java diff --git a/src/test/java/edu/ferris/seng210/GUITest.java b/src/test/java/edu/ferris/seng210/GUITest.java new file mode 100644 index 0000000..c4f2d0f --- /dev/null +++ b/src/test/java/edu/ferris/seng210/GUITest.java @@ -0,0 +1,226 @@ +package edu.ferris.seng210; + +import org.assertj.swing.data.TableCell; +import org.assertj.swing.edt.GuiActionRunner; +import org.assertj.swing.fixture.FrameFixture; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class GUITest { + + private FrameFixture window; + + @BeforeEach + public void setUp() { + AppFrame appFrame = GuiActionRunner.execute(AppFrame::new); + window = new FrameFixture(appFrame); + window.show(); + } + + @AfterEach + public void tearDown() { + window.cleanUp(); + } + + @Test + public void incomeChargesShowsWhenIncomeAdded() { + window.menuItem("Add Item").click(); + window.textBox("Income Name").setText("Salary"); + window.textBox("Income Amount").setText("1000"); + window.comboBox("Month").selectItem(0); + window.button("Add Income").click(); + + window.textBox("Income Name").requireText(""); + window.textBox("Income Amount").requireText(""); + + window.menuItem("Home").click(); + window.label("Total Income Amount").requireText("$1000.00"); + window.label("Total Expenses Amount").requireText("$0.00"); + window.label("Total Savings Amount").requireText("$1000.00"); + + window.menuItem("Income Report").click(); + window.table("Income Table").requireRowCount(1); + window.table("Income Table").requireCellValue(TableCell.row(0).column(0), "Salary"); + window.table("Income Table").requireCellValue(TableCell.row(0).column(1), "$1000.00"); + window.table("Income Table").requireCellValue(TableCell.row(0).column(2), "January"); + + window.menuItem("Detailed Report").click(); + window.table("Detailed Report Table").requireRowCount(1); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(0), "Income"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(1), "Salary"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(2), "$1000.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(3), "January"); + } + + @Test + public void multipleIncomeChargesShowsWhenIncomeAdded() { + window.menuItem("Add Item").click(); + + window.textBox("Income Name").setText("Salary"); + window.textBox("Income Amount").setText("1000"); + window.comboBox("Month").selectItem(0); + window.button("Add Income").click(); + + window.textBox("Income Name").requireText(""); + window.textBox("Income Amount").requireText(""); + + window.textBox("Income Name").setText("Salary"); + window.textBox("Income Amount").setText("1250"); + window.comboBox("Month").selectItem(1); + window.button("Add Income").click(); + + window.textBox("Income Name").requireText(""); + window.textBox("Income Amount").requireText(""); + + window.textBox("Income Name").setText("Salary"); + window.textBox("Income Amount").setText("1500"); + window.comboBox("Month").selectItem(2); + window.button("Add Income").click(); + + window.textBox("Income Name").requireText(""); + window.textBox("Income Amount").requireText(""); + + window.menuItem("Home").click(); + window.label("Total Income Amount").requireText("$3750.00"); + window.label("Total Expenses Amount").requireText("$0.00"); + window.label("Total Savings Amount").requireText("$3750.00"); + + window.menuItem("Income Report").click(); + window.table("Income Table").requireRowCount(3); + + window.table("Income Table").requireCellValue(TableCell.row(0).column(0), "Salary"); + window.table("Income Table").requireCellValue(TableCell.row(0).column(1), "$1000.00"); + window.table("Income Table").requireCellValue(TableCell.row(0).column(2), "January"); + + window.table("Income Table").requireCellValue(TableCell.row(1).column(0), "Salary"); + window.table("Income Table").requireCellValue(TableCell.row(1).column(1), "$1250.00"); + window.table("Income Table").requireCellValue(TableCell.row(1).column(2), "February"); + + window.table("Income Table").requireCellValue(TableCell.row(2).column(0), "Salary"); + window.table("Income Table").requireCellValue(TableCell.row(2).column(1), "$1500.00"); + window.table("Income Table").requireCellValue(TableCell.row(2).column(2), "March"); + + window.menuItem("Detailed Report").click(); + window.table("Detailed Report Table").requireRowCount(3); + + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(0), "Income"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(1), "Salary"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(2), "$1000.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(3), "January"); + + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(0), "Income"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(1), "Salary"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(2), "$1250.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(3), "February"); + + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(0), "Income"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(1), "Salary"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(2), "$1500.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(3), "March"); + } + + @Test + public void expenseChargesShowsWhenExpensesAreAdded() { + window.menuItem("Add Item").click(); + window.tabbedPane("Add Item Pane").selectTab("Add expense"); + + window.textBox("Expense Name").setText("Coffee"); + window.textBox("Expense Amount").setText("5"); + window.textBox("Expense Frequency").setText("1"); + window.button("Add Expense").click(); + + window.textBox("Expense Name").requireText(""); + window.textBox("Expense Amount").requireText(""); + window.textBox("Expense Frequency").requireText(""); + + window.menuItem("Home").click(); + window.label("Total Income Amount").requireText("$0.00"); + window.label("Total Expenses Amount").requireText("$5.00"); + window.label("Total Savings Amount").requireText("$-5.00"); + + window.menuItem("Expense Report").click(); + window.table("Expense Table").requireRowCount(1); + window.table("Expense Table").requireCellValue(TableCell.row(0).column(0), "Coffee"); + window.table("Expense Table").requireCellValue(TableCell.row(0).column(1), "$5.00"); + window.table("Expense Table").requireCellValue(TableCell.row(0).column(2), "1"); + + window.menuItem("Detailed Report").click(); + window.table("Detailed Report Table").requireRowCount(1); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(0), "Expense"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(1), "Coffee"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(2), "$5.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(3), "1"); + } + + @Test + public void multipleExpenseChargesShowsWhenExpensesAreAdded() { + window.menuItem("Add Item").click(); + window.tabbedPane("Add Item Pane").selectTab("Add expense"); + + window.textBox("Expense Name").setText("Coffee"); + window.textBox("Expense Amount").setText("5"); + window.textBox("Expense Frequency").setText("1"); + window.button("Add Expense").click(); + + window.textBox("Expense Name").requireText(""); + window.textBox("Expense Amount").requireText(""); + window.textBox("Expense Frequency").requireText(""); + + window.textBox("Expense Name").setText("Meal"); + window.textBox("Expense Amount").setText("15"); + window.textBox("Expense Frequency").setText("1"); + window.button("Add Expense").click(); + + window.textBox("Expense Name").requireText(""); + window.textBox("Expense Amount").requireText(""); + window.textBox("Expense Frequency").requireText(""); + + window.textBox("Expense Name").setText("Spotify"); + window.textBox("Expense Amount").setText("15"); + window.textBox("Expense Frequency").setText("12"); + window.button("Add Expense").click(); + + window.textBox("Expense Name").requireText(""); + window.textBox("Expense Amount").requireText(""); + window.textBox("Expense Frequency").requireText(""); + + window.menuItem("Home").click(); + window.label("Total Income Amount").requireText("$0.00"); + window.label("Total Expenses Amount").requireText("$35.00"); + window.label("Total Savings Amount").requireText("$-35.00"); + + window.menuItem("Expense Report").click(); + window.table("Expense Table").requireRowCount(3); + window.table("Expense Table").requireCellValue(TableCell.row(0).column(0), "Coffee"); + window.table("Expense Table").requireCellValue(TableCell.row(0).column(1), "$5.00"); + window.table("Expense Table").requireCellValue(TableCell.row(0).column(2), "1"); + + window.table("Expense Table").requireCellValue(TableCell.row(1).column(0), "Meal"); + window.table("Expense Table").requireCellValue(TableCell.row(1).column(1), "$15.00"); + window.table("Expense Table").requireCellValue(TableCell.row(1).column(2), "1"); + + window.table("Expense Table").requireCellValue(TableCell.row(2).column(0), "Spotify"); + window.table("Expense Table").requireCellValue(TableCell.row(2).column(1), "$15.00"); + window.table("Expense Table").requireCellValue(TableCell.row(2).column(2), "12"); + + window.menuItem("Detailed Report").click(); + window.table("Detailed Report Table").requireRowCount(3); + + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(0), "Expense"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(1), "Coffee"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(2), "$5.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(0).column(3), "1"); + + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(0), "Expense"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(1), "Meal"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(2), "$15.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(1).column(3), "1"); + + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(0), "Expense"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(1), "Spotify"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(2), "$15.00"); + window.table("Detailed Report Table").requireCellValue(TableCell.row(2).column(3), "12"); + } + +} From 9f2913eb4137fef227a79b727ad50e80428c55e0 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:29:56 -0400 Subject: [PATCH 115/123] adding jackson dataformat csv dependency --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index b293a5e..a0e3508 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,13 @@ test + + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + 2.18.2 + + \ No newline at end of file From 48b946c4677fc38f3fc4183565a4633fbad95eb9 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:30:48 -0400 Subject: [PATCH 116/123] reformatting csv file --- UserCredentials.csv | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/UserCredentials.csv b/UserCredentials.csv index 720b772..a289545 100644 --- a/UserCredentials.csv +++ b/UserCredentials.csv @@ -1,5 +1,8 @@ -admin, Password!123, -Test1,FirstTest1!, -Test2,SecondTest!2, -Test3,ThirdTest3!, -Test4,FourthTest!4, +username,password +admin,"Password!123" +Test1,"FirstTest1!" +Test2,"SecondTest!2" +Test3,"ThirdTest3!" +Test4,"FourthTest!4" +john,"mySecurePassword!123" +joe,"mySecurePassword!123" From c75ffc6a46578b73f369366b9f858cc1b63fbade Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:31:55 -0400 Subject: [PATCH 117/123] cleaning username checker a bit --- .../seng210/checker/UsernameChecker.java | 66 +++---------------- 1 file changed, 10 insertions(+), 56 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/checker/UsernameChecker.java b/src/main/java/edu/ferris/seng210/checker/UsernameChecker.java index 56aac40..acc92aa 100644 --- a/src/main/java/edu/ferris/seng210/checker/UsernameChecker.java +++ b/src/main/java/edu/ferris/seng210/checker/UsernameChecker.java @@ -1,70 +1,24 @@ package edu.ferris.seng210.checker; -import java.io.FileInputStream; -import java.io.FileNotFoundException; +import edu.ferris.seng210.csv.CsvCredentialService; +import edu.ferris.seng210.records.Credentials; + import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Scanner; +import java.util.List; public class UsernameChecker { - public boolean check(String username) { - boolean flag = false; - String savedUser; - - try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - while(scnr.hasNextLine()) { - savedUser = scnr.nextLine(); - if(savedUser.indexOf(username) != -1) { - flag = true; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return flag; - } - - public boolean hasRepeat(String username) { + public boolean exists(String username) { + CsvCredentialService credentialService = new CsvCredentialService(); try { - FileInputStream fileInputStream = new FileInputStream("src\\UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); - - Path path = Paths.get("src/UserCredentials.csv"); - long lines = Files.lines(path).count(); - String textAtLine; - String readUsername; - if(lines < 1) { - System.out.println("There is no data in file."); - } else { - for (int i = 0; i < lines; i++) { - textAtLine = scnr.nextLine(); - readUsername = ""; - for (int j = 0; j < textAtLine.length(); j++) { - if (textAtLine.charAt(j) != ',') { - readUsername += textAtLine.charAt(j); - } else { - break; - } - } - if (username.equals(readUsername)) { + List currentCredentials = credentialService.readCredentials(); - System.out.println("Username already exists."); - return true; - - } + for (Credentials credential : currentCredentials) { + if (credential.username().equals(username)) { + return true; } } - } catch (FileNotFoundException e) { - - System.out.println("The file UserCredentials.csv was not found."); - } catch (IOException e) { e.printStackTrace(); } From 0d64ba98f74e6818224c6473bc6c81441753f063 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:32:10 -0400 Subject: [PATCH 118/123] cleaning user creation service a bit --- .../seng210/services/UserCreationService.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/services/UserCreationService.java b/src/main/java/edu/ferris/seng210/services/UserCreationService.java index b432305..69ffcdf 100644 --- a/src/main/java/edu/ferris/seng210/services/UserCreationService.java +++ b/src/main/java/edu/ferris/seng210/services/UserCreationService.java @@ -4,34 +4,35 @@ import edu.ferris.seng210.account.User; import edu.ferris.seng210.checker.PasswordComplexityChecker; import edu.ferris.seng210.checker.UsernameChecker; +import edu.ferris.seng210.csv.CsvCredentialService; +import edu.ferris.seng210.records.Credentials; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.PrintWriter; +import javax.swing.*; +import java.io.*; +import java.util.List; public class UserCreationService { public void create(String username, String password) { UsernameChecker checker = new UsernameChecker(); + CsvCredentialService credentialService = new CsvCredentialService(); PasswordComplexityChecker passwordComplexityChecker = new PasswordComplexityChecker(); - if (!checker.hasRepeat(username) && passwordComplexityChecker.check(password)) { + if (!checker.exists(username) && passwordComplexityChecker.check(password)) { User user = new User(username, password); EWalletApp.users.add(user); try { - FileOutputStream fileOutputStream = new FileOutputStream("UserCredentials.csv", true); - PrintWriter printWriter = new PrintWriter(fileOutputStream); - printWriter.append(username); - printWriter.append(","); - printWriter.append(password); - printWriter.append(",\n"); - printWriter.close(); - - } catch (FileNotFoundException e) { + List currentCredentials = credentialService.readCredentials(); + currentCredentials.add(new Credentials(username, password)); + credentialService.writeCredentials(currentCredentials); + + } catch (IOException e) { e.printStackTrace(); } + } else { + JOptionPane.showMessageDialog(null, "Username already exists or password does not meet complexity requirements."); } } From 2d31b256b03454d20b2f452c2af6fd5adff6f5f8 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:32:30 -0400 Subject: [PATCH 119/123] cleaning password checker a bit --- .../seng210/checker/PasswordChecker.java | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java b/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java index 7c19d1b..3e8e047 100644 --- a/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java +++ b/src/main/java/edu/ferris/seng210/checker/PasswordChecker.java @@ -1,39 +1,24 @@ package edu.ferris.seng210.checker; -import edu.ferris.seng210.EWalletApp; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.util.Scanner; +import edu.ferris.seng210.csv.CsvCredentialService; +import edu.ferris.seng210.records.Credentials; +import java.io.IOException; +import java.util.List; public class PasswordChecker { - public boolean check(String username,String password) { - boolean flag = false; - String lineTxt; + public boolean check(String username, String password) { + CsvCredentialService credentialService = new CsvCredentialService(); try { - FileInputStream fileInputStream = new FileInputStream("UserCredentials.csv"); - Scanner scnr = new Scanner(fileInputStream); + List currentCredentials = credentialService.readCredentials(); + int accountFound = currentCredentials.indexOf(new Credentials(username, password)); - while(scnr.hasNextLine()) { - lineTxt = scnr.nextLine(); - if(lineTxt.indexOf(username) != -1) { - if((lineTxt.indexOf(username) + username.length() + 1) == lineTxt.indexOf(password)) { - for(int i = 0; i < EWalletApp.users.size(); i++) { - if(EWalletApp.users.get(i).getUsername().equals(username)) { - EWalletApp.activeUser = EWalletApp.users.get(i); - } - } - flag = true; - break; - } - } - } - } catch (FileNotFoundException e) { + return accountFound != -1; + } catch (IOException e) { e.printStackTrace(); } - return flag; + return false; } } From 4acb7701f033de72987429ba781afcca2cf18110 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:32:54 -0400 Subject: [PATCH 120/123] adjusting method call name in LoginPanel --- src/main/java/edu/ferris/seng210/panels/LoginPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java index 20a59e9..6fa61a3 100644 --- a/src/main/java/edu/ferris/seng210/panels/LoginPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/LoginPanel.java @@ -80,7 +80,7 @@ public ActionListener loginAction() { UsernameChecker usernameChecker = new UsernameChecker(); PasswordChecker passwordChecker = new PasswordChecker(); - if(usernameChecker.check(username) && passwordChecker.check(username, password)) { + if(usernameChecker.exists(username) && passwordChecker.check(username, password)) { usernameIncField.setText(""); passwordIncField.setText(""); System.out.println("Login Successful"); From 830ffac8b2b9a532ad5d3db375979c2a7da606bd Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:33:24 -0400 Subject: [PATCH 121/123] creating class to handle reading and writing to the credentials csv file --- .../seng210/csv/CsvCredentialService.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/csv/CsvCredentialService.java diff --git a/src/main/java/edu/ferris/seng210/csv/CsvCredentialService.java b/src/main/java/edu/ferris/seng210/csv/CsvCredentialService.java new file mode 100644 index 0000000..709fc92 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/csv/CsvCredentialService.java @@ -0,0 +1,53 @@ +package edu.ferris.seng210.csv; + +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; +import edu.ferris.seng210.records.Credentials; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +public class CsvCredentialService { + + + public List readCredentials() throws IOException { + File credentialsCsv = new File("UserCredentials.csv"); + + return new CsvMapper() + .readerFor(Credentials.class) + .with(buildCsvSchemaForReadingCredentials()) + .readValues(credentialsCsv) + .readAll(); + } + + public void writeCredentials(List credentials) throws IOException { + Path filePath = Path.of("UserCredentials.csv"); + + byte[] csvByteData = new CsvMapper() + .writer(buildCsvSchemaForWritingCredentials()) + .writeValueAsBytes(credentials); + + Files.write(filePath, csvByteData); + } + + public CsvSchema buildCsvSchemaForWritingCredentials() { + return CsvSchema.builder() + .addColumn("username") + .addColumn("password") + .setColumnSeparator(',') + .build() + .withHeader(); + } + + public CsvSchema buildCsvSchemaForReadingCredentials() { + return CsvSchema.builder() + .setSkipFirstDataRow(true) + .addColumn("username") + .addColumn("password") + .setColumnSeparator(',') + .build(); + } +} From 462253b4e915dc5f56fd2cae4e2886bd35d536d7 Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:33:48 -0400 Subject: [PATCH 122/123] creating record class to store credentials read from csv file --- src/main/java/edu/ferris/seng210/records/Credentials.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/edu/ferris/seng210/records/Credentials.java diff --git a/src/main/java/edu/ferris/seng210/records/Credentials.java b/src/main/java/edu/ferris/seng210/records/Credentials.java new file mode 100644 index 0000000..76384f5 --- /dev/null +++ b/src/main/java/edu/ferris/seng210/records/Credentials.java @@ -0,0 +1,7 @@ +package edu.ferris.seng210.records; + +public record Credentials( + String username, + String password +) { +} From 96ca56f8a08aec4033fa0818a0083d7f015f292d Mon Sep 17 00:00:00 2001 From: Trevor Busk Date: Tue, 18 Mar 2025 23:34:23 -0400 Subject: [PATCH 123/123] removing unnecessary logic from create account button action --- .../seng210/panels/CreateAccountPanel.java | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java index 55abec7..7f3f1c0 100644 --- a/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java +++ b/src/main/java/edu/ferris/seng210/panels/CreateAccountPanel.java @@ -88,30 +88,18 @@ public CreateAccountPanel() { public ActionListener createAccountAction() { return e -> { if (e.getSource() == createAccBtn) { - username = usernameField.getText(); - password = passwordField.getText(); - confPassword = confPasswordField.getText(); - if (!usernameField.getText().isEmpty() && !passwordField.getText().isEmpty() && !confPasswordField.getText().isEmpty()) { - if (confPassword.equals(password)) { - UsernameChecker usernameChecker = new UsernameChecker(); - if (usernameChecker.hasRepeat(usernameField.getText())) { - JOptionPane.showMessageDialog(null, "Username taken. Please choose another."); - } else { - UserCreationService userCreationService = new UserCreationService(); - - userCreationService.create(username, password); - JOptionPane.showMessageDialog(null, "User created successfully."); - usernameField.setText(""); - passwordField.setText(""); - confPasswordField.setText(""); - } - } else { - JOptionPane.showMessageDialog(null, "Passwords do not match!"); - } - } else { - JOptionPane.showMessageDialog(null, "Not all fields filled out. Please fill them out."); - } + + UserCreationService userCreationService = new UserCreationService(); + userCreationService.create(usernameField.getText(), passwordField.getText()); + clearCredentialFields(); + } }; } + + private void clearCredentialFields() { + usernameField.setText(""); + passwordField.setText(""); + confPasswordField.setText(""); + } }