Started implumenting a GUI for the program.
This commit is contained in:
@@ -7,20 +7,46 @@ import org.intellij.lang.annotations.MagicConstant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents an account in the bank for a user.
|
||||
*/
|
||||
public class Account {
|
||||
/**
|
||||
* List of transactions in the account.<br>
|
||||
* Each transaction contains information about the transaction, such as the amount, description, and the type of transaction.
|
||||
*/
|
||||
ArrayList<Transaction> transactions;
|
||||
/**
|
||||
* Name of the account.
|
||||
*/
|
||||
String name;
|
||||
/**
|
||||
* Balance of the account.
|
||||
*/
|
||||
double balance;
|
||||
/**
|
||||
* ID of the account.<br>
|
||||
* Also works as the Account number.
|
||||
*/
|
||||
UUID id;
|
||||
/**
|
||||
* Interest rate of the account.
|
||||
*/
|
||||
@MagicConstant(valuesFromClass = Interests.class)
|
||||
double interestRate;
|
||||
|
||||
public Account(String name, double balance, @MagicConstant(valuesFromClass = Interests.class) double interestRate) {
|
||||
/**
|
||||
* Creates a new account.
|
||||
* @param name Name of the account.
|
||||
* @param interestRate Interest rate of the account.
|
||||
*/
|
||||
public Account(String name, @MagicConstant(valuesFromClass = Interests.class) double interestRate) {
|
||||
this.name = name;
|
||||
this.balance = balance;
|
||||
this.balance = 0;
|
||||
transactions = new ArrayList<>();
|
||||
id = UUID.randomUUID();
|
||||
this.interestRate = interestRate;
|
||||
transactions.add(new Transaction(0, "Account opened", id, id, TransactionType.OPEN));
|
||||
}
|
||||
|
||||
public void WithdrawTransaction(double amount, String description, UUID destination) {
|
||||
@@ -62,7 +88,7 @@ public class Account {
|
||||
throw new IllegalArgumentException("Insufficient balance");
|
||||
}
|
||||
balance -= transaction.getAmount();
|
||||
} else if(transaction.getType() == TransactionType.DEPOSIT) {
|
||||
} else if(transaction.getType() == TransactionType.DEPOSIT || transaction.getType() == TransactionType.OPEN || transaction.getType() == TransactionType.CLOSE) {
|
||||
if(transaction.getAmount() < 0) {
|
||||
throw new IllegalArgumentException("Amount cannot be negative");
|
||||
}
|
||||
@@ -93,6 +119,11 @@ public class Account {
|
||||
return balance * (1+interestRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " - " + balance + " kr";
|
||||
}
|
||||
|
||||
public static class Interests
|
||||
{
|
||||
public static final double BANK_ACCOUNT_INTEREST_RATE = 0.001;
|
||||
|
||||
@@ -6,7 +6,7 @@ import static me.zacharias.bank.Account.Interests.BANK_ACCOUNT_INTEREST_RATE;
|
||||
* This class only works as a way to have prefilled information, but can be replaced by just calling the {@link Account#Account(String, double, double)} instead
|
||||
*/
|
||||
public class BankAccount extends Account {
|
||||
public BankAccount(String name, double balance) {
|
||||
super(name, balance, BANK_ACCOUNT_INTEREST_RATE);
|
||||
public BankAccount(String name) {
|
||||
super(name, BANK_ACCOUNT_INTEREST_RATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,25 +12,16 @@ import static me.zacharias.bank.Utils.*;
|
||||
public class Main {
|
||||
User user;
|
||||
|
||||
static Gson gson;
|
||||
|
||||
static {
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
//gsonBuilder.registerTypeAdapter(Account.class, new AccountAdapter());
|
||||
|
||||
gson = gsonBuilder.create();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String user = SHA256("zacharias");
|
||||
String user = SHA256("user");
|
||||
File userFile = new File("./users/" + user + ".json");
|
||||
|
||||
if(!userFile.exists()) {
|
||||
|
||||
User u = new User("zacharias");
|
||||
u.createAccount("Konto", 0.0);
|
||||
User u = new User("user");
|
||||
u.createAccount("Konto");
|
||||
Account a = u.getAccount("Konto");
|
||||
a.DepositTransaction(104, "Spawnar pängar", UUID.randomUUID());
|
||||
a.DepositTransaction(104, "Deposit", UUID.randomUUID());
|
||||
|
||||
String json = gson.toJson(u);
|
||||
try {
|
||||
@@ -52,7 +43,7 @@ public class Main {
|
||||
//return;
|
||||
}
|
||||
|
||||
String name = "zacharias";//console.readLine("Enter your name: ");
|
||||
String name = "user";//console.readLine("Enter your name: ");
|
||||
|
||||
String userHash = SHA256(name);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import static me.zacharias.bank.Account.Interests.SAVINGS_ACCOUNT_INTEREST_RATE;
|
||||
*/
|
||||
public class SavingsAccount extends Account{
|
||||
|
||||
public SavingsAccount(String name, double balance) {
|
||||
super(name, balance, SAVINGS_ACCOUNT_INTEREST_RATE);
|
||||
public SavingsAccount(String name) {
|
||||
super(name, SAVINGS_ACCOUNT_INTEREST_RATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package me.zacharias.bank;
|
||||
|
||||
import me.zacharias.bank.transaction.Transaction;
|
||||
import me.zacharias.bank.transaction.TransactionType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -14,14 +18,16 @@ public class User {
|
||||
accounts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void createAccount(String name, double balance) {
|
||||
Account account = new BankAccount(name, balance);
|
||||
public UUID createAccount(String name) {
|
||||
Account account = new BankAccount(name);
|
||||
accounts.add(account);
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
public void createSavingsAccount(String name, double balance) {
|
||||
Account account = new SavingsAccount(name, balance);
|
||||
public UUID createSavingsAccount(String name) {
|
||||
Account account = new SavingsAccount(name);
|
||||
accounts.add(account);
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
public Account getAccount(String name) {
|
||||
@@ -33,7 +39,7 @@ public class User {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Account getAccount(UUID id) {
|
||||
public Account getAccount(@NotNull UUID id) {
|
||||
for (Account account : accounts) {
|
||||
if (account.id.equals(id)) {
|
||||
return account;
|
||||
@@ -42,17 +48,25 @@ public class User {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void deleteAccount(Account account) {
|
||||
public void deleteAccount(@NotNull Account account) {
|
||||
Account base = null;
|
||||
for(Account a : accounts) {
|
||||
if(a instanceof BankAccount) {
|
||||
if(a.getId().equals(account.getId())) {
|
||||
base = a;
|
||||
}
|
||||
}
|
||||
if(base == null) {
|
||||
throw new IllegalArgumentException("No bank accounts found");
|
||||
throw new IllegalArgumentException("No other bank accounts found");
|
||||
}
|
||||
base.TransferTransaction(account.getBalance(), "Account closed", account.getId(), base.getId());
|
||||
base.handleTransaction(new Transaction(account.getBalance(), "Account closed", account.getId(), base.getId(), TransactionType.CLOSE));
|
||||
accounts.remove(account);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public ArrayList<Account> getAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package me.zacharias.bank;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
@@ -14,6 +17,22 @@ import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static final Gson gson;
|
||||
|
||||
static {
|
||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
//gsonBuilder.registerTypeAdapter(Account.class, new AccountAdapter());
|
||||
|
||||
gson = gsonBuilder.create();
|
||||
|
||||
File users = new File("./users");
|
||||
|
||||
if(!users.exists()) {
|
||||
users.mkdir();
|
||||
}
|
||||
}
|
||||
|
||||
public static String SHA256(String input) {
|
||||
MessageDigest sha256 = null;
|
||||
try {
|
||||
|
||||
67
src/main/java/me/zacharias/bank/app/AccountView.java
Normal file
67
src/main/java/me/zacharias/bank/app/AccountView.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package me.zacharias.bank.app;
|
||||
|
||||
import me.zacharias.bank.Account;
|
||||
import me.zacharias.bank.transaction.Transaction;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class AccountView extends JPanel {
|
||||
|
||||
Main bankApplication;
|
||||
Account account;
|
||||
|
||||
JLabel accountName;
|
||||
JLabel balance;
|
||||
JLabel AccountNumber;
|
||||
JList<Transaction> transactionList;
|
||||
|
||||
public AccountView(Main bankApplication, Account account) {
|
||||
this.bankApplication = bankApplication;
|
||||
this.account = account;
|
||||
|
||||
this.setLayout(null);
|
||||
|
||||
accountName = new JLabel(account.getName());
|
||||
accountName.setBounds(10, 10, 200, 30);
|
||||
|
||||
balance = new JLabel(account.getBalance() + " kr");
|
||||
balance.setBounds(10, 50, 200, 30);
|
||||
|
||||
AccountNumber = new JLabel(account.getId().toString());
|
||||
AccountNumber.setBounds(10, 90, 200, 30);
|
||||
|
||||
transactionList = new JList<>();
|
||||
transactionList.setBounds(10, 130, 200, 30);
|
||||
transactionList.setModel(new DefaultListModel<>());
|
||||
transactionList.setBackground(Color.GRAY);
|
||||
transactionList.setCellRenderer(new ListCellRenderer<Transaction>() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends Transaction> list, Transaction value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
JButton label = new JButton();
|
||||
label.setText(value.getDescription() + " " + value.getAmount() + " kr");
|
||||
label.setBackground(Color.GRAY);
|
||||
label.addActionListener(e -> {
|
||||
bankApplication.showAccount(account);
|
||||
});
|
||||
return label;
|
||||
}
|
||||
});
|
||||
|
||||
this.add(accountName);
|
||||
this.add(balance);
|
||||
this.add(AccountNumber);
|
||||
this.add(transactionList);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
accountName.setBounds(10, 10, 200, 30);
|
||||
balance.setBounds(10, 50, 200, 30);
|
||||
AccountNumber.setBounds(10, 90, 200, 30);
|
||||
transactionList.setBounds(10, 130, 200, 30);
|
||||
|
||||
transactionList.setListData(account.getTransactions().toArray(new Transaction[0]));
|
||||
super.paintComponent(g);
|
||||
}
|
||||
}
|
||||
135
src/main/java/me/zacharias/bank/app/Login.java
Normal file
135
src/main/java/me/zacharias/bank/app/Login.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package me.zacharias.bank.app;
|
||||
|
||||
import me.zacharias.bank.User;
|
||||
import me.zacharias.bank.Utils;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.io.File;
|
||||
|
||||
public class Login extends JPanel {
|
||||
|
||||
//String username;
|
||||
//String password;
|
||||
User user = null;
|
||||
|
||||
JTextField usernameField;
|
||||
JLabel usernameLabel;
|
||||
JPasswordField passwordField;
|
||||
JLabel passwordLabel;
|
||||
JLabel error;
|
||||
JButton loginButton;
|
||||
|
||||
Main bankApplication;
|
||||
|
||||
public Login(Main bankApplication) {
|
||||
this.bankApplication = bankApplication;
|
||||
|
||||
this.setLayout(null);
|
||||
|
||||
usernameField = new JTextField();
|
||||
usernameField.setBounds(getWidth()/2-100, 10, 200, 30);
|
||||
usernameField.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
usernameField.selectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
usernameField.select(0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
usernameLabel = new JLabel("Username");
|
||||
usernameLabel.setBounds(getWidth()/2-100-80, 10, 80, 30);
|
||||
|
||||
passwordField = new JPasswordField();
|
||||
passwordField.setBounds(getWidth()/2-100, 50, 200, 30);
|
||||
passwordField.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
usernameField.selectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
usernameField.select(0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
passwordLabel = new JLabel("Password");
|
||||
passwordLabel.setBounds(getWidth()/2-100-80, 50, 80, 30);
|
||||
|
||||
error = new JLabel();
|
||||
error.setBounds(getWidth()/2-100, 80, 200, 10);
|
||||
error.setFont(new Font("Arial", Font.BOLD, 10));
|
||||
error.setForeground(Color.RED);
|
||||
|
||||
loginButton = new JButton("Login");
|
||||
loginButton.setBounds(getWidth()/2-100, 95, 200, 30);
|
||||
loginButton.addActionListener(e -> {
|
||||
String username = usernameField.getText();
|
||||
String userHash = Utils.SHA256(username);
|
||||
String password = new String(passwordField.getPassword());
|
||||
|
||||
File userFile = new File("users/" + userHash + ".json");
|
||||
if (!userFile.exists()) {
|
||||
//JOptionPane.showMessageDialog(null, "Wrong username or password");
|
||||
error.setText("Wrong username or password");
|
||||
return;
|
||||
}
|
||||
|
||||
String userData;
|
||||
try {
|
||||
userData = Utils.Decrypt(Utils.ReadFile(userFile), password);
|
||||
} catch (Exception ex) {
|
||||
//JOptionPane.showMessageDialog(null, "Wrong username or password");
|
||||
error.setText("Wrong username or password");
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
user = Utils.gson.fromJson(userData, User.class);
|
||||
}catch (Exception ex){
|
||||
//JOptionPane.showMessageDialog(null, "Wrong username or password");
|
||||
error.setText("Wrong username or password");
|
||||
return;
|
||||
}
|
||||
|
||||
error.setText("");
|
||||
|
||||
bankApplication.login(user);
|
||||
});
|
||||
|
||||
this.add(usernameField);
|
||||
this.add(usernameLabel);
|
||||
this.add(passwordField);
|
||||
this.add(passwordLabel);
|
||||
this.add(error);
|
||||
this.add(loginButton);
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
usernameField.setBounds(getWidth()/2-100, 10, 200, 30);
|
||||
usernameLabel.setBounds(getWidth()/2-100-80, 10, 80, 30);
|
||||
passwordField.setBounds(getWidth()/2-100, 50, 200, 30);
|
||||
passwordLabel.setBounds(getWidth()/2-100-80, 50, 80, 30);
|
||||
error.setBounds(getWidth()/2-100, 80, 200, 10);
|
||||
loginButton.setBounds(getWidth()/2-100, 95, 200, 30);
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
usernameField.setText("");
|
||||
passwordField.setText("");
|
||||
error.setText("");
|
||||
}
|
||||
}
|
||||
57
src/main/java/me/zacharias/bank/app/Main.java
Normal file
57
src/main/java/me/zacharias/bank/app/Main.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package me.zacharias.bank.app;
|
||||
|
||||
import me.zacharias.bank.Account;
|
||||
import me.zacharias.bank.User;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class Main extends JPanel {
|
||||
public static void main(String[] args) {
|
||||
new Main();
|
||||
}
|
||||
|
||||
JFrame frame;
|
||||
Login login;
|
||||
MainMenu mainManu;
|
||||
AccountView accountView;
|
||||
|
||||
Timer timer = new Timer(100, e -> {frame.repaint();});
|
||||
|
||||
|
||||
public Main() {
|
||||
frame = new JFrame("Bank");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setSize(800, 600);
|
||||
frame.setLocationRelativeTo(null);
|
||||
|
||||
login = new Login(this);
|
||||
login.setBounds(0, 0, 800, 600);
|
||||
|
||||
frame.add(login);
|
||||
|
||||
frame.setVisible(true);
|
||||
timer.start();
|
||||
}
|
||||
|
||||
public void login(User user) {
|
||||
frame.remove(login);
|
||||
mainManu = new MainMenu(user, this);
|
||||
frame.add(mainManu);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
frame.remove(mainManu);
|
||||
login.clear();
|
||||
frame.add(login);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
public void showAccount(Account account) {
|
||||
frame.remove(mainManu);
|
||||
accountView = new AccountView(this, account);
|
||||
frame.add(accountView);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
66
src/main/java/me/zacharias/bank/app/MainMenu.java
Normal file
66
src/main/java/me/zacharias/bank/app/MainMenu.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package me.zacharias.bank.app;
|
||||
|
||||
import me.zacharias.bank.Account;
|
||||
import me.zacharias.bank.User;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class MainMenu extends JPanel {
|
||||
|
||||
User user;
|
||||
Main bankApplication;
|
||||
|
||||
JLabel welcome;
|
||||
JButton logout;
|
||||
|
||||
JList<Account> accountList;
|
||||
|
||||
public MainMenu(User user, Main bankApplication) {
|
||||
this.user = user;
|
||||
this.bankApplication = bankApplication;
|
||||
|
||||
this.setLayout(null);
|
||||
|
||||
welcome = new JLabel("Welcome " + user.getName());
|
||||
welcome.setBounds(getWidth()/2-100, 10, 200, 30);
|
||||
|
||||
logout = new JButton("Logout");
|
||||
logout.setBounds(getWidth()/2-100, getHeight()-50, 200, 30);
|
||||
logout.addActionListener(e -> {
|
||||
bankApplication.logout();
|
||||
});
|
||||
|
||||
accountList = new JList<>();
|
||||
accountList.setBounds(getWidth()/2-100, 80, 200, 30);
|
||||
accountList.setModel(new DefaultListModel<>());
|
||||
accountList.setBackground(Color.GRAY);
|
||||
accountList.setCellRenderer(new ListCellRenderer<Account>() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends Account> list, Account value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
JButton label = new JButton();
|
||||
label.setText(value.getName() + " " + value.getBalance() + " kr");
|
||||
label.setBackground(Color.GRAY);
|
||||
label.addActionListener(e -> {
|
||||
bankApplication.showAccount(value);
|
||||
});
|
||||
return label;
|
||||
}
|
||||
});
|
||||
|
||||
this.add(welcome);
|
||||
this.add(logout);
|
||||
this.add(accountList);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
welcome.setBounds(getWidth()/2-100, 10, 200, 30);
|
||||
logout.setBounds(getWidth()/2-100, getHeight()-50, 200, 30);
|
||||
accountList.setBounds(getWidth()/2-100, 80, 200, 30);
|
||||
|
||||
|
||||
accountList.setListData(user.getAccounts().toArray(new Account[0]));
|
||||
super.paintComponent(g);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package me.zacharias.bank.transaction;
|
||||
|
||||
public enum TransactionType {
|
||||
WITHDRAW, DEPOSIT, TRANSFER
|
||||
WITHDRAW, DEPOSIT, OPEN, TRANSFER, CLOSE
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user