elltyl325

bankaccount classes

Sep 21st, 2020
1,347
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 1. BankAccountUser
  2. 2. BankAccount
  3. 3. SimulationControl
  4. -----------------------------------------------------------------------------------------------------------------------------------------
  5. package threads;
  6.  
  7. import java.util.logging.Level;
  8. import java.util.logging.Logger;
  9.  
  10. /**
  11.  * A class representing a bank account user.
  12.  * @author tcolburn
  13.  */
  14. public class BankAccountUser extends Thread {
  15.  
  16.     /**
  17.      * Creates a new bank account user.
  18.      * @param name the user's name
  19.      * @param account the account used
  20.      * @param transactions an array of integers representing deposits (positive)
  21.      * and withdrawals (negative)
  22.      */
  23.     public BankAccountUser(String name, BankAccount account, int[] transactions) {
  24.         super(name);
  25.         this.waiting = false;
  26.         this.account = account;
  27.         if(transactions == null){
  28.             transactionsRemaining = 0;
  29.         }
  30.         else transactionsRemaining = transactions.length;
  31.         this.transactions = transactions;
  32.        
  33.     }
  34.  
  35.     public boolean isWaiting() { return waiting; }
  36.  
  37.     public void changeWaitingStatus(boolean bool){
  38.         waiting = bool;
  39.     }
  40.     /**
  41.      * Getter for the number of transactions remaining for this user.
  42.      * @return the number of transactions remaining
  43.      */
  44.     public int getTransactionsRemaining() {
  45.         return transactionsRemaining;
  46.     }
  47.    
  48.     public BankAccount getAccount(){
  49.         return account;
  50.     }
  51.    
  52.     /**
  53.      * Runs the transactions in a loop.
  54.      * When finished, a message is logged.
  55.      */
  56.     public void run() {
  57.        
  58.         for (int amount : transactions) {
  59.             if (amount > 0) {
  60.                 account.deposit(amount, this);
  61.             }
  62.             else if (amount < 0) {
  63.                 try {
  64.                     account.withdraw(Math.abs(amount), this);
  65.                 } catch (InterruptedException ex) {
  66.                     Logger.getLogger(BankAccountUser.class.getName()).log(Level.SEVERE, null, ex);
  67.                 }
  68.             }
  69.             else {
  70.                 // amount will not be zero
  71.             }
  72.             transactionsRemaining--;
  73.             try {
  74.                 Thread.sleep((int)(Math.random() * 100));
  75.             } catch (InterruptedException ex) {
  76.                 Logger.getLogger(BankAccountUser.class.getName()).log(Level.SEVERE, null, ex);
  77.             }
  78.         }
  79.     }
  80.    
  81.     private boolean waiting;
  82.     private final BankAccount account;
  83.     private final int[] transactions;
  84.     private int transactionsRemaining;
  85. }
  86.  
  87. -----------------------------------------------------------------------------------------------------------------------------------------
  88.  
  89. package threads;
  90.  
  91. /**
  92.  * This class represents a bank account. It provides methods for setting the
  93.  * balance, depositing, and withdrawing.
  94.  * @author tcolburn
  95.  */
  96. public class BankAccount {
  97.    
  98.     /**
  99.      * Creates a new bank account.
  100.      * @param logView the viewing area for logging deposit and withdrawal messages
  101.      */
  102.     public BankAccount(LogView logView) {
  103.         this.logView = logView;
  104.     }
  105.    
  106.     /**
  107.      * Deposits an amount on behalf of a bank account user.
  108.      * A message is logged showing the deposit amount and new balance.
  109.      * Note that an assertion is used to check if this method is thread-safe.
  110.      * @param amount the amount to deposit
  111.      * @param user the user making the deposit
  112.      */
  113.     public synchronized void deposit(int amount, BankAccountUser user) {
  114.         int newBalance = balance + amount;
  115.         logView.log("\n" +user.getName()+ " Depositing $" +amount);
  116.         balance = balance + amount;
  117.         logView.log(". Balance = " + balance);
  118.         checkFinished(user);
  119.         notifyAll();
  120.         assert(balance == newBalance); // should be true if this method is thread-safe
  121.     }
  122.     /**
  123.      * Withdraws an amount on behalf of a bank account user.
  124.      * A message is logged showing the withdrawal amount and new balance.
  125.      * If the withdrawal would cause a negative balance, a runtime exception
  126.      * is thrown.
  127.      * Note that an assertion is used to check if this method is thread-safe.
  128.      * @param amount the amount to withdraw
  129.      * @param user the user making the withdrawal
  130.      * @throws java.lang.InterruptedException
  131.      */
  132.     public synchronized void withdraw(int amount, BankAccountUser user) throws InterruptedException {
  133.         int newBalance = balance - amount;
  134.         logView.log("\n" +user.getName() + " Withdrawing $" + amount);
  135.         while ( amount > balance ) {
  136.             user.changeWaitingStatus(true);
  137.             wait();
  138.         }
  139.         user.changeWaitingStatus(false);
  140.         balance = balance - amount;
  141.         logView.log(". Balance = " + balance);
  142.         checkFinished(user);
  143.         assert(balance == newBalance); // should be true if this method is thread-safe
  144.     }
  145.    
  146.     /**
  147.      * Private helper method to log user finished message.
  148.      * @param user the bank account user
  149.      */
  150.     private void checkFinished(BankAccountUser user) {
  151.             if (user.getTransactionsRemaining() == 1) {
  152.             logView.log("\n******************************\n        " + user.getName() +
  153.                         " finished.\n******************************");
  154.         }
  155.     }
  156.  
  157.     /**
  158.      * Setter to set the initial balance of this bank account.
  159.      * @param balance the initial balance
  160.      */
  161.     public void setBalance(int balance) {
  162.         this.balance = balance;
  163.     }
  164.  
  165.     /**
  166.      * Getter for the current balance of this bank account.
  167.      * @return the current balance
  168.      */
  169.     public int getBalance() {
  170.         return balance;
  171.     }
  172.    
  173.     private final LogView logView;
  174.    
  175.     private int balance;
  176. }
  177.  
  178.  
  179.  
  180. ----------------------------------------------------------------------------------------------------------------------------------------
  181.  
  182.  
  183. package threads;
  184.  
  185. import java.util.Random;
  186. import javafx.collections.FXCollections;
  187. import javafx.geometry.Insets;
  188. import javafx.geometry.Pos;
  189. import javafx.scene.control.Button;
  190. import javafx.scene.control.ComboBox;
  191. import javafx.scene.control.Control;
  192. import javafx.scene.control.Label;
  193. import javafx.scene.layout.HBox;
  194. import javafx.scene.layout.VBox;
  195. import javafx.scene.text.Text;
  196.  
  197. /**
  198.  * A class providing controls for a bank account simulation.
  199.  * Controls allow for selecting a starting balance for the account,
  200.  * the number of users (siblings) of the account, the transaction limit,
  201.  * the number of transactions each user will make, and a button to
  202.  * run the simulation.
  203.  * @author tcolburn
  204.  */
  205. public class SimulationControl extends VBox {
  206.    
  207.     /**
  208.      * Creates the simulation controls arranged in a vertical box
  209.      * @param account the bank account
  210.      * @param logView the message logging area
  211.      */
  212.     public SimulationControl(BankAccount account, LogView logView) {
  213.         this.account = account;
  214.         this.logView = logView;
  215.        
  216.         balance = new ComboBox(FXCollections.observableArrayList(100, 500, 1000, 10000));
  217.         balance.setValue(100);
  218.        
  219.         siblings = new ComboBox(FXCollections.observableArrayList(1, 2, 3, 4, 5));
  220.         siblings.setValue(1);
  221.        
  222.         limit = new ComboBox(FXCollections.observableArrayList(50, 100, 200, 500));
  223.         limit.setValue(50);
  224.        
  225.         numTransactions = new ComboBox(FXCollections.observableArrayList(10, 25, 50, 100));
  226.         numTransactions.setValue(10);
  227.        
  228.         setPadding(new Insets(10));
  229.        
  230.         super.getChildren().addAll(
  231.                 new LabeledControl("Starting Balance:", balance),
  232.                 new LabeledControl("Number of Siblings:", siblings),
  233.                 new LabeledControl("Transaction Limit:", limit),
  234.                 new LabeledControl("Transactions per Sibling:", numTransactions),
  235.                 new Runner());
  236.     }
  237.    
  238.     /**
  239.      * A private class for creating labeled combo boxes.
  240.      */
  241.     private class LabeledControl extends HBox {
  242.         public LabeledControl(String label, Control control) {
  243.             setPadding(new Insets(5));
  244.             setSpacing(10);
  245.             setAlignment(Pos.CENTER_LEFT);
  246.             Label lab = new Label(label);
  247.             lab.setPrefWidth(labelWidth);
  248.             super.getChildren().addAll(lab, control);
  249.         }
  250.     }
  251.    
  252.     /**
  253.      * A private class for the RUN button.
  254.      * When clicked, the users are generated, the account balance is set.
  255.      * and each user's transactions are executed.
  256.      */
  257.     private class Runner extends Button {
  258.         public Runner() {
  259.             super("RUN");
  260.             setOnAction(e -> {
  261.                 generateUsers();
  262.                 account.setBalance(balance.getValue());
  263.                 logView.clear();
  264.                 try {
  265.                     for (BankAccountUser user : users) {
  266.                         user.start();
  267.                     }
  268.                     parent.start();
  269.                 }
  270.                 catch(Exception ex) {
  271.                     logView.log(ex.getMessage());
  272.                 }
  273.             });
  274.         }
  275.     }
  276.    
  277.     /**
  278.      * A private helper method that generates an array of bank account users
  279.      * as an instance field.
  280.      */
  281.     private void generateUsers() {
  282.         users = new BankAccountUser[siblings.getValue()];
  283.         for (int i = 0; i < users.length; i++) {
  284.             users[i] = new BankAccountUser("Sibling " + (i+1), account, generateTransactions());
  285.         }
  286.         parent = new BankAccountRescuer("Parent", account, null, users);
  287.     }
  288.    
  289.     /**
  290.      * A private helper method that generates an integer array of random transactions.
  291.      * A positive integer is a deposit; a negative integer is a withdrawal.
  292.      * The transaction amounts are randomly generated within the limit, and whether
  293.      * the amount is a deposit or withdrawal is also random.
  294.      * @return the array of transactions
  295.      */
  296.     private int[] generateTransactions() {
  297.         int[] transactions = new int[numTransactions.getValue()];
  298.         for (int i = 0; i < transactions.length; i++) {
  299.             int amount = GENERATOR.nextInt(limit.getValue()) + 1; // 1 <= amount <= amountLimit
  300.             transactions[i] = GENERATOR.nextBoolean() ? amount : -amount;
  301.         }
  302.         return transactions;
  303.     }
  304.    
  305.     private static final Random GENERATOR = new Random();
  306.    
  307.     private final ComboBox<Integer> balance;
  308.     private final ComboBox<Integer> siblings;
  309.     private final ComboBox<Integer> limit;
  310.     private final ComboBox<Integer> numTransactions;
  311.    
  312.     private final BankAccount account;
  313.    
  314.     private final LogView logView;
  315.    
  316.     private BankAccountUser[] users;
  317.     private BankAccountRescuer parent;
  318.    
  319.     private final double labelWidth = new Text("Transactions per Sibling:").getLayoutBounds().getWidth();
  320. }
RAW Paste Data