├── BankingApp.iml ├── README.md ├── Screenshot_16.png ├── lib └── mysql-connector-j-8.1.0.jar ├── out └── production │ └── BankingApp │ ├── AppLauncher$1.class │ ├── AppLauncher.class │ ├── db_objs │ ├── MyJDBC.class │ ├── Transaction.class │ └── User.class │ └── guis │ ├── BankingAppDialog.class │ ├── BankingAppGui.class │ ├── BaseFrame.class │ ├── LoginGui$1.class │ ├── LoginGui$2.class │ ├── LoginGui.class │ ├── RegisterGui$1.class │ ├── RegisterGui$2.class │ └── RegisterGui.class └── src ├── AppLauncher.java ├── db_objs ├── MyJDBC.java ├── Transaction.java └── User.java └── guis ├── BankingAppDialog.java ├── BankingAppGui.java ├── BaseFrame.java ├── LoginGui.java └── RegisterGui.java /BankingApp.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bank App with Swing and MySQL 2 | 3 | A simple bank application with a graphical user interface developed in Java using the Swing framework. The application interacts with a MySQL database to perform essential banking operations. 4 | You can watch this video where I build this app from the ground up so that you can get a better understanding of how it works: https://www.youtube.com/watch?v=phYuQWRaazw&t=1s 5 | 6 | ## Features 7 | 8 | 1. **Logging into an Account**: Users can log in using their credentials. 9 | 10 | 2. **Registering an Account**: New users can register for a bank account. 11 | 12 | 3. **Depositing Balance**: Users can deposit funds into their accounts. 13 | 14 | 4. **Withdrawing Balance**: Users can withdraw funds from their accounts. 15 | 16 | 5. **Checking Balance**: View the current account balance. 17 | 18 | 6. **Logging Out**: Securely log out of the account. 19 | 20 | 7. **Viewing Past Transactions**: Access a history of past transactions. 21 | 22 | 8. **Transferring to Users within the MySQL Database**: Users can transfer funds to other registered users. 23 | 24 |

25 | Bank App Screenshot 26 |

27 | 28 | ### Technologies 29 | 30 | - Java Development Kit (JDK18) 31 | - MySQL Database 32 | -------------------------------------------------------------------------------- /Screenshot_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/Screenshot_16.png -------------------------------------------------------------------------------- /lib/mysql-connector-j-8.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/lib/mysql-connector-j-8.1.0.jar -------------------------------------------------------------------------------- /out/production/BankingApp/AppLauncher$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/AppLauncher$1.class -------------------------------------------------------------------------------- /out/production/BankingApp/AppLauncher.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/AppLauncher.class -------------------------------------------------------------------------------- /out/production/BankingApp/db_objs/MyJDBC.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/db_objs/MyJDBC.class -------------------------------------------------------------------------------- /out/production/BankingApp/db_objs/Transaction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/db_objs/Transaction.class -------------------------------------------------------------------------------- /out/production/BankingApp/db_objs/User.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/db_objs/User.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/BankingAppDialog.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/BankingAppDialog.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/BankingAppGui.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/BankingAppGui.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/BaseFrame.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/BaseFrame.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/LoginGui$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/LoginGui$1.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/LoginGui$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/LoginGui$2.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/LoginGui.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/LoginGui.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/RegisterGui$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/RegisterGui$1.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/RegisterGui$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/RegisterGui$2.class -------------------------------------------------------------------------------- /out/production/BankingApp/guis/RegisterGui.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curadProgrammer/BankAppJava/db3763df651817f9388186ade51d0aaaf57a5ccb/out/production/BankingApp/guis/RegisterGui.class -------------------------------------------------------------------------------- /src/AppLauncher.java: -------------------------------------------------------------------------------- 1 | import db_objs.User; 2 | import guis.BankingAppGui; 3 | import guis.LoginGui; 4 | import guis.RegisterGui; 5 | 6 | import javax.swing.*; 7 | import java.math.BigDecimal; 8 | 9 | public class AppLauncher { 10 | public static void main(String[] args) { 11 | // use invokeLater to make updates to the GUI more thread-safe 12 | SwingUtilities.invokeLater(new Runnable(){ 13 | @Override 14 | public void run() { 15 | new LoginGui().setVisible(true); 16 | // new RegisterGui().setVisible(true); 17 | // new BankingAppGui( 18 | // new User(4, "username", "password", new BigDecimal("20.00")) 19 | // ).setVisible(true); 20 | } 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/db_objs/MyJDBC.java: -------------------------------------------------------------------------------- 1 | package db_objs; 2 | 3 | import com.mysql.cj.x.protobuf.MysqlxPrepare; 4 | 5 | import java.math.BigDecimal; 6 | import java.sql.*; 7 | import java.util.ArrayList; 8 | 9 | /* 10 | JDBC class is used to interact with our MySQL Database to perform activities such as retrieving and updating our db 11 | */ 12 | public class MyJDBC { 13 | // database configurations 14 | private static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/bankapp"; 15 | private static final String DB_USERNAME = "root"; 16 | private static final String DB_PASSWORD = "password"; 17 | 18 | // if valid return an object with the user's information 19 | public static User validateLogin(String username, String password){ 20 | try{ 21 | // establish a connection to the database using configurations 22 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 23 | 24 | // create sql query 25 | PreparedStatement preparedStatement = connection.prepareStatement( 26 | "SELECT * FROM users WHERE username = ? AND password = ?" 27 | ); 28 | 29 | // replace the ? with values 30 | // parameter index referring to the iteration of the ? so 1 is the first ? and 2 is the second ? 31 | preparedStatement.setString(1, username); 32 | preparedStatement.setString(2, password); 33 | 34 | // execute query and store into a result set 35 | ResultSet resultSet = preparedStatement.executeQuery(); 36 | 37 | // next() returns true or false 38 | // true - query returned data and result set now points to the first row 39 | // false - query returned no data and result set equals to null 40 | if(resultSet.next()){ 41 | // success 42 | // get id 43 | int userId = resultSet.getInt("id"); 44 | 45 | // get current balance 46 | BigDecimal currentBalance = resultSet.getBigDecimal("current_balance"); 47 | 48 | // return user object 49 | return new User(userId, username, password, currentBalance); 50 | } 51 | 52 | }catch(SQLException e){ 53 | e.printStackTrace(); 54 | } 55 | 56 | // not valid user 57 | return null; 58 | } 59 | 60 | // registers new user to the database 61 | // true - register success 62 | // false - register fails 63 | public static boolean register(String username, String password){ 64 | try{ 65 | // first we will need to check if the username has already been taken 66 | if(!checkUser(username)){ 67 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 68 | 69 | PreparedStatement preparedStatement = connection.prepareStatement( 70 | "INSERT INTO users(username, password, current_balance) " + 71 | "VALUES(?, ?, ?)" 72 | ); 73 | 74 | preparedStatement.setString(1, username); 75 | preparedStatement.setString(2, password); 76 | preparedStatement.setBigDecimal(3, new BigDecimal(0)); 77 | 78 | preparedStatement.executeUpdate(); 79 | return true; 80 | 81 | } 82 | }catch(SQLException e){ 83 | e.printStackTrace(); 84 | } 85 | 86 | return false; 87 | } 88 | 89 | // check if username already exists in the db 90 | // true - user exists 91 | // false - user doesn't exist 92 | private static boolean checkUser(String username){ 93 | try{ 94 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 95 | 96 | PreparedStatement preparedStatement = connection.prepareStatement( 97 | "SELECT * FROM users WHERE username = ?" 98 | ); 99 | 100 | preparedStatement.setString(1, username); 101 | ResultSet resultSet = preparedStatement.executeQuery(); 102 | 103 | // this means that the query returned no data meaning that the username is available 104 | if(!resultSet.next()){ 105 | return false; 106 | } 107 | }catch(SQLException e){ 108 | e.printStackTrace(); 109 | } 110 | 111 | return true; 112 | } 113 | 114 | // true - update to db was a success 115 | // false - update to the db was a fail 116 | public static boolean addTransactionToDatabase(Transaction transaction){ 117 | try{ 118 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 119 | 120 | PreparedStatement insertTransaction = connection.prepareStatement( 121 | "INSERT transactions(user_id, transaction_type, transaction_amount, transaction_date) " + 122 | "VALUES(?, ?, ?, NOW())" 123 | ); 124 | // NOW() will put in the current date 125 | 126 | insertTransaction.setInt(1, transaction.getUserId()); 127 | insertTransaction.setString(2, transaction.getTransactionType()); 128 | insertTransaction.setBigDecimal(3, transaction.getTransactionAmount()); 129 | 130 | // update database 131 | insertTransaction.executeUpdate(); 132 | 133 | return true; 134 | 135 | }catch(SQLException e){ 136 | e.printStackTrace(); 137 | } 138 | 139 | return false; 140 | } 141 | 142 | // true - update balance successful 143 | // false - update balance fail 144 | public static boolean updateCurrentBalance(User user){ 145 | try{ 146 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 147 | 148 | PreparedStatement updateBalance = connection.prepareStatement( 149 | "UPDATE users SET current_balance = ? WHERE id = ?" 150 | ); 151 | 152 | updateBalance.setBigDecimal(1, user.getCurrentBalance()); 153 | updateBalance.setInt(2, user.getId()); 154 | 155 | updateBalance.executeUpdate(); 156 | return true; 157 | 158 | }catch(SQLException e){ 159 | e.printStackTrace(); 160 | } 161 | 162 | return false; 163 | } 164 | 165 | // true - transfer was a success 166 | // false - transfer was a fail 167 | public static boolean transfer(User user, String transferredUsername, float transferAmount){ 168 | try{ 169 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 170 | 171 | PreparedStatement queryUser = connection.prepareStatement( 172 | "SELECT * FROM users WHERE username = ?" 173 | ); 174 | 175 | queryUser.setString(1, transferredUsername); 176 | ResultSet resultSet = queryUser.executeQuery(); 177 | 178 | while (resultSet.next()) { 179 | // perfrom transfer 180 | User transferredUser = new User( 181 | resultSet.getInt("id"), 182 | transferredUsername, 183 | resultSet.getString("password"), 184 | resultSet.getBigDecimal("current_balance") 185 | ); 186 | 187 | // create transaction 188 | Transaction transferTransaction = new Transaction( 189 | user.getId(), 190 | "Transfer", 191 | new BigDecimal(-transferAmount), 192 | null 193 | ); 194 | 195 | // this transaction will belong to the transferred user 196 | Transaction receivedTransaction = new Transaction( 197 | transferredUser.getId(), 198 | "Transfer", 199 | new BigDecimal(transferAmount), 200 | null 201 | ); 202 | 203 | // update transfer user 204 | transferredUser.setCurrentBalance(transferredUser.getCurrentBalance().add(BigDecimal.valueOf(transferAmount))); 205 | updateCurrentBalance(transferredUser); 206 | 207 | // update user current balance 208 | user.setCurrentBalance(user.getCurrentBalance().subtract(BigDecimal.valueOf(transferAmount))); 209 | updateCurrentBalance(user); 210 | 211 | // add these transactions to the database 212 | addTransactionToDatabase(transferTransaction); 213 | addTransactionToDatabase(receivedTransaction); 214 | 215 | return true; 216 | 217 | } 218 | }catch(SQLException e){ 219 | e.printStackTrace(); 220 | } 221 | 222 | return false; 223 | } 224 | 225 | // get all transactions (used for past transaction) 226 | public static ArrayList getPastTransaction(User user){ 227 | ArrayList pastTransactions = new ArrayList<>(); 228 | try{ 229 | Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD); 230 | 231 | PreparedStatement selectAllTransaction = connection.prepareStatement( 232 | "SELECT * FROM transactions WHERE user_id = ?" 233 | ); 234 | selectAllTransaction.setInt(1, user.getId()); 235 | 236 | ResultSet resultSet = selectAllTransaction.executeQuery(); 237 | 238 | // iterate throught the results (if any) 239 | while(resultSet.next()){ 240 | // create transaction obj 241 | Transaction transaction = new Transaction( 242 | user.getId(), 243 | resultSet.getString("transaction_type"), 244 | resultSet.getBigDecimal("transaction_amount"), 245 | resultSet.getDate("transaction_date") 246 | ); 247 | 248 | // store into array list 249 | pastTransactions.add(transaction); 250 | } 251 | }catch(SQLException e){ 252 | e.printStackTrace(); 253 | } 254 | 255 | return pastTransactions; 256 | } 257 | } 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /src/db_objs/Transaction.java: -------------------------------------------------------------------------------- 1 | package db_objs; 2 | 3 | import java.math.BigDecimal; 4 | import java.sql.Date; 5 | 6 | /* 7 | Transaction entity used to store transaction data 8 | */ 9 | public class Transaction { 10 | private final int userId; 11 | private final String transactionType; 12 | private final BigDecimal transactionAmount; 13 | private final Date transactionDate; 14 | 15 | public Transaction(int userId, String transactionType, BigDecimal transactionAmount, Date transactionDate){ 16 | this.userId = userId; 17 | this.transactionType = transactionType; 18 | this.transactionAmount = transactionAmount; 19 | this.transactionDate = transactionDate; 20 | } 21 | 22 | public int getUserId() { 23 | return userId; 24 | } 25 | 26 | public String getTransactionType() { 27 | return transactionType; 28 | } 29 | 30 | public BigDecimal getTransactionAmount() { 31 | return transactionAmount; 32 | } 33 | 34 | public Date getTransactionDate() { 35 | return transactionDate; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/db_objs/User.java: -------------------------------------------------------------------------------- 1 | package db_objs; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.RoundingMode; 5 | 6 | /* 7 | User entity which is used to store user information (i.e. id, username, password, and current balance) 8 | */ 9 | public class User { 10 | private final int id; 11 | private final String username, password; 12 | private BigDecimal currentBalance; 13 | 14 | public User(int id, String username, String password, BigDecimal currentBalance){ 15 | this.id = id; 16 | this.username = username; 17 | this.password = password; 18 | this.currentBalance = currentBalance; 19 | } 20 | 21 | public int getId() { 22 | return id; 23 | } 24 | 25 | public String getUsername() { 26 | return username; 27 | } 28 | 29 | public String getPassword() { 30 | return password; 31 | } 32 | 33 | public BigDecimal getCurrentBalance() { 34 | return currentBalance; 35 | } 36 | 37 | public void setCurrentBalance(BigDecimal newBalance){ 38 | // store new value to the 2nd decimal place 39 | currentBalance = newBalance.setScale(2, RoundingMode.FLOOR); 40 | } 41 | } 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/guis/BankingAppDialog.java: -------------------------------------------------------------------------------- 1 | package guis; 2 | 3 | import db_objs.MyJDBC; 4 | import db_objs.Transaction; 5 | import db_objs.User; 6 | 7 | import javax.swing.*; 8 | import java.awt.*; 9 | import java.awt.event.ActionEvent; 10 | import java.awt.event.ActionListener; 11 | import java.math.BigDecimal; 12 | import java.util.ArrayList; 13 | 14 | /* 15 | Displays a custom dialog for our BankingAppGui 16 | */ 17 | public class BankingAppDialog extends JDialog implements ActionListener { 18 | private User user; 19 | private BankingAppGui bankingAppGui; 20 | private JLabel balanceLabel, enterAmountLabel, enterUserLabel; 21 | private JTextField enterAmountField, enterUserField; 22 | private JButton actionButton; 23 | private JPanel pastTransactionPanel; 24 | private ArrayList pastTransactions; 25 | 26 | public BankingAppDialog(BankingAppGui bankingAppGui, User user){ 27 | // set the size 28 | setSize(400, 400); 29 | 30 | // add focus to the dialog (can't interact with anything else until dialog is closed) 31 | setModal(true); 32 | 33 | // loads in teh center of our banking gui 34 | setLocationRelativeTo(bankingAppGui); 35 | 36 | // when suer closes dialog, it releases its resources that are being used 37 | setDefaultCloseOperation(DISPOSE_ON_CLOSE); 38 | 39 | // prevents dialog from being resized 40 | setResizable(false); 41 | 42 | // allows us to manually specify the size and position of each component 43 | setLayout(null); 44 | 45 | // we will need reference to our gui so that we can update the current balance 46 | this.bankingAppGui = bankingAppGui; 47 | 48 | // we will need access to the user info to make updates to our db or retrieve data about the user 49 | this.user = user; 50 | } 51 | 52 | public void addCurrentBalanceAndAmount(){ 53 | // balance label 54 | balanceLabel = new JLabel("Balance: $" + user.getCurrentBalance()); 55 | balanceLabel.setBounds(0, 10, getWidth() - 20, 20); 56 | balanceLabel.setFont(new Font("Dialog", Font.BOLD, 16)); 57 | balanceLabel.setHorizontalAlignment(SwingConstants.CENTER); 58 | add(balanceLabel); 59 | 60 | // enter amount label 61 | enterAmountLabel = new JLabel("Enter Amount:"); 62 | enterAmountLabel.setBounds(0, 50, getWidth() - 20, 20); 63 | enterAmountLabel.setFont(new Font("Dialog", Font.BOLD, 16)); 64 | enterAmountLabel.setHorizontalAlignment(SwingConstants.CENTER); 65 | add(enterAmountLabel); 66 | 67 | // enter amount field 68 | enterAmountField = new JTextField(); 69 | enterAmountField.setBounds(15, 80, getWidth() - 50, 40); 70 | enterAmountField.setFont(new Font("Dialog", Font.BOLD, 20)); 71 | enterAmountField.setHorizontalAlignment(SwingConstants.RIGHT); 72 | add(enterAmountField); 73 | } 74 | 75 | public void addActionButton(String actionButtonType){ 76 | actionButton = new JButton(actionButtonType); 77 | actionButton.setBounds(15, 300, getWidth() - 50, 40); 78 | actionButton.setFont(new Font("Dialog", Font.BOLD, 20)); 79 | actionButton.addActionListener(this); 80 | add(actionButton); 81 | } 82 | 83 | public void addUserField(){ 84 | // enter user label 85 | enterUserLabel = new JLabel("Enter User:"); 86 | enterUserLabel.setBounds(0, 160, getWidth() - 20, 20); 87 | enterUserLabel.setFont(new Font("Dialog", Font.BOLD, 16)); 88 | enterUserLabel.setHorizontalAlignment(SwingConstants.CENTER); 89 | add(enterUserLabel); 90 | 91 | // enter user field 92 | enterUserField = new JTextField(); 93 | enterUserField.setBounds(15, 190, getWidth() - 50, 40); 94 | enterUserField.setFont(new Font("Dialog", Font.BOLD, 20)); 95 | add(enterUserField); 96 | } 97 | 98 | public void addPastTransactionComponents(){ 99 | // container where we will store each transaction 100 | pastTransactionPanel = new JPanel(); 101 | 102 | // make layout 1x1 103 | pastTransactionPanel.setLayout(new BoxLayout(pastTransactionPanel, BoxLayout.Y_AXIS)); 104 | 105 | // add scrollability to the container 106 | JScrollPane scrollPane = new JScrollPane(pastTransactionPanel); 107 | 108 | // displays the vertical scroll only when it is required 109 | scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 110 | scrollPane.setBounds(0, 20, getWidth() - 15, getHeight() - 80); 111 | 112 | // perform db call to retrieve all of the past transaction and store into array list 113 | pastTransactions = MyJDBC.getPastTransaction(user); 114 | 115 | // iterate through the list and add to the gui 116 | for(int i = 0; i < pastTransactions.size(); i++){ 117 | // store current transaction 118 | Transaction pastTransaction = pastTransactions.get(i); 119 | 120 | // create a container to store an individual transaction 121 | JPanel pastTransactionContainer = new JPanel(); 122 | pastTransactionContainer.setLayout(new BorderLayout()); 123 | 124 | // create transaction type label 125 | JLabel transactionTypeLabel = new JLabel(pastTransaction.getTransactionType()); 126 | transactionTypeLabel.setFont(new Font("Dialog", Font.BOLD, 20)); 127 | 128 | // create transaction amount label 129 | JLabel transactionAmountLabel = new JLabel(String.valueOf(pastTransaction.getTransactionAmount())); 130 | transactionAmountLabel.setFont(new Font("Dialog", Font.BOLD, 20)); 131 | 132 | // create transaction date label 133 | JLabel transactionDateLabel = new JLabel(String.valueOf(pastTransaction.getTransactionDate())); 134 | transactionDateLabel.setFont(new Font("Dialog", Font.BOLD, 20)); 135 | 136 | // add to the container 137 | pastTransactionContainer.add(transactionTypeLabel, BorderLayout.WEST); // place this on the west side 138 | pastTransactionContainer.add(transactionAmountLabel, BorderLayout.EAST); // place this on the east side 139 | pastTransactionContainer.add(transactionDateLabel, BorderLayout.SOUTH); // place this on the south side 140 | 141 | // give a white background to each container 142 | pastTransactionContainer.setBackground(Color.WHITE); 143 | 144 | // give a black border to each transaction container 145 | pastTransactionContainer.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 146 | 147 | // add transaction component to the transaction panel 148 | pastTransactionPanel.add(pastTransactionContainer); 149 | } 150 | 151 | // add to the dialog 152 | add(scrollPane); 153 | } 154 | 155 | private void handleTransaction(String transactionType, float amountVal){ 156 | Transaction transaction; 157 | 158 | if(transactionType.equalsIgnoreCase("Deposit")){ 159 | // deposit transaction type 160 | // add to current balance 161 | user.setCurrentBalance(user.getCurrentBalance().add(new BigDecimal(amountVal))); 162 | 163 | // create transaction 164 | // we leave date null because we are going to be using the NOW() in sql which will get the current date 165 | transaction = new Transaction(user.getId(), transactionType, new BigDecimal(amountVal), null); 166 | }else{ 167 | // withdraw transaction type 168 | // subtract from current balance 169 | user.setCurrentBalance(user.getCurrentBalance().subtract(new BigDecimal(amountVal))); 170 | 171 | // we want to show a negative sign for the amount val when withdrawing 172 | transaction = new Transaction(user.getId(), transactionType, new BigDecimal(-amountVal), null); 173 | } 174 | 175 | // update database 176 | if(MyJDBC.addTransactionToDatabase(transaction) && MyJDBC.updateCurrentBalance(user)){ 177 | // show success dialog 178 | JOptionPane.showMessageDialog(this, transactionType + " Successfully!"); 179 | 180 | // reset the fields 181 | resetFieldsAndUpdateCurrentBalance(); 182 | }else{ 183 | // show failure dialog 184 | JOptionPane.showMessageDialog(this, transactionType + " Failed..."); 185 | } 186 | 187 | } 188 | 189 | private void resetFieldsAndUpdateCurrentBalance(){ 190 | // reset fields 191 | enterAmountField.setText(""); 192 | 193 | // only appears when transfer is clicked 194 | if(enterUserField != null){ 195 | enterUserField.setText(""); 196 | } 197 | 198 | // update current balance on dialog 199 | balanceLabel.setText("Balance: $" + user.getCurrentBalance()); 200 | 201 | // update current balance on main gui 202 | bankingAppGui.getCurrentBalanceField().setText("$" + user.getCurrentBalance()); 203 | } 204 | 205 | private void handleTransfer(User user, String transferredUser, float amount){ 206 | // attempt to perform transfer 207 | if(MyJDBC.transfer(user, transferredUser, amount)){ 208 | // show success dialog 209 | JOptionPane.showMessageDialog(this, "Transfer Success!"); 210 | resetFieldsAndUpdateCurrentBalance(); 211 | }else{ 212 | // show failure dialog 213 | JOptionPane.showMessageDialog(this, "Transfer Failed..."); 214 | } 215 | } 216 | 217 | @Override 218 | public void actionPerformed(ActionEvent e) { 219 | String buttonPressed = e.getActionCommand(); 220 | 221 | // get amount val 222 | float amountVal = Float.parseFloat(enterAmountField.getText()); 223 | 224 | // pressed deposit 225 | if(buttonPressed.equalsIgnoreCase("Deposit")){ 226 | // we want to handle the deposit transaction 227 | handleTransaction(buttonPressed, amountVal); 228 | }else{ 229 | // pressed withdraw or transfer 230 | 231 | // validate input by making sure that withdraw or transfer amount is less than current balance 232 | // if result is -1 it means that the entered amount is more, 0 means they are equal, and 1 means that 233 | // the entered amount is less 234 | int result = user.getCurrentBalance().compareTo(BigDecimal.valueOf(amountVal)); 235 | if(result < 0){ 236 | // display error dialog 237 | JOptionPane.showMessageDialog(this, "Error: Input value is more than current balance"); 238 | return; 239 | } 240 | 241 | // check to see if withdraw or transfer was pressed 242 | if(buttonPressed.equalsIgnoreCase("Withdraw")){ 243 | handleTransaction(buttonPressed, amountVal); 244 | }else{ 245 | // transfer 246 | String transferredUser = enterUserField.getText(); 247 | 248 | // handle transfer 249 | handleTransfer(user, transferredUser, amountVal); 250 | } 251 | 252 | } 253 | } 254 | } 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /src/guis/BankingAppGui.java: -------------------------------------------------------------------------------- 1 | package guis; 2 | 3 | import db_objs.User; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | import java.awt.event.ActionEvent; 8 | import java.awt.event.ActionListener; 9 | 10 | /* 11 | Performs banking functions such as depositing, withdrawing, seeing past transaction, and transferring 12 | This extends from the BaseFrame which means we will need to define our own addGuiComponent 13 | */ 14 | public class BankingAppGui extends BaseFrame implements ActionListener { 15 | private JTextField currentBalanceField; 16 | public JTextField getCurrentBalanceField(){return currentBalanceField;} 17 | 18 | public BankingAppGui(User user){ 19 | super("Banking App", user); 20 | } 21 | @Override 22 | protected void addGuiComponents() { 23 | // create welcome message 24 | String welcomeMessage = "" + 25 | "" + 26 | "Hello " + user.getUsername() + "
" + 27 | "What would you like to do today?"; 28 | JLabel welcomeMessageLabel = new JLabel(welcomeMessage); 29 | welcomeMessageLabel.setBounds(0, 20, getWidth() - 10, 40); 30 | welcomeMessageLabel.setFont(new Font("Dialog", Font.PLAIN, 16)); 31 | welcomeMessageLabel.setHorizontalAlignment(SwingConstants.CENTER); 32 | add(welcomeMessageLabel); 33 | 34 | // create current balance label 35 | JLabel currentBalanceLabel = new JLabel("Current Balance"); 36 | currentBalanceLabel.setBounds(0, 80, getWidth() - 10, 30); 37 | currentBalanceLabel.setFont(new Font("Dialog", Font.BOLD, 22)); 38 | currentBalanceLabel.setHorizontalAlignment(SwingConstants.CENTER); 39 | add(currentBalanceLabel); 40 | // 41 | // create current balance field 42 | currentBalanceField = new JTextField("$" + user.getCurrentBalance()); 43 | currentBalanceField.setBounds(15, 120, getWidth() - 50, 40); 44 | currentBalanceField.setFont(new Font("Dialog", Font.BOLD, 28)); 45 | currentBalanceField.setHorizontalAlignment(SwingConstants.RIGHT); 46 | currentBalanceField.setEditable(false); 47 | add(currentBalanceField); 48 | 49 | // deposit button 50 | JButton depositButton = new JButton("Deposit"); 51 | depositButton.setBounds(15, 180, getWidth() - 50, 50); 52 | depositButton.setFont(new Font("Dialog", Font.BOLD, 22)); 53 | depositButton.addActionListener(this); 54 | add(depositButton); 55 | 56 | // withdraw button 57 | JButton withdrawButton = new JButton("Withdraw"); 58 | withdrawButton.setBounds(15, 250, getWidth() - 50, 50); 59 | withdrawButton.setFont(new Font("Dialog", Font.BOLD, 22)); 60 | withdrawButton.addActionListener(this); 61 | add(withdrawButton); 62 | 63 | // past transaction button 64 | JButton pastTransactionButton = new JButton("Past Transaction"); 65 | pastTransactionButton.setBounds(15, 320, getWidth() - 50, 50); 66 | pastTransactionButton.setFont(new Font("Dialog", Font.BOLD, 22)); 67 | pastTransactionButton.addActionListener(this); 68 | add(pastTransactionButton); 69 | 70 | // transfer button 71 | JButton transferButton = new JButton("Transfer"); 72 | transferButton.setBounds(15, 390, getWidth() - 50, 50); 73 | transferButton.setFont(new Font("Dialog", Font.BOLD, 22)); 74 | transferButton.addActionListener(this); 75 | add(transferButton); 76 | 77 | // logout button 78 | JButton logoutButton = new JButton("Logout"); 79 | logoutButton.setBounds(15, 500, getWidth() - 50, 50); 80 | logoutButton.setFont(new Font("Dialog", Font.BOLD, 22)); 81 | logoutButton.addActionListener(this); 82 | add(logoutButton); 83 | } 84 | 85 | @Override 86 | public void actionPerformed(ActionEvent e) { 87 | String buttonPressed = e.getActionCommand(); 88 | 89 | // user pressed logout 90 | if(buttonPressed.equalsIgnoreCase("Logout")){ 91 | // return user to the login gui 92 | new LoginGui().setVisible(true); 93 | 94 | // dispose of this gui 95 | this.dispose(); 96 | 97 | // don't bother running the rest of the code 98 | return; 99 | } 100 | 101 | // other functions 102 | BankingAppDialog bankingAppDialog = new BankingAppDialog(this, user); 103 | 104 | // set the title of the dialog header to the action 105 | bankingAppDialog.setTitle(buttonPressed); 106 | 107 | // if the button pressed is deposit, withdraw, or transfer 108 | if(buttonPressed.equalsIgnoreCase("Deposit") || buttonPressed.equalsIgnoreCase("Withdraw") 109 | || buttonPressed.equalsIgnoreCase("Transfer")){ 110 | // add in the current balance and amount gui components to the dialog 111 | bankingAppDialog.addCurrentBalanceAndAmount(); 112 | 113 | // add action button 114 | bankingAppDialog.addActionButton(buttonPressed); 115 | 116 | // for the transfer action it will require more components 117 | if(buttonPressed.equalsIgnoreCase("Transfer")){ 118 | bankingAppDialog.addUserField(); 119 | } 120 | 121 | }else if(buttonPressed.equalsIgnoreCase("Past Transaction")){ 122 | bankingAppDialog.addPastTransactionComponents(); 123 | } 124 | 125 | // make the app dialog visible 126 | bankingAppDialog.setVisible(true); 127 | } 128 | } 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /src/guis/BaseFrame.java: -------------------------------------------------------------------------------- 1 | package guis; 2 | 3 | import db_objs.User; 4 | 5 | import javax.swing.*; 6 | 7 | /* 8 | Creating an abstract class helps us setup the blueprint that our GUIs will follow, for example 9 | in each of the GUIs they will be thee same size and will need to invoke their own addGuiComponents() 10 | which will be unique to each subclass 11 | */ 12 | public abstract class BaseFrame extends JFrame { 13 | // store user information 14 | protected User user; 15 | 16 | public BaseFrame(String title){ 17 | initialize(title); 18 | } 19 | public BaseFrame(String title, User user){ 20 | // initialize user 21 | this.user = user; 22 | 23 | initialize(title); 24 | } 25 | 26 | private void initialize(String title){ 27 | // instantiate jframe properties and add a title to the bar 28 | setTitle(title); 29 | 30 | // set size (in pixels) 31 | setSize(420, 600); 32 | 33 | // terminate program when the gui is closed 34 | setDefaultCloseOperation(EXIT_ON_CLOSE); 35 | 36 | // set layout to null to have absolute layout which allows us to manually specify the size and position of each gui component 37 | setLayout(null); 38 | 39 | // prevent gui from being resized 40 | setResizable(false); 41 | 42 | // launch the gui in the center of the screen 43 | setLocationRelativeTo(null); 44 | 45 | // call on the subclass' addGuiComponent() 46 | addGuiComponents(); 47 | } 48 | 49 | // this method will need to be defined by subclasses when this class is being inherited from 50 | protected abstract void addGuiComponents(); 51 | } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/guis/LoginGui.java: -------------------------------------------------------------------------------- 1 | package guis; 2 | 3 | import db_objs.MyJDBC; 4 | import db_objs.User; 5 | 6 | import javax.swing.*; 7 | import java.awt.*; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | import java.awt.event.MouseAdapter; 11 | import java.awt.event.MouseEvent; 12 | 13 | /* 14 | This gui will allow user to login or launch the register gui 15 | This extends from the BaseFrame which emans we will need to define our own addGuiComponent() 16 | */ 17 | public class LoginGui extends BaseFrame{ 18 | public LoginGui(){ 19 | super("Banking App Login"); 20 | } 21 | 22 | @Override 23 | protected void addGuiComponents() { 24 | // create banking app label 25 | JLabel bankingAppLabel = new JLabel("Banking Application"); 26 | 27 | // set the location and the size of the gui component 28 | bankingAppLabel.setBounds(0, 20, super.getWidth(), 40); 29 | 30 | // change the font style 31 | bankingAppLabel.setFont(new Font("Dialog", Font.BOLD, 32)); 32 | 33 | // center text in Jlabel 34 | bankingAppLabel.setHorizontalAlignment(SwingConstants.CENTER); 35 | 36 | // add to gui 37 | add(bankingAppLabel); 38 | 39 | // username label 40 | JLabel usernameLabel = new JLabel("Username:"); 41 | 42 | // getWidth() returns us the width of our frame which is about 420 43 | usernameLabel.setBounds(20, 120, getWidth() - 30, 24); 44 | 45 | usernameLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 46 | add(usernameLabel); 47 | 48 | // create username field 49 | JTextField usernameField = new JTextField(); 50 | usernameField.setBounds(20, 160, getWidth() - 50, 40); 51 | usernameField.setFont(new Font("Dialog", Font.PLAIN, 28)); 52 | add(usernameField); 53 | 54 | // create password label 55 | JLabel passwordLabel = new JLabel("Password:"); 56 | passwordLabel.setBounds(20, 280, getWidth() - 50, 24); 57 | passwordLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 58 | add(passwordLabel); 59 | 60 | // create password field 61 | JPasswordField passwordField = new JPasswordField(); 62 | passwordField.setBounds(20, 320, getWidth() - 50, 40); 63 | passwordField.setFont(new Font("Dialog", Font.PLAIN, 28)); 64 | add(passwordField); 65 | 66 | // create login button 67 | JButton loginButton = new JButton("Login"); 68 | loginButton.setBounds(20, 460, getWidth() - 50, 40); 69 | loginButton.setFont(new Font("Dialog", Font.BOLD, 20)); 70 | loginButton.addActionListener(new ActionListener() { 71 | @Override 72 | public void actionPerformed(ActionEvent e) { 73 | // get username 74 | String username = usernameField.getText(); 75 | 76 | // get password 77 | String password = String.valueOf(passwordField.getPassword()); 78 | 79 | // validate login 80 | User user = MyJDBC.validateLogin(username, password); 81 | 82 | // if user is null it means invalid otherwise it is a valid account 83 | if(user != null){ 84 | // means valid login 85 | 86 | // dispose this gui 87 | LoginGui.this.dispose(); 88 | 89 | // launch bank app gui 90 | BankingAppGui bankingAppGui = new BankingAppGui(user); 91 | bankingAppGui.setVisible(true); 92 | 93 | // show success dialog 94 | JOptionPane.showMessageDialog(bankingAppGui, "Login Successfully!"); 95 | }else{ 96 | // invalid login 97 | JOptionPane.showMessageDialog(LoginGui.this, "Login failed..."); 98 | } 99 | } 100 | }); 101 | add(loginButton); 102 | 103 | // create register label 104 | JLabel registerLabel = new JLabel("Don't have an account? Register Here"); 105 | registerLabel.setBounds(0, 510, getWidth() - 10, 30); 106 | registerLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 107 | registerLabel.setHorizontalAlignment(SwingConstants.CENTER); 108 | 109 | // adds an event listener so when the mouse is clicked it will launch the register gui 110 | registerLabel.addMouseListener(new MouseAdapter() { 111 | @Override 112 | public void mouseClicked(MouseEvent e) { 113 | // dispose of this gui 114 | LoginGui.this.dispose(); 115 | 116 | // launch the register gui 117 | new RegisterGui().setVisible(true); 118 | } 119 | }); 120 | 121 | add(registerLabel); 122 | } 123 | } 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/guis/RegisterGui.java: -------------------------------------------------------------------------------- 1 | package guis; 2 | 3 | import db_objs.MyJDBC; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | import java.awt.event.ActionEvent; 8 | import java.awt.event.ActionListener; 9 | import java.awt.event.MouseAdapter; 10 | import java.awt.event.MouseEvent; 11 | 12 | public class RegisterGui extends BaseFrame{ 13 | public RegisterGui(){ 14 | super("Banking App Register"); 15 | } 16 | 17 | @Override 18 | protected void addGuiComponents() { 19 | // create banking app label 20 | JLabel bankingAppLabel = new JLabel("Banking Application"); 21 | 22 | // set the location and the size of the gui component 23 | bankingAppLabel.setBounds(0, 20, super.getWidth(), 40); 24 | 25 | // change the font style 26 | bankingAppLabel.setFont(new Font("Dialog", Font.BOLD, 32)); 27 | 28 | // center text in Jlabel 29 | bankingAppLabel.setHorizontalAlignment(SwingConstants.CENTER); 30 | 31 | // add to gui 32 | add(bankingAppLabel); 33 | 34 | // username label 35 | JLabel usernameLabel = new JLabel("Username:"); 36 | 37 | // getWidth() returns us the width of our frame which is about 420 38 | usernameLabel.setBounds(20, 120, getWidth() - 30, 24); 39 | 40 | usernameLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 41 | add(usernameLabel); 42 | 43 | // create username field 44 | JTextField usernameField = new JTextField(); 45 | usernameField.setBounds(20, 160, getWidth() - 50, 40); 46 | usernameField.setFont(new Font("Dialog", Font.PLAIN, 28)); 47 | add(usernameField); 48 | 49 | // create password label 50 | JLabel passwordLabel = new JLabel("Password:"); 51 | passwordLabel.setBounds(20, 220, getWidth() - 50, 24); 52 | passwordLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 53 | add(passwordLabel); 54 | 55 | // create password field 56 | JPasswordField passwordField = new JPasswordField(); 57 | passwordField.setBounds(20, 260, getWidth() - 50, 40); 58 | passwordField.setFont(new Font("Dialog", Font.PLAIN, 28)); 59 | add(passwordField); 60 | 61 | // re-type password label 62 | JLabel rePasswordLabel = new JLabel("Re-type Password:"); 63 | rePasswordLabel.setBounds(20, 320, getWidth() - 50, 40); 64 | rePasswordLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 65 | add(rePasswordLabel); 66 | 67 | // create re-type password field 68 | JPasswordField rePasswordField = new JPasswordField(); 69 | rePasswordField.setBounds(20, 360, getWidth() - 50, 40); 70 | rePasswordField.setFont(new Font("Dialog", Font.PLAIN, 28)); 71 | add(rePasswordField); 72 | 73 | // create register button 74 | JButton registerButton = new JButton("Register"); 75 | registerButton.setBounds(20, 460, getWidth() - 50, 40); 76 | registerButton.setFont(new Font("Dialog", Font.BOLD, 20)); 77 | registerButton.addActionListener(new ActionListener() { 78 | @Override 79 | public void actionPerformed(ActionEvent e) { 80 | // get username 81 | String username = usernameField.getText(); 82 | 83 | // get password 84 | String password = String.valueOf(passwordField.getPassword()); 85 | 86 | // get re password 87 | String rePassword = String.valueOf(rePasswordField.getPassword()); 88 | 89 | // we will need to validate the user input 90 | if(validateUserInput(username, password, rePassword)){ 91 | // attempt to register the user to the database 92 | if(MyJDBC.register(username, password)){ 93 | // register success 94 | // dispose of this gui 95 | RegisterGui.this.dispose(); 96 | 97 | // launch the login gui 98 | LoginGui loginGui = new LoginGui(); 99 | loginGui.setVisible(true); 100 | 101 | // create a result dialog 102 | JOptionPane.showMessageDialog(loginGui, "Registered Account Successfully!"); 103 | }else{ 104 | // register failed 105 | JOptionPane.showMessageDialog(RegisterGui.this, "Error: Username already taken"); 106 | } 107 | }else{ 108 | // invalid user input 109 | JOptionPane.showMessageDialog(RegisterGui.this, 110 | "Error: Username must be at least 6 characters\n" + 111 | "and/or Password must match"); 112 | } 113 | } 114 | }); 115 | add(registerButton); 116 | 117 | // create login label 118 | JLabel loginLabel = new JLabel("Have an account? Sign-in here"); 119 | loginLabel.setBounds(0, 510, getWidth() - 10, 30); 120 | loginLabel.setFont(new Font("Dialog", Font.PLAIN, 20)); 121 | loginLabel.setHorizontalAlignment(SwingConstants.CENTER); 122 | loginLabel.addMouseListener(new MouseAdapter() { 123 | @Override 124 | public void mouseClicked(MouseEvent e) { 125 | // dispose of this gui 126 | RegisterGui.this.dispose(); 127 | 128 | // launch the login gui 129 | new LoginGui().setVisible(true); 130 | } 131 | }); 132 | add(loginLabel); 133 | } 134 | 135 | private boolean validateUserInput(String username, String password, String rePassword){ 136 | // all fields must have a value 137 | if(username.length() == 0 || password.length() == 0 || rePassword.length() == 0) return false; 138 | 139 | // username has to be at least 6 characters long 140 | if(username.length() < 6) return false; 141 | 142 | // password and repassword must be the same 143 | if(!password.equals(rePassword)) return false; 144 | 145 | // passes validation 146 | return true; 147 | } 148 | } 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | --------------------------------------------------------------------------------