Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
|
43f6c3b6f2 | |
|
1f14a6c13b | |
|
6a7781de40 | |
|
a53bfef53e | |
|
4973d45198 |
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
// 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"
|
||||
}
|
||||
]
|
||||
}
|
26
README.md
26
README.md
|
@ -7,7 +7,18 @@
|
|||
- [Table of Contents](#table-of-contents)
|
||||
- [Introduction](#introduction)
|
||||
- [Scenario:](#scenario)
|
||||
- [Application Architecture \& Components](#application-architecture--components)
|
||||
- [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)
|
||||
- [Functionality \& Rationale](#functionality--rationale)
|
||||
- [Running Application Screenshots \& Demo](#running-application-screenshots--demo)
|
||||
- [Potential for Scalability \& Future Enhancements](#potential-for-scalability--future-enhancements)
|
||||
|
@ -39,6 +50,8 @@ 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
|
||||
|
@ -64,6 +77,7 @@ 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.
|
||||
|
@ -73,20 +87,30 @@ 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.
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,80 +1,102 @@
|
|||
/* Phase II */
|
||||
/* Phase IV */
|
||||
|
||||
package bankAcctApp;
|
||||
|
||||
public class Account {
|
||||
import java.util.ArrayList;
|
||||
|
||||
private String accountNumber;
|
||||
private String accountType;
|
||||
private Double svcFee;
|
||||
private Double interestRate;
|
||||
private Double overDraftFee;
|
||||
private Double balance = 0.00;
|
||||
// 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
|
||||
|
||||
// Transaction history stored as strings
|
||||
private ArrayList<String> transactionHistory = new ArrayList<>();
|
||||
|
||||
// Getter and Setter for Account Number info.
|
||||
// Getter for account number
|
||||
public String getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
|
||||
// Setter for account number
|
||||
public void setAccountNumber(String accountNumber) {
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
|
||||
// Getter and Setter for Customer ID info.
|
||||
// Getter for account type
|
||||
public String getAccountType() {
|
||||
return accountType;
|
||||
}
|
||||
|
||||
// Setter for account type
|
||||
public void setAccountType(String accountType) {
|
||||
this.accountType = accountType;
|
||||
}
|
||||
|
||||
|
||||
// Getter and Setter for Service Fee info.
|
||||
public Double getSvcFee() {
|
||||
// Getter for service fee
|
||||
public double getSvcFee() {
|
||||
return svcFee;
|
||||
}
|
||||
public void setSvcFee(Double svcFee) {
|
||||
|
||||
// Setter for service fee
|
||||
public void setSvcFee(double svcFee) {
|
||||
this.svcFee = svcFee;
|
||||
}
|
||||
|
||||
|
||||
// Getter and Setter for Interest Rate info.
|
||||
public Double getInterestRate() {
|
||||
// Getter for interest rate
|
||||
public double getInterestRate() {
|
||||
return interestRate;
|
||||
}
|
||||
public void setInterestRate(Double interestRate) {
|
||||
|
||||
// Setter for interest rate
|
||||
public void setInterestRate(double interestRate) {
|
||||
this.interestRate = interestRate;
|
||||
}
|
||||
|
||||
|
||||
// Getter and Setter for Overdraft Fee info.
|
||||
public Double getOverDraftFee() {
|
||||
// Getter for overdraft fee
|
||||
public double getOverDraftFee() {
|
||||
return overDraftFee;
|
||||
}
|
||||
public void setOverDraftFee(Double overDraftFee) {
|
||||
|
||||
// Setter for overdraft fee
|
||||
public void setOverDraftFee(double overDraftFee) {
|
||||
this.overDraftFee = overDraftFee;
|
||||
}
|
||||
|
||||
|
||||
// Getter and Setter for Balance info.
|
||||
public Double getBalance() {
|
||||
// Getter for account balance
|
||||
public double getBalance() {
|
||||
return balance;
|
||||
}
|
||||
public void setBalance(Double balance) {
|
||||
|
||||
// Setter for account balance
|
||||
public void setBalance(double balance) {
|
||||
this.balance = 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
|
||||
);
|
||||
// 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
|
||||
);
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Phase IV */
|
||||
|
||||
package bankAcctApp;
|
||||
|
||||
public interface AccountInterface {
|
||||
void withdrawal(double amount);
|
||||
void deposit(double amount);
|
||||
double applyAccruedInterest(String date);
|
||||
double balance();
|
||||
}
|
|
@ -1,182 +1,345 @@
|
|||
/* Phase II */
|
||||
/* Phase IV */
|
||||
|
||||
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;
|
||||
|
||||
// Create the loop that keeps adding Customer and Account instances until
|
||||
// the user chooses to quit.
|
||||
// Add customers and accounts
|
||||
while (moreCustomers) {
|
||||
|
||||
// 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();
|
||||
Account account = null;
|
||||
int inputCount = 0;
|
||||
|
||||
// Customer Information:
|
||||
System.out.println("Enter details for new customer:\n");
|
||||
|
||||
// Collect and validate user input for Customer ID info.
|
||||
// Collect and validate customer ID
|
||||
while (inputCount == 0) {
|
||||
try {
|
||||
customer.setID(DataEntry.inputStringWithLimit("Customer ID (max 5 chars): ", 5));
|
||||
} catch (IllegalArgumentException e){
|
||||
} 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 user input for Social Security Number (SSN).
|
||||
// Collect and validate SSN
|
||||
while (inputCount == 1) {
|
||||
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 user input for Last Namee.
|
||||
// Collect and validate Last Name
|
||||
while (inputCount == 2) {
|
||||
try {
|
||||
customer.setLastName(DataEntry.inputStringWithLimit("Last Name (max 20 chars): ", 20));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Last Name must not contain numbers (0-9) or special characters "
|
||||
+ "(!@#$%^&*(){}[]|). Try again.");
|
||||
System.out.println("Last Name must not contain numbers or special characters. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for First Name.
|
||||
// Collect and validate First Name
|
||||
while (inputCount == 3) {
|
||||
try {
|
||||
customer.setFirstName(DataEntry.inputStringWithLimit("First Name (max 15 chars): ", 15));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("First Name must not contain numbers (0-9) "
|
||||
+ "or special characters (!@#$%^&*(){}[]|). Try again.");
|
||||
System.out.println("First Name must not contain numbers or special characters. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
|
||||
// Collect and validate user input for Street Address.
|
||||
// Collect and validate Street Address
|
||||
while (inputCount == 4) {
|
||||
try {
|
||||
customer.setStreet(DataEntry.inputStringWithLimit("Street (max 20 chars): ", 20));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Street must be no more than 20 characters consisting of "
|
||||
+ "numbers, letters, spaces, and \" . , - ' \". Try again.");
|
||||
System.out.println("Street must be no more than 20 valid characters. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for City.
|
||||
// Collect and validate City
|
||||
while (inputCount == 5) {
|
||||
try {
|
||||
customer.setCity(DataEntry.inputStringWithLimit("City (max 20 chars): ", 20));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("City must not contain numbers (0-9) or special characters "
|
||||
+ "(!@#$%^&*(){}[]|). Try again.");
|
||||
System.out.println("City must not contain numbers or special characters. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for State.
|
||||
// Collect and validate State
|
||||
while (inputCount == 6) {
|
||||
try {
|
||||
customer.setState(DataEntry.inputStringWithLimit("State (2 chars): ", 2));
|
||||
} catch (InputMismatchException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("State must be 2 letters only. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for Zip Code.
|
||||
// Collect and validate ZIP code
|
||||
while (inputCount == 7) {
|
||||
try {
|
||||
customer.setZip(DataEntry.inputNumericString("Zip (5 numeric chars): ", 5));
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("Zip Code must only contain 5 digits. Try again.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Zip must be exactly 5 digits. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for Phone Number.
|
||||
// Collect and validate Phone Number
|
||||
while (inputCount == 8) {
|
||||
try {
|
||||
customer.setPhone(DataEntry.inputNumericString("Phone (10 numeric chars): ", 10));
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("Phone Number must only contain 9 digits.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Phone number must be 10 digits only. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Store Customer information to the Customer instance.
|
||||
// Add customer instance to customers ArrayList
|
||||
customers.add(customer);
|
||||
|
||||
// Account Information:
|
||||
// Collect and validate user input for Account Number.
|
||||
// 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) {
|
||||
try {
|
||||
account.setAccountNumber(DataEntry.inputNumericString("Account Number (5 numeric chars): ", 5));
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("Account Number can only be 5 digits. Try again.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Account number must be exactly 5 digits. Try again.");
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for Account Type.
|
||||
// Collect and validate Service Fee Amount
|
||||
while (inputCount == 11) {
|
||||
try {
|
||||
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.");
|
||||
account.setSvcFee(DataEntry.inputDecimalInRange("Service Fee (0.00 to 10.00): $", 0.00, 10.00));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println(e.getMessage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (InputMismatchException e) {
|
||||
System.out.println("Invalid input. Please try again.");
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for Service Fee.
|
||||
// Collect and validate Interest Rate Amount
|
||||
while (inputCount == 12) {
|
||||
try {
|
||||
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.");
|
||||
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++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for Interest Rate.
|
||||
// Collect and validate Overdraft Fee Amount
|
||||
while (inputCount == 13) {
|
||||
try {
|
||||
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.");
|
||||
account.setOverDraftFee(DataEntry.inputDecimal("Overdraft Fee (dollars and cents): $"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println(e.getMessage());
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// Collect and validate user input for Overdraft Fee.
|
||||
// Collect and validate Starting Balance
|
||||
while (inputCount == 14) {
|
||||
try {
|
||||
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");
|
||||
account.setBalance(DataEntry.inputDecimal("Starting Balance (dollars and cents): $"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println(e.getMessage());
|
||||
continue;
|
||||
}
|
||||
inputCount++;
|
||||
}
|
||||
|
||||
// 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
|
||||
// Add account instance to accounts ArrayList
|
||||
accounts.add(account);
|
||||
|
||||
// Prompt user to add additional customers or quit.
|
||||
// Ask if more customers should be added
|
||||
String more = DataEntry.inputStringWithLimit("\nAdd another customer? (y/n): ", 1);
|
||||
if (more.equalsIgnoreCase("n")) {
|
||||
moreCustomers = false;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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++) {
|
||||
if (selectedAccount == null) {
|
||||
System.out.println("Account not found. Please try again.\n");
|
||||
continue; // Prompt for account number again if not found
|
||||
}
|
||||
|
||||
// Use [int i] for both ArrayLists to ensure the correct Accounts instance is
|
||||
// printed with the corresponding Customer instance.
|
||||
// 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++) {
|
||||
Customer customer = customers.get(i);
|
||||
Account account = accounts.get(i);
|
||||
|
||||
System.out.println(customer + "\n");
|
||||
System.out.println(account);
|
||||
System.out.println("---------------------------------------------------------"
|
||||
+ "----------------------------------------------------------------------------");
|
||||
System.out.println(customer);
|
||||
|
||||
System.out.println("Account Details:");
|
||||
System.out.println(account);
|
||||
|
||||
System.out.println("Transactions:");
|
||||
for (String transaction : account.getTransactionHistory()) {
|
||||
System.out.println(transaction);
|
||||
}
|
||||
System.out.println("------------------------------|End Report|-------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,763 @@
|
|||
/* 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* 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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* Phase II */
|
||||
/* Phase IV */
|
||||
|
||||
package bankAcctApp;
|
||||
|
||||
|
@ -101,7 +101,6 @@ 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" +
|
||||
|
@ -109,4 +108,7 @@ public class Customer {
|
|||
id, lastName, firstName, ssn, phone, street, city, state, zip
|
||||
);
|
||||
}
|
||||
public Object getAccountNumber() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* Phase II */
|
||||
/* Phase IV */
|
||||
|
||||
package bankAcctApp;
|
||||
|
||||
|
@ -73,7 +73,7 @@ public class DataEntry {
|
|||
return input;
|
||||
}
|
||||
|
||||
// Static method to validate decimals.
|
||||
// Static method to validate decimals (specific to the CLI)
|
||||
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.
|
||||
// Static method to validate decimals are within a range (specific to the CLI)
|
||||
public static double inputDecimalInRange(String prompt, double min, double max) {
|
||||
double value;
|
||||
do {
|
||||
|
@ -105,21 +105,108 @@ 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);
|
||||
do {
|
||||
while (date.isEmpty()) {
|
||||
String input = in.nextLine();
|
||||
if (patternDate.matcher(input).matches()) {
|
||||
return input;
|
||||
date = input;
|
||||
return date;
|
||||
} 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.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* 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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue