Compare commits

..

No commits in common. "Phase-IV" and "Phase-II" have entirely different histories.

29 changed files with 230 additions and 1406 deletions

21
.vscode/launch.json vendored
View File

@ -1,21 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "BankAcctApp",
"request": "launch",
"mainClass": "bankAcctApp.BankAcctApp",
"projectName": "Bank Account App_b3cd1e26"
}
]
}

View File

@ -7,18 +7,7 @@
- [Table of Contents](#table-of-contents)
- [Introduction](#introduction)
- [Scenario:](#scenario)
- [Phase I: Creating the Initial Classes](#phase-i-creating-the-initial-classes)
- [Phase II: Adding an Abstract Superclass & Input Data Validation](#phase-ii-adding-an-abstract-superclass--input-data-validation)
- [Phase III: Adding & Implementing Subclasses](#phase-iii-adding--implementing-subclasses)
- [Phase IV: Creating the Application GUI](#phase-iv-creating-the-application-gui)
- [Application Architecture & Components](#application-architecture--components)
- [DataEntry Class](#dataentry-class)
- [Customer Class](#customer-class)
- [BankAcctApp Class](#bankacctapp-class)
- [Account Abstract Superclass](#account-abstract-superclass)
- [CheckingAccount & SavingsAccount Subclasses](#checkingaccount--savingsaccount-subclasses)
- [AccountInterface Interface](#accountinterface-interface)
- [BankAcctAppGUI Class](#bankacctappgui-class)
- [Application Architecture \& Components](#application-architecture--components)
- [Functionality \& Rationale](#functionality--rationale)
- [Running Application Screenshots \& Demo](#running-application-screenshots--demo)
- [Potential for Scalability \& Future Enhancements](#potential-for-scalability--future-enhancements)
@ -50,8 +39,6 @@ During the first three phases, the application employs console-based input and o
- ## Phase IV: Adding a GUI Frontend
The final phase of the project, Phase IV, creates a **graphical user interface (GUI)** to replace the console interface. The GUI is created using **Swing classes** to include **JFrames**, **JPanels**, and other GUI components. This GUI uses a combination of **BorderLayout**, **GridBagLayout**, and **FlowLayout** to manage the GUI's layout design.
[Back to Top](#table-of-contents)
<br>
# Application Architecture & Components
@ -77,7 +64,6 @@ The application follows a modular design to provide clearly-defined separation o
- Shared Rules: Logic is implemented to prevent overdrafting savings accounts and to ensure no interest is applied to account balances of $0 or less.
These subclasses provide distinct account management features while adhering to shared principles of financial security and error handling.
- ## AccountInterface Interface
The **AccountInterface** serves three key purposes:
**1. Enforce encapsulation** by defining a consistent interface for interacting with account objects.
@ -87,30 +73,20 @@ The application follows a modular design to provide clearly-defined separation o
- ## BankAcctAppGUI Class
The **BankAcctAppGUI class** is responsible for implementing the **graphical user interface (GUI)** introduced in **Phase IV**. It utilizes **Java's Swing library**, incorporating **JFrame** for the main application window and **JPanel** for creating distinct sections within the interface. **FlowLayout**, **BorderLayout**, and **GridBagLayout** are implemented to position GUI components in an intuitive manner. The GUI leverages the **enhanced data validation engine** from the **DataEntry class** to ensure data integrity and security. This class facilitates user interaction with the application through a more visually appealing and user-friendly interface. More details and screenshots are provided in the [Functionality & Rationale](#functionality--rationale) and [Running Application Screenshots & Demo](#running-application-screenshots--demo) sections below.
[Back to Top](#table-of-contents)
<br>
# Functionality & Rationale
[Back to Top](#table-of-contents)
<br>
# Running Application Screenshots & Demo
[Back to Top](#table-of-contents)
<br>
# Potential for Scalability & Future Enhancements
[Back to Top](#table-of-contents)
<br>
# Project Issues & Lessons Learned
[Back to Top](#table-of-contents)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,102 +1,80 @@
/* Phase IV */
/* Phase II */
package bankAcctApp;
import java.util.ArrayList;
public class Account {
// Abstract class defining the structure for account types
public abstract class Account implements AccountInterface {
private String accountNumber; // Account number for each account
private String accountType; // Type of account (CHK or SAV)
private double svcFee; // Service fee for transactions
private double interestRate; // Interest rate for the account
private double overDraftFee; // Overdraft fee for checking accounts
private double balance = 0.00; // Initial balance of the account
private String accountNumber;
private String accountType;
private Double svcFee;
private Double interestRate;
private Double overDraftFee;
private Double balance = 0.00;
// Transaction history stored as strings
private ArrayList<String> transactionHistory = new ArrayList<>();
// Getter for account number
// Getter and Setter for Account Number info.
public String getAccountNumber() {
return accountNumber;
}
// Setter for account number
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
// Getter for account type
// Getter and Setter for Customer ID info.
public String getAccountType() {
return accountType;
}
// Setter for account type
public void setAccountType(String accountType) {
this.accountType = accountType;
}
// Getter for service fee
public double getSvcFee() {
// Getter and Setter for Service Fee info.
public Double getSvcFee() {
return svcFee;
}
// Setter for service fee
public void setSvcFee(double svcFee) {
public void setSvcFee(Double svcFee) {
this.svcFee = svcFee;
}
// Getter for interest rate
public double getInterestRate() {
// Getter and Setter for Interest Rate info.
public Double getInterestRate() {
return interestRate;
}
// Setter for interest rate
public void setInterestRate(double interestRate) {
public void setInterestRate(Double interestRate) {
this.interestRate = interestRate;
}
// Getter for overdraft fee
public double getOverDraftFee() {
// Getter and Setter for Overdraft Fee info.
public Double getOverDraftFee() {
return overDraftFee;
}
// Setter for overdraft fee
public void setOverDraftFee(double overDraftFee) {
public void setOverDraftFee(Double overDraftFee) {
this.overDraftFee = overDraftFee;
}
// Getter for account balance
public double getBalance() {
// Getter and Setter for Balance info.
public Double getBalance() {
return balance;
}
// Setter for account balance
public void setBalance(double balance) {
public void setBalance(Double balance) {
this.balance = balance;
}
// Getter for transaction history
public ArrayList<String> getTransactionHistory() {
return transactionHistory;
}
// Method to log a transaction and store it in the transaction history
public String logTransaction(String date, String type, double amount) {
String transaction = String.format(
"Date: %s | Type: %s | Amount: $%.2f | Balance: $%.2f",
date, type, amount, this.balance
// Override the toString() method that is inherited by default in Java.
// Then use the custom-written toString() method to return Account Info
@Override
public String toString() {
return String.format(
"Acct#: Type: Svc Fee: Int Rate: Ovdft Fee: Balance: \n" +
"------ ----- -------- --------- ---------- -------- \n" +
"%-8s %-8s $%-10.2f %-12.1f $%-12.2f $%-9.2f",
accountNumber, accountType, svcFee, interestRate, overDraftFee, balance
);
transactionHistory.add(transaction); // Add transaction to history
return transaction; // Return the formatted transaction string
}
// Abstract method for withdrawals, to be implemented in subclasses
public abstract void withdrawal(double amount);
// Abstract method for deposits, to be implemented in subclasses
public abstract void deposit(double amount);
// Abstract method for applying accrued interest
public abstract double applyAccruedInterest(String transactionDate);
}

View File

@ -1,10 +0,0 @@
/* Phase IV */
package bankAcctApp;
public interface AccountInterface {
void withdrawal(double amount);
void deposit(double amount);
double applyAccruedInterest(String date);
double balance();
}

View File

@ -1,345 +1,182 @@
/* Phase IV */
/* Phase II */
package bankAcctApp;
import java.util.ArrayList;
import java.util.InputMismatchException;
public class BankAcctApp {
public static void main(String[] args) {
// Create ArrayLists for the Customer and Account classes. Each ArrayList will store the instances
// created of its respective class, appending each new instance to the end of the list.
ArrayList<Customer> customers = new ArrayList<>();
ArrayList<Account> accounts = new ArrayList<>();
new BankAcctAppGUI(customers, accounts);
boolean moreCustomers = true;
// Add customers and accounts
// Create the loop that keeps adding Customer and Account instances until
// the user chooses to quit.
while (moreCustomers) {
Customer customer = new Customer();
Account account = null;
int inputCount = 0;
// Create instances of the both the Customer and Account classes.
// These will be stored in their respective class' ArrayList.
Customer customer = new Customer();
Account account = new Account();
// Customer Information:
System.out.println("Enter details for new customer:\n");
// Collect and validate customer ID
while (inputCount == 0) {
// Collect and validate user input for Customer ID info.
try {
customer.setID(DataEntry.inputStringWithLimit("Customer ID (max 5 chars): ", 5));
} catch (IllegalArgumentException e){
System.out.println("Customer ID must be 5 alphanumeric characters only. Try again.");
continue; // retry input if invalid
}
inputCount++;
}
// Collect and validate SSN
while (inputCount == 1) {
// Collect and validate user input for Social Security Number (SSN).
try {
customer.setSSN(DataEntry.inputNumericString("SSN (9 numeric chars): ", 9));
} catch (IllegalArgumentException e) {
System.out.println("SSN must be exactly 9 digits. Try again.");
continue;
}
inputCount++;
}
// Collect and validate Last Name
while (inputCount == 2) {
// Collect and validate user input for Last Namee.
try {
customer.setLastName(DataEntry.inputStringWithLimit("Last Name (max 20 chars): ", 20));
} catch (IllegalArgumentException e) {
System.out.println("Last Name must not contain numbers or special characters. Try again.");
continue;
}
inputCount++;
System.out.println("Last Name must not contain numbers (0-9) or special characters "
+ "(!@#$%^&*(){}[]|). Try again.");
}
// Collect and validate First Name
while (inputCount == 3) {
// Collect and validate user input for First Name.
try {
customer.setFirstName(DataEntry.inputStringWithLimit("First Name (max 15 chars): ", 15));
} catch (IllegalArgumentException e) {
System.out.println("First Name must not contain numbers or special characters. Try again.");
continue;
}
inputCount++;
System.out.println("First Name must not contain numbers (0-9) "
+ "or special characters (!@#$%^&*(){}[]|). Try again.");
}
// Collect and validate Street Address
while (inputCount == 4) {
// Collect and validate user input for Street Address.
try {
customer.setStreet(DataEntry.inputStringWithLimit("Street (max 20 chars): ", 20));
} catch (IllegalArgumentException e) {
System.out.println("Street must be no more than 20 valid characters. Try again.");
continue;
}
inputCount++;
System.out.println("Street must be no more than 20 characters consisting of "
+ "numbers, letters, spaces, and \" . , - ' \". Try again.");
}
// Collect and validate City
while (inputCount == 5) {
// Collect and validate user input for City.
try {
customer.setCity(DataEntry.inputStringWithLimit("City (max 20 chars): ", 20));
} catch (IllegalArgumentException e) {
System.out.println("City must not contain numbers or special characters. Try again.");
continue;
}
inputCount++;
System.out.println("City must not contain numbers (0-9) or special characters "
+ "(!@#$%^&*(){}[]|). Try again.");
}
// Collect and validate State
while (inputCount == 6) {
// Collect and validate user input for State.
try {
customer.setState(DataEntry.inputStringWithLimit("State (2 chars): ", 2));
} catch (IllegalArgumentException e) {
} catch (InputMismatchException e) {
System.out.println("State must be 2 letters only. Try again.");
continue;
}
inputCount++;
}
// Collect and validate ZIP code
while (inputCount == 7) {
// Collect and validate user input for Zip Code.
try {
customer.setZip(DataEntry.inputNumericString("Zip (5 numeric chars): ", 5));
} catch (IllegalArgumentException e) {
System.out.println("Zip must be exactly 5 digits. Try again.");
continue;
}
inputCount++;
} catch (NumberFormatException e) {
System.out.println("Zip Code must only contain 5 digits. Try again.");
}
// Collect and validate Phone Number
while (inputCount == 8) {
// Collect and validate user input for Phone Number.
try {
customer.setPhone(DataEntry.inputNumericString("Phone (10 numeric chars): ", 10));
} catch (IllegalArgumentException e) {
System.out.println("Phone number must be 10 digits only. Try again.");
continue;
}
inputCount++;
} catch (NumberFormatException e) {
System.out.println("Phone Number must only contain 9 digits.");
}
// Add customer instance to customers ArrayList
// Store Customer information to the Customer instance.
customers.add(customer);
// Collect and validate Account Type
while (inputCount == 9) {
try {
String accountType = DataEntry.inputStringWithLimit("Account type ('CHK' or 'SAV' only): ", 3).toUpperCase();
if (accountType.equals("CHK")) {
account = new CheckingAccount();
account.setAccountType("CHK");
} else if (accountType.equals("SAV")) {
account = new SavingsAccount();
account.setAccountType("SAV");
} else {
throw new IllegalArgumentException("Account type must be 'CHK' or 'SAV'.");
}
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
}
inputCount++;
}
// Collect and validate Account Number
while (inputCount == 10) {
// Account Information:
// Collect and validate user input for Account Number.
try {
account.setAccountNumber(DataEntry.inputNumericString("Account Number (5 numeric chars): ", 5));
} catch (IllegalArgumentException e) {
System.out.println("Account number must be exactly 5 digits. Try again.");
continue;
}
inputCount++;
} catch (NumberFormatException e) {
System.out.println("Account Number can only be 5 digits. Try again.");
}
// Collect and validate Service Fee Amount
while (inputCount == 11) {
// Collect and validate user input for Account Type.
try {
account.setSvcFee(DataEntry.inputDecimalInRange("Service Fee (0.00 to 10.00): $", 0.00, 10.00));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
boolean validAcctType = false;
while (!validAcctType) {
String input = DataEntry.inputStringWithLimit("Account type ('CHK' or 'SVG' only): ", 3);
if (input.equalsIgnoreCase("CHK") || input.equalsIgnoreCase("SAV")) {
account.setAccountType(input.toUpperCase());
validAcctType = true;
} else {
System.out.println("Input for Account Type can only be 'CHK' or 'SVG'. Try again.");
}
inputCount++;
}
} catch (InputMismatchException e) {
System.out.println("Invalid input. Please try again.");
}
// Collect and validate Interest Rate Amount
while (inputCount == 12) {
// Collect and validate user input for Service Fee.
try {
account.setInterestRate(DataEntry.inputDecimalInRange("Interest Rate (0.0% to 10.0%): ", 0.0, 10.0));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
}
inputCount++;
account.setSvcFee(DataEntry.inputDecimalInRange("Service Fee Amount (in dollars and cents): $", 0.00, 10.00));
} catch (InputMismatchException e) {
System.out.println("Input must be a dollar amount between $0.00 - $10.00. Try again.");
}
// Collect and validate Overdraft Fee Amount
while (inputCount == 13) {
// Collect and validate user input for Interest Rate.
try {
account.setOverDraftFee(DataEntry.inputDecimal("Overdraft Fee (dollars and cents): $"));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
}
inputCount++;
account.setInterestRate(DataEntry.inputDecimalInRange("Interest Rate (percent between 0.0% and 10.0%: ", 0.0, 10.0));
} catch (InputMismatchException e) {
System.out.println("Interest Rate must be entered as a decimial between 0.0% - 10.0%. Try again.");
}
// Collect and validate Starting Balance
while (inputCount == 14) {
// Collect and validate user input for Overdraft Fee.
try {
account.setBalance(DataEntry.inputDecimal("Starting Balance (dollars and cents): $"));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
}
inputCount++;
account.setOverDraftFee(DataEntry.inputDecimal("Overdraft Fee Amount (in dollars and cents): $"));
} catch (InputMismatchException e) {
System.out.println("Input must be a dollar amount between $0.00 and $10.00");
}
// Add account instance to accounts ArrayList
// Collect and validate user input for Current Balance.
try {
account.setBalance(DataEntry.inputDecimal("Starting Balance (in dollars and cents): $"));
} catch (InputMismatchException e) {
System.out.println("Current Balance must be in dollars and cents. Try again.");
}
// Add the Account class instance to the accounts ArrayList
accounts.add(account);
// Ask if more customers should be added
// Prompt user to add additional customers or quit.
String more = DataEntry.inputStringWithLimit("\nAdd another customer? (y/n): ", 1);
moreCustomers = more.equalsIgnoreCase("y");
System.out.println();
}
// Handle transactions
boolean addTransactionDetails = true;
// Start do-while loop add transaction details to any accounts
do {
String promptAddTransactions = DataEntry.inputStringWithLimit("Would you like to enter transaction details for an account? (y/n): ", 1).toUpperCase();
if (!promptAddTransactions.equals("Y") && !promptAddTransactions.equals("N")) {
System.out.println("Please enter 'Y' or 'N' only.");
continue; // Prompt again if invalid input
} else if (promptAddTransactions.equalsIgnoreCase("N")) {
addTransactionDetails = false; // Exit the loop and proceed to report generation
} else if (promptAddTransactions.equalsIgnoreCase("Y")) {
boolean addTransactionsToAcct = true;
// Start do-while loop to add transaction entries to a specified account
do {
// Prompt for account number
String accountNumber = DataEntry.inputNumericString("Enter Account Number (5 digits): ", 5);
// Find account and corresponding customer
Account selectedAccount = null;
Customer selectedCustomer = null;
for (int i = 0; i < accounts.size(); i++) {
if (accounts.get(i).getAccountNumber().equals(accountNumber)) {
selectedAccount = accounts.get(i);
selectedCustomer = customers.get(i);
break;
if (more.equalsIgnoreCase("n")) {
moreCustomers = false;
}
}
if (selectedAccount == null) {
System.out.println("Account not found. Please try again.\n");
continue; // Prompt for account number again if not found
}
// Print out the results so that each Customer instance and its corresponding Account instance are
// printed together, and so the program iterates through all of the instance pairs in their respective ArrayLists.
System.out.println("\n========================================\n");
for (int i = 0; i < customers.size(); i++) {
// Display customer details for verification
System.out.println("Customer Information:");
System.out.println(selectedCustomer);
// Add transactions for the selected account
boolean newTransaction = true;
// Start do-while loop for "newTransactions
do {
String transaction = null;
int transactionStep = 0;
String transactionType = "";
String transactionDate = "";
try {
while (transactionStep == 0) {
transactionType = DataEntry.inputStringWithLimit("\nTransaction Type ('DEP', 'WTH', or 'INT'): ", 3).toUpperCase();
if (!transactionType.equals("DEP") && !transactionType.equals("WTH") && !transactionType.equals("INT")) {
System.out.println("Invalid transaction type. Please try again.");
} else {
transactionStep++;
}
}
} catch (IllegalArgumentException e) {
System.out.println("Type must be 'DEP', 'WTH', or 'INT' only. Try again");
}
while (transactionStep == 1) {
transactionDate = DataEntry.inputDate("Enter the transaction date (MM/DD/YYYY): ");
transactionStep++;
}
while (transactionStep == 2) {
double amount = 0;
if (!transactionType.equals("INT")) {
amount = DataEntry.inputDecimal("Transaction Amount: $");
}
try {
if (transactionType.equals("DEP")) {
selectedAccount.deposit(amount);
transaction = selectedAccount.logTransaction(transactionDate, "DEP", amount);
} else if (transactionType.equals("WTH")) {
selectedAccount.withdrawal(amount);
transaction = selectedAccount.logTransaction(transactionDate, "WTH", amount);
} else if (transactionType.equals("INT")) {
double interest = selectedAccount.applyAccruedInterest(transactionDate);
transaction = selectedAccount.logTransaction(transactionDate, "INT", interest);
}
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
continue;
}
System.out.println(transaction + "\n");
// Ask if another transaction should be entered for this account
String anotherNewTransaction = DataEntry.inputStringWithLimit("Add another transaction for this account? (y/n): ", 1);
if (!anotherNewTransaction.equalsIgnoreCase("N") && !anotherNewTransaction.equalsIgnoreCase("Y")) {
System.out.println("Please enter 'Y' or 'N' only.");
continue;
}else if (anotherNewTransaction.equalsIgnoreCase("N")) {
newTransaction = false;
break;
}else if (anotherNewTransaction.equalsIgnoreCase("Y")) {
transactionStep = 0;
}
}
}while (newTransaction);
// Ask if another account's transactions should be entered
String otherAcctTransactions = DataEntry.inputStringWithLimit("Enter transactions for another account? (y/n): ", 1);
if (!otherAcctTransactions.equalsIgnoreCase("N") && !otherAcctTransactions.equalsIgnoreCase("y")) {
System.out.println("Please enter 'Y' or 'N' only.");
continue;
} else if (otherAcctTransactions.equalsIgnoreCase("N")) {
addTransactionsToAcct = false;
break;
}
} while (addTransactionsToAcct);
}
} while (addTransactionDetails);
// Generate final report (this part should be in your existing code)
System.out.println("\n------------------------------|Final Report|-------------------------------");
for (int i = 0; i < accounts.size(); i++) {
// Use [int i] for both ArrayLists to ensure the correct Accounts instance is
// printed with the corresponding Customer instance.
Customer customer = customers.get(i);
Account account = accounts.get(i);
System.out.println(customer);
System.out.println("Account Details:");
System.out.println(customer + "\n");
System.out.println(account);
System.out.println("---------------------------------------------------------"
+ "----------------------------------------------------------------------------");
System.out.println("Transactions:");
for (String transaction : account.getTransactionHistory()) {
System.out.println(transaction);
}
System.out.println("------------------------------|End Report|-------------------------------");
}
}
}

View File

@ -1,763 +0,0 @@
/* Phase IV */
package bankAcctApp;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class BankAcctAppGUI extends JFrame {
private JButton addCustomerBtn, addTransactionBtn, viewInfoBtn;
private ArrayList<Customer> customers;
private ArrayList<Account> accounts;
public BankAcctAppGUI(ArrayList<Customer> customers, ArrayList<Account> accounts) {
super("Bank Account Application");
this.customers = customers;
this.accounts = accounts;
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
addCustomerBtn = new JButton("Add Customer and Account");
addCustomerBtn.setPreferredSize(new Dimension(200, 50));
addTransactionBtn = new JButton("Add Transactions to Existing Account");
addTransactionBtn.setPreferredSize(new Dimension(200, 50));
viewInfoBtn = new JButton("View Customer Account Info");
viewInfoBtn.setPreferredSize(new Dimension(200, 50));
mainPanel.add(addCustomerBtn);
mainPanel.add(addTransactionBtn);
mainPanel.add(viewInfoBtn);
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(mainPanel);
add(centerPanel, BorderLayout.CENTER);
addCustomerBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showAddCustomerPanel();
}
});
addTransactionBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showAddTransactionPanel();
}
});
viewInfoBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showViewInfoPanel();
}
});
setVisible(true);
}
private void showAddCustomerPanel() {
JFrame addCustomerFrame = new JFrame("Add Customer and Account");
addCustomerFrame.setSize(800, 600);
addCustomerFrame.setLayout(new BorderLayout());
JPanel customerPanel = new JPanel(new GridBagLayout());
JPanel accountPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
// Customer Information
gbc.gridx = 0;
gbc.gridy = 0;
customerPanel.add(new JLabel("Customer ID:"), gbc);
gbc.gridx = 1;
JTextField idTxtFld = new JTextField(15);
customerPanel.add(idTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
customerPanel.add(new JLabel("SSN:"), gbc);
gbc.gridx = 1;
JTextField ssnTxtFld = new JTextField(15);
customerPanel.add(ssnTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
customerPanel.add(new JLabel("Last Name:"), gbc);
gbc.gridx = 1;
JTextField lastNameTxtFld = new JTextField(15);
customerPanel.add(lastNameTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
customerPanel.add(new JLabel("First Name:"), gbc);
gbc.gridx = 1;
JTextField firstNameTxtFld = new JTextField(15);
customerPanel.add(firstNameTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
customerPanel.add(new JLabel("Street Address:"), gbc);
gbc.gridx = 1;
JTextField streetTxtFld = new JTextField(15);
customerPanel.add(streetTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
customerPanel.add(new JLabel("City:"), gbc);
gbc.gridx = 1;
JTextField cityTxtFld = new JTextField(15);
customerPanel.add(cityTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 6;
customerPanel.add(new JLabel("State:"), gbc);
gbc.gridx = 1;
String[] states = {
"AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA",
"HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD",
"MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ",
"NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC",
"SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"
};
JComboBox<String> stateDropdown = new JComboBox<>(states);
customerPanel.add(stateDropdown, gbc);
gbc.gridx = 0;
gbc.gridy = 7;
customerPanel.add(new JLabel("ZIP Code:"), gbc);
gbc.gridx = 1;
JTextField zipTxtFld = new JTextField(15);
customerPanel.add(zipTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 8;
customerPanel.add(new JLabel("Phone:"), gbc);
gbc.gridx = 1;
JTextField phoneTxtFld = new JTextField(10);
customerPanel.add(phoneTxtFld, gbc);
// Account Information
gbc.gridx = 0;
gbc.gridy = 0;
accountPanel.add(new JLabel("Account Number:"), gbc);
gbc.gridx = 1;
JTextField acctNumTxtFld = new JTextField(15);
accountPanel.add(acctNumTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
accountPanel.add(new JLabel("Account Type:"), gbc);
gbc.gridx = 1;
JRadioButton chkRadio = new JRadioButton("Checking");
JRadioButton savRadio = new JRadioButton("Savings");
ButtonGroup acctTypeGroup = new ButtonGroup();
acctTypeGroup.add(chkRadio);
acctTypeGroup.add(savRadio);
JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
radioPanel.add(chkRadio);
radioPanel.add(savRadio);
accountPanel.add(radioPanel, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
accountPanel.add(new JLabel("Service Fee:"), gbc);
gbc.gridx = 1;
JTextField svcFeeTxtFld = new JTextField(15);
accountPanel.add(svcFeeTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
accountPanel.add(new JLabel("Interest Rate:"), gbc);
gbc.gridx = 1;
JTextField intRateTxtFld = new JTextField(15);
accountPanel.add(intRateTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
accountPanel.add(new JLabel("Overdraft Fee: "), gbc);
gbc.gridx = 1;
JTextField ovDrftTxtFld = new JTextField(15);
accountPanel.add(ovDrftTxtFld, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
accountPanel.add(new JLabel("Starting Balance:"), gbc);
gbc.gridx = 1;
JTextField startBalTxtFld = new JTextField(15);
accountPanel.add(startBalTxtFld, gbc);
JPanel buttonPanel = new JPanel();
JButton saveBtn = new JButton("Save");
JButton clearBtn = new JButton("Clear");
JButton cancelBtn = new JButton("Cancel");
buttonPanel.add(saveBtn);
buttonPanel.add(clearBtn);
buttonPanel.add(cancelBtn);
addCustomerFrame.add(customerPanel, BorderLayout.NORTH);
addCustomerFrame.add(accountPanel, BorderLayout.CENTER);
addCustomerFrame.add(buttonPanel, BorderLayout.SOUTH);
addCustomerFrame.setVisible(true);
// Add action listeners for buttons
saveBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("--Action Event-- saveBtn clicked DataEntry validation engine starting.");
try {
// Create a new instance of Customer and Account at the beginning
System.out.println("Attempting to create new Customer.");
Customer customer = new Customer();
System.out.println("New Customer created.");
System.out.println("\nStarting Customer Information validation.");
// ----------------- Customer Information -----------------
System.out.println("Starting [id] validation.");
String id = idTxtFld.getText().trim();
DataEntry.inputIDGUI(id); // Use the GUI-specific validation method for ID
customer.setID(id);
System.out.println("[id] validated.");
System.out.println("Starting [ssn] validation.");
String ssn = ssnTxtFld.getText().trim();
DataEntry.inputSSNGUI(ssn); // Use the GUI-specific validation method for SSN
customer.setSSN(ssn);
System.out.println("[ssn] validated.");
System.out.println("Starting [lastName] validation.");
String lastName = lastNameTxtFld.getText().trim();
DataEntry.inputLastNameGUI(lastName); // Use the GUI-specific validation method for last name
customer.setLastName(lastName);
System.out.println("[lastName] validated.");
System.out.println("Starting [firstName] validation.");
String firstName = firstNameTxtFld.getText().trim();
DataEntry.inputFirstNameGUI(firstName); // Use the GUI-specific validation method for first name
customer.setFirstName(firstName);
System.out.println("[firstName] validated.");
System.out.println("Starting [street] validation.");
String street = streetTxtFld.getText().trim();
DataEntry.inputStreetGUI(street); // Use the GUI-specific validation method for street
customer.setStreet(street);
System.out.println("[street] validated.");
System.out.println("Starting [city] validation.");
String city = cityTxtFld.getText().trim();
DataEntry.inputCityGUI(city); // Use the GUI-specific validation method for city
customer.setCity(city);
System.out.println("[city] validated");
// Handle dropdown for State
System.out.println("Starting [state] validation.");
String state = (String) stateDropdown.getSelectedItem();
if (state == null || state.isEmpty()) {
throw new IllegalArgumentException("State must be selected.");
}
customer.setState(state);
System.out.println("[state] validated.");
System.out.println("Starting [zip] validation.");
String zip = zipTxtFld.getText().trim();
DataEntry.inputZipGUI(zip); // Use the GUI-specific validation method for zip
customer.setZip(zip);
System.out.println("[zip] validated.");
System.out.println("Starting [phone] validation.");
String phone = phoneTxtFld.getText().trim();
DataEntry.inputPhoneGUI(phone); // Use the GUI-specific validation method for phone
customer.setPhone(phone);
System.out.println("[phone] validated.");
System.out.println("Customer Information validation completed.");
// ----------------- Account Information -----------------
// Create Null account object
Account account = null;
// Determine account type
System.out.println("Checking for account type.");
System.out.println("Attempting to create new account.");
if (chkRadio.isSelected()) {
account = new CheckingAccount();
account.setAccountType("CHK");
System.out.println("Account type accepted.");
System.out.println("New Checking Account created.");
} else if (savRadio.isSelected()) {
account = new SavingsAccount();
account.setAccountType("SAV");
System.out.println("Account type accepted.");
System.out.println("New Savings Account created.");
} else {
throw new IllegalArgumentException("Account type must be selected.");
}
// Account number validation
System.out.println("Starting [accountNumber] validation.");
String accountNumber = acctNumTxtFld.getText().trim();
DataEntry.inputNumericStringGUI(accountNumber, 5); // Use GUI-specific validation method for account number
account.setAccountNumber(accountNumber); // Set account number in the account instance
System.out.println("[accountNumber] validated.");
// Service fee validation
System.out.println("Starting [svcFee] validation.");
String svcFeeStr = svcFeeTxtFld.getText().trim();
try {
double svcFee = DataEntry.inputDecimalInRangeGUI(svcFeeStr, 0.00, 10.00); // Validate and convert to double
account.setSvcFee(svcFee); // Set service fee in the same Account instance
System.out.println("[svcFee] validated.");
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(addCustomerFrame, ex.getMessage(), "Input Error", JOptionPane.ERROR_MESSAGE);
return; // Prevent further processing if invalid input
}
// Interest rate validation
System.out.println("Starting [interestRate] validation.");
String intRateStr = intRateTxtFld.getText().trim();
try {
double interestRate = DataEntry.inputDecimalInRangeGUI(intRateStr, 0.0, 10.0); // Validate and convert to double
account.setInterestRate(interestRate); // Set interest rate
System.out.println("[interestRate] validated.");
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(addCustomerFrame, ex.getMessage(), "Input Error", JOptionPane.ERROR_MESSAGE);
return; // Prevent further processing if invalid input
}
// Overdraft fee validation
System.out.println("Starting [overdraftFee] validation.");
String ovDrftFeeStr = ovDrftTxtFld.getText().trim();
try {
double overdraftFee = DataEntry.inputDecimalGUI(ovDrftFeeStr); // Validate and convert to double
account.setOverDraftFee(overdraftFee); // Set overdraft fee
System.out.println("[overdraftFee] validated.");
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(addCustomerFrame, ex.getMessage(), "Input Error", JOptionPane.ERROR_MESSAGE);
return; // Prevent further processing if invalid input
}
// Starting balance validation
System.out.println("Starting [startingBalance] validation.");
String startBalStr = startBalTxtFld.getText().trim();
try {
double startingBalance = DataEntry.inputDecimalGUI(startBalStr); // Validate and convert to double
account.setBalance(startingBalance); // Set starting balance
System.out.println("[startingBalance] validated.");
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(addCustomerFrame, ex.getMessage(), "Input Error", JOptionPane.ERROR_MESSAGE);
return; // Prevent further processing if invalid input
}
// ----------------- Add to Collections -----------------
System.out.println("Adding customer instance to customers collection.");
customers.add(customer); // Add customer to collection
System.out.println("Customer was successfully added.");
System.out.println("Adding account instance to accounts collection.");
accounts.add(account); // Add account to collection
System.out.println("Account was successfully added.");
// ----------------- Success Message -----------------
JOptionPane.showMessageDialog(addCustomerFrame, "Customer and Account added successfully!");
// ----------------- Clear Fields -----------------
System.out.println("Clearing JTextField form controls.");
idTxtFld.setText("");
ssnTxtFld.setText("");
lastNameTxtFld.setText("");
firstNameTxtFld.setText("");
streetTxtFld.setText("");
cityTxtFld.setText("");
stateDropdown.setSelectedIndex(0);
zipTxtFld.setText("");
phoneTxtFld.setText("");
acctNumTxtFld.setText("");
svcFeeTxtFld.setText("");
intRateTxtFld.setText("");
ovDrftTxtFld.setText("");
startBalTxtFld.setText("");
System.out.println("JTextField form controls cleared successfully.");
} catch (IllegalArgumentException ex) {
// Display validation error message and keep fields unchanged for correction
JOptionPane.showMessageDialog(addCustomerFrame, ex.getMessage(), "Validation Error", JOptionPane.ERROR_MESSAGE);
}
}
});
clearBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Clear all text fields
System.out.println("--Action Event-- clearBtn clicked.");
System.out.println("Clearing JTextField form controls.");
idTxtFld.setText("");
ssnTxtFld.setText("");
lastNameTxtFld.setText("");
firstNameTxtFld.setText("");
streetTxtFld.setText("");
cityTxtFld.setText("");
stateDropdown.setSelectedIndex(0);
zipTxtFld.setText("");
acctNumTxtFld.setText("");
svcFeeTxtFld.setText("");
intRateTxtFld.setText("");
ovDrftTxtFld.setText("");
startBalTxtFld.setText("");
System.out.println("JTextField form controls cleared successfully.");
}
});
cancelBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("--Action Event-- cancelBtn Clicked -- Operation canceled.");
addCustomerFrame.dispose();
}
});
}
private void showAddTransactionPanel() {
JFrame addTransactionFrame = new JFrame("Add Transaction");
addTransactionFrame.setSize(800, 600);
addTransactionFrame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
// Account Number
gbc.gridx = 0;
gbc.gridy = 0;
addTransactionFrame.add(new JLabel("Account Number:"), gbc);
gbc.gridx = 1;
JTextField acctNumTxtFld = new JTextField(15);
addTransactionFrame.add(acctNumTxtFld, gbc);
// Transaction Type (Radio Buttons for Deposit or Withdrawal)
gbc.gridx = 0;
gbc.gridy = 1;
addTransactionFrame.add(new JLabel("Transaction Type:"), gbc);
gbc.gridx = 1;
// Create the radio buttons for deposit and withdrawal types
JRadioButton depositButton = new JRadioButton("Deposit");
JRadioButton withdrawalButton = new JRadioButton("Withdrawal");
// Group the radio buttons
ButtonGroup transactionTypeGroup = new ButtonGroup();
transactionTypeGroup.add(depositButton);
transactionTypeGroup.add(withdrawalButton);
// Add the radio buttons to the panel
JPanel transactionTypePanel = new JPanel();
transactionTypePanel.add(depositButton);
transactionTypePanel.add(withdrawalButton);
addTransactionFrame.add(transactionTypePanel, gbc);
// Date (Transaction Date)
gbc.gridx = 0;
gbc.gridy = 2;
addTransactionFrame.add(new JLabel("Transaction Date (MM/dd/yyyy):"), gbc);
gbc.gridx = 1;
JTextField dateTxtFld = new JTextField(15);
addTransactionFrame.add(dateTxtFld, gbc);
// Amount (For deposit/withdrawal)
gbc.gridx = 0;
gbc.gridy = 3;
addTransactionFrame.add(new JLabel("Amount:"), gbc);
gbc.gridx = 1;
JTextField amountTxtFld = new JTextField(15);
addTransactionFrame.add(amountTxtFld, gbc);
// Apply Interest Button
JButton applyInterestBtn = new JButton("Apply Interest");
gbc.gridx = 0;
gbc.gridy = 4;
addTransactionFrame.add(applyInterestBtn, gbc);
// Submit Button
gbc.gridx = 2;
gbc.gridy = 4;
JButton submitBtn = new JButton("Submit");
addTransactionFrame.add(submitBtn, gbc);
// Transaction History
gbc.gridx = 0;
gbc.gridy = 5;
addTransactionFrame.add(new JLabel("Transaction History:"), gbc);
gbc.gridx = 1;
JTextArea transactionHistoryArea = new JTextArea(10, 40);
transactionHistoryArea.setEditable(false);
addTransactionFrame.add(new JScrollPane(transactionHistoryArea), gbc);
addTransactionFrame.setVisible(true);
// Action listener for Apply Interest button
applyInterestBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String accountNumber = acctNumTxtFld.getText();
String transactionDate = dateTxtFld.getText();
Account selectedAccount = null;
Customer selectedCustomer = null;
// Validate the date format (MM/dd/yyyy)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
try {
LocalDate.parse(transactionDate, formatter); // Check if the date is valid
} catch (DateTimeParseException ex) {
JOptionPane.showMessageDialog(addTransactionFrame, "Invalid date format. Please use MM/dd/yyyy.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
// Find the account and customer based on the account number
for (int i = 0; i < accounts.size(); i++) {
if (accounts.get(i).getAccountNumber().equals(accountNumber)) {
selectedAccount = accounts.get(i);
selectedCustomer = customers.get(i);
break;
}
}
// Handle interest application if account found
if (selectedAccount != null && selectedCustomer != null) {
// Apply interest to the account
selectedAccount.applyAccruedInterest(transactionDate);
// Log the interest applied transaction
String transaction = selectedAccount.logTransaction(transactionDate, "Interest Applied", 0);
// Update transaction history display
StringBuilder historyText = new StringBuilder();
for (String trans : selectedAccount.getTransactionHistory()) {
historyText.append(trans).append("\n");
}
transactionHistoryArea.setText(historyText.toString());
} else {
JOptionPane.showMessageDialog(addTransactionFrame, "Account not found.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
// Action listener for Submit button (Deposit/Withdrawal)
submitBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String accountNumber = acctNumTxtFld.getText();
String transactionDate = dateTxtFld.getText();
Account selectedAccount = null;
Customer selectedCustomer = null;
// Validate the date format (MM/dd/yyyy)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
try {
LocalDate.parse(transactionDate, formatter); // Check if the date is valid
} catch (DateTimeParseException ex) {
JOptionPane.showMessageDialog(addTransactionFrame, "Invalid date format. Please use MM/dd/yyyy.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
// Find the account and customer based on the account number
for (int i = 0; i < accounts.size(); i++) {
if (accounts.get(i).getAccountNumber().equals(accountNumber)) {
selectedAccount = accounts.get(i);
selectedCustomer = customers.get(i);
break;
}
}
// Handle deposit/withdrawal if account found
if (selectedAccount != null && selectedCustomer != null) {
String transactionType = "";
double amount = 0;
if (depositButton.isSelected()) {
transactionType = "Deposit";
amount = Double.parseDouble(amountTxtFld.getText());
} else if (withdrawalButton.isSelected()) {
transactionType = "Withdrawal";
amount = Double.parseDouble(amountTxtFld.getText());
}
// Process Deposit or Withdrawal
String transaction = "";
switch (transactionType) {
case "Deposit":
selectedAccount.deposit(amount);
transaction = selectedAccount.logTransaction(transactionDate, "Deposit", amount);
break;
case "Withdrawal":
selectedAccount.withdrawal(amount);
transaction = selectedAccount.logTransaction(transactionDate, "Withdrawal", amount);
break;
}
// Update the transaction history display
StringBuilder historyText = new StringBuilder();
for (String trans : selectedAccount.getTransactionHistory()) {
historyText.append(trans).append("\n");
}
transactionHistoryArea.setText(historyText.toString());
} else {
JOptionPane.showMessageDialog(addTransactionFrame, "Account not found.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
}
private void showViewInfoPanel() {
JFrame viewInfoFrame = new JFrame("View Customer and Account Info");
viewInfoFrame.setSize(800, 600);
viewInfoFrame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
// Account Number
gbc.gridx = 0;
gbc.gridy = 0;
viewInfoFrame.add(new JLabel("Account Number:"), gbc);
gbc.gridx = 1;
JTextField acctNumTxtFld = new JTextField(15);
viewInfoFrame.add(acctNumTxtFld, gbc);
// Submit Button
gbc.gridx = 2;
gbc.gridy = 0;
JButton submitBtn = new JButton("Submit");
viewInfoFrame.add(submitBtn, gbc);
// Customer and Account Info Labels
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
viewInfoFrame.add(new JLabel("Customer ID:"), gbc);
gbc.gridx = 1;
JLabel idLabel = new JLabel();
viewInfoFrame.add(idLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
viewInfoFrame.add(new JLabel("SSN:"), gbc);
gbc.gridx = 1;
JLabel ssnLabel = new JLabel();
viewInfoFrame.add(ssnLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
viewInfoFrame.add(new JLabel("Last Name:"), gbc);
gbc.gridx = 1;
JLabel lastNameLabel = new JLabel();
viewInfoFrame.add(lastNameLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
viewInfoFrame.add(new JLabel("First Name:"), gbc);
gbc.gridx = 1;
JLabel firstNameLabel = new JLabel();
viewInfoFrame.add(firstNameLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
viewInfoFrame.add(new JLabel("Street Address:"), gbc);
gbc.gridx = 1;
JLabel streetLabel = new JLabel();
viewInfoFrame.add(streetLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 6;
viewInfoFrame.add(new JLabel("City:"), gbc);
gbc.gridx = 1;
JLabel cityLabel = new JLabel();
viewInfoFrame.add(cityLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 7;
viewInfoFrame.add(new JLabel("State:"), gbc);
gbc.gridx = 1;
JLabel stateLabel = new JLabel();
viewInfoFrame.add(stateLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 8;
viewInfoFrame.add(new JLabel("ZIP Code:"), gbc);
gbc.gridx = 1;
JLabel zipLabel = new JLabel();
viewInfoFrame.add(zipLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 9;
viewInfoFrame.add(new JLabel("Phone:"), gbc);
gbc.gridx = 1;
JLabel phoneLabel = new JLabel();
viewInfoFrame.add(phoneLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 10;
viewInfoFrame.add(new JLabel("Account Type:"), gbc);
gbc.gridx = 1;
JLabel acctTypeLabel = new JLabel();
viewInfoFrame.add(acctTypeLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 11;
viewInfoFrame.add(new JLabel("Balance:"), gbc);
gbc.gridx = 1;
JLabel balanceLabel = new JLabel();
viewInfoFrame.add(balanceLabel, gbc);
// Transaction History Section
gbc.gridx = 0;
gbc.gridy = 12;
viewInfoFrame.add(new JLabel("Transaction History:"), gbc);
gbc.gridx = 1;
gbc.gridy = 12;
gbc.gridwidth = 3;
JTextArea transactionHistoryArea = new JTextArea(10, 40);
transactionHistoryArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(transactionHistoryArea);
viewInfoFrame.add(scrollPane, gbc);
// Done Button
JButton doneBtn = new JButton("Done");
gbc.gridx = 2;
gbc.gridy = 13;
viewInfoFrame.add(doneBtn, gbc);
viewInfoFrame.setVisible(true);
// Add action listener for the submit button
submitBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Retrieve and display customer and account info
String accountNumber = acctNumTxtFld.getText();
Account selectedAccount = null;
Customer selectedCustomer = null;
for (int i = 0; i < accounts.size(); i++) {
if (accounts.get(i).getAccountNumber().equals(accountNumber)) {
selectedAccount = accounts.get(i);
selectedCustomer = customers.get(i);
break;
}
}
if (selectedAccount != null && selectedCustomer != null) {
idLabel.setText(selectedCustomer.getID());
ssnLabel.setText(selectedCustomer.getSSN());
lastNameLabel.setText(selectedCustomer.getLastName());
firstNameLabel.setText(selectedCustomer.getFirstName());
streetLabel.setText(selectedCustomer.getStreet());
cityLabel.setText(selectedCustomer.getCity());
stateLabel.setText(selectedCustomer.getState());
zipLabel.setText(selectedCustomer.getZip());
phoneLabel.setText(selectedCustomer.getPhone());
acctTypeLabel.setText(selectedAccount.getAccountType());
balanceLabel.setText(String.format("$%.2f", selectedAccount.getBalance()));
// Populate transaction history
StringBuilder transactionHistoryText = new StringBuilder();
for (String transaction : selectedAccount.getTransactionHistory()) {
transactionHistoryText.append(transaction).append("\n");
}
transactionHistoryArea.setText(transactionHistoryText.toString());
} else {
JOptionPane.showMessageDialog(viewInfoFrame, "Account not found.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
// Add action listener for the done button
doneBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
viewInfoFrame.dispose(); // Close the window when done is clicked
}
});
}
public static void main(String[] args) {
ArrayList<Customer> customers = new ArrayList<>();
ArrayList<Account> accounts = new ArrayList<>();
new BankAcctAppGUI(customers, accounts);
}
}

View File

@ -1,43 +0,0 @@
/* Phase IV */
package bankAcctApp;
//Class representing checking accounts
public class CheckingAccount extends Account {
// Overridden method for withdrawals in checking accounts
@Override
public void withdrawal(double amount) {
double newBalance = getBalance() - amount - getSvcFee(); // Deduct amount and service fee
if (newBalance < 0) { // Check for overdraft
newBalance -= getOverDraftFee(); // Apply overdraft fee if balance is negative
}
setBalance(newBalance); // Update balance
}
// Overridden method for deposits in checking accounts
@Override
public void deposit(double amount) {
setBalance(getBalance() + amount - getSvcFee()); // Add amount and deduct service fee
}
// Overridden method for applying accrued interest in checking accounts
@Override
public double applyAccruedInterest(String transactionDate) {
double interest = 0.0;
if (getBalance() <= 0.0) { // Ensure balance is positive for interest accrual
System.out.println("This account has an insufficient balance for interest to apply.");
} else {
interest = getBalance() * (getInterestRate() / 100); // Calculate interest
setBalance(getBalance() + interest); // Add interest to the balance
logTransaction(transactionDate, "INT", interest); // Log the interest transaction
}
return interest;
}
// Implementation of balance() method from AccountInterface
@Override
public double balance() {
return getBalance(); // Return the current balance
}
}

View File

@ -1,4 +1,4 @@
/* Phase IV */
/* Phase II */
package bankAcctApp;
@ -101,6 +101,7 @@ public class Customer {
@Override
public String toString() {
return String.format(
"Customer Information:\n" +
"---------------------\n" +
"ID: Last Name: First Name: SSN: Phone: Street: City: ST: ZIP: \n" +
"--- ---------- ----------- ---- ------ ------- ----- --- ---- \n" +
@ -108,7 +109,4 @@ public class Customer {
id, lastName, firstName, ssn, phone, street, city, state, zip
);
}
public Object getAccountNumber() {
return null;
}
}

View File

@ -1,4 +1,4 @@
/* Phase IV */
/* Phase II */
package bankAcctApp;
@ -73,7 +73,7 @@ public class DataEntry {
return input;
}
// Static method to validate decimals (specific to the CLI)
// Static method to validate decimals.
public static double inputDecimal(String prompt) {
boolean isValid = false;
double decimalValue = 0.0;
@ -91,7 +91,7 @@ public class DataEntry {
return decimalValue;
}
// Static method to validate decimals are within a range (specific to the CLI)
// Static method to validate decimals are within a range.
public static double inputDecimalInRange(String prompt, double min, double max) {
double value;
do {
@ -105,108 +105,21 @@ public class DataEntry {
return value;
}
// Static method to validate a date in MM/DD/YYYY format.
public static String inputDate(String prompt) {
Pattern patternDate = Pattern.compile("^(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])/(\\d{4})$");
String date = "";
System.out.print(prompt);
while (date.isEmpty()) {
do {
String input = in.nextLine();
if (patternDate.matcher(input).matches()) {
date = input;
return date;
return input;
} else {
System.out.print("Invalid date. Please try again: ");
in.next();
}
}
in.nextLine();
} while (date.isEmpty());
return date;
}
// Validation methods specific to the GUI
// Reusable patterns for string v // Reusable patterns for string validation (no prompt messages, just validation)
private static final Pattern patternID = Pattern.compile("[A-Z0-9]{5}");
private static final Pattern patternSSN = Pattern.compile("[0-9]{9}");
private static final Pattern patternName = Pattern.compile("[A-Za-z\\s,\\.\\-']{1,20}");
private static final Pattern patternStreet = Pattern.compile("[0-9]+[A-Za-z\\s,\\.\\-]{1,19}");
private static final Pattern patternCity = Pattern.compile("[A-Za-z\\s]{1,20}");
private static final Pattern patternState = Pattern.compile("[A-Z]{2}");
private static final Pattern patternZip = Pattern.compile("[0-9]{5}");
private static final Pattern patternPhone = Pattern.compile("[0-9]{10}");
// Validate input for strings using regex (for GUI)
private static void validateInput(Pattern pattern, String input) {
if (!pattern.matcher(input).matches()) {
throw new IllegalArgumentException("Invalid input: " + input);
}
}
// Validate and convert string input to double
private static double validateAndConvertToDouble(String input) {
try {
return Double.parseDouble(input); // Convert to double
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Invalid decimal input: " + input);
}
}
// Validate and convert decimal numbers for account information within a range (for GUI)
public static double inputDecimalInRangeGUI(String input, double min, double max) {
double value = validateAndConvertToDouble(input); // Validate as double
if (value < min || value > max) {
throw new IllegalArgumentException("Value out of range: " + value);
}
return value;
}
// Validate decimal input (no range validation)
public static double inputDecimalGUI(String input) {
return validateAndConvertToDouble(input); // Simply convert the valid decimal input
}
// Field-specific validation methods for GUI
public static void inputIDGUI(String id) {
validateInput(patternID, id); // Validate ID format
}
public static void inputSSNGUI(String ssn) {
validateInput(patternSSN, ssn); // Validate SSN format
}
public static void inputLastNameGUI(String lastName) {
validateInput(patternName, lastName); // Validate last name format
}
public static void inputFirstNameGUI(String firstName) {
validateInput(patternName, firstName); // Validate first name format
}
public static void inputStreetGUI(String street) {
validateInput(patternStreet, street); // Validate street format
}
public static void inputCityGUI(String city) {
validateInput(patternCity, city); // Validate city format
}
public static void inputStateGUI(String state) {
validateInput(patternState, state); // Validate state format
}
public static void inputZipGUI(String zip) {
validateInput(patternZip, zip); // Validate zip format
}
public static void inputPhoneGUI(String phone) {
validateInput(patternPhone, phone); // Validate phone format
}
// For numeric string validation (e.g., for account number)
public static void inputNumericStringGUI(String input, int length) {
if (input.length() != length || !input.matches("[0-9]+")) {
throw new IllegalArgumentException("Invalid numeric input. Must be " + length + " digits.");
}
}
}

View File

@ -1,41 +0,0 @@
/* Phase IV */
package bankAcctApp;
//Class representing savings accounts
public class SavingsAccount extends Account {
// Overridden method for withdrawals in savings accounts
@Override
public void withdrawal(double amount) {
if (getBalance() >= amount + getSvcFee()) { // Ensure sufficient balance
setBalance(getBalance() - amount - getSvcFee()); // Deduct amount and service fee
} else {
throw new IllegalArgumentException("Insufficient funds for withdrawal. Savings accounts cannot overdraft.");
}
}
// Overridden method for deposits in savings accounts
@Override
public void deposit(double amount) {
setBalance(getBalance() + amount - getSvcFee()); // Add amount and deduct service fee
}
// Overridden method for applying accrued interest in savings accounts
@Override
public double applyAccruedInterest(String transactionDate) {
if (getBalance() <= 0) { // Ensure balance is positive for interest accrual
throw new IllegalArgumentException("The account has an insufficient balance for interest to apply.");
}
double interest = getBalance() * (getInterestRate() / 100); // Calculate interest
setBalance(getBalance() + interest); // Add interest to the balance
logTransaction(transactionDate, "INT", interest); // Log the interest transaction
return interest;
}
// Implementation of balance() method from AccountInterface
@Override
public double balance() {
return getBalance(); // Return the current balance
}
}