CPSC 120 Lab 12
Class Dependencies and Dialog Boxes

As usual, create a lab12 subdirectory for today's lab, open up Mozilla Firefox and the Web version of this handout, and open emacs.

Dependencies Among Objects of the Same Class

  1. All Java classes are derived from the Object class in the Java Class Library. That class provides default versions of several methods. Two of those methods are toString and equals. We have used toString often. We know that if we want to print an object we can use the object in a print statement and, if we have written a toString method in our class, that method will be invoked automatically and the string it returns will be printed. If we do not have a toString method, the reference (a hexadecimal number) to the object will be printed. Similarly, we can use equals to compare objects from a class we have written but if we haven't written our own method, the method will compare references. In this exercise you will define equals for dice objects. Save the files Die.java, PairOfDice.java, and TestEquals.java to your directory and do the following.

    1. The Die class is from the text book (we've used it before). The constructor initializes the face on a die to 1. The PairOfDice class models a pair of dice (its instance variables are two Die objects). Study the TestEquals program to see what it does, then compile and run it. You should notice that even though all three pairs of dice are initially snake eyes (two 1s) they aren't all "equal" because the references are not the same.

    2. Open up Die.java and add an equals method. Two Die objects will be equal if they have the same face value. The equals method signature is:
           public boolean equals (Die otherDie)
      

    3. Open up PairOfDice.java and add an equals method. When writing an equals method for a class you need to decide what you mean for two objects to be equal. For a pair of dice there are two possibilites - you could mean the sum on the dice is the same (that's often what is needed in games) or you could mean that the dice have the same faces (so, for example if the faces are 3 and 4 on one pair, then another pair would be equal with a 3 and 4 (or 4 and 3) but not 2 and 5). Write your method using the latter definition. You should use the equals method in the Die class in your method. There is a getDie method in the PairOfDice class that takes an integer parameter (1 to get die1 and 2 to get die2) and returns the Die object. Be sure to think about what the signature for equals should be in the PairOfDice class.

    4. Compile and run TestEquals again. Now all pairs should be equal.

    5. Add a for loop to the program that rolls pair1 and pair2 20 times and counts the times they are equal. Print out each roll in the loop along with a message if the two pair are equal. After the loop print the number of times the rolls were the same. So your output should look something like this:
           Roll 1: [1 : 6] and [3 : 2]
           Roll 2: [3 : 4] and [4 : 3] - equal
           Roll 3: [6 : 2] and [4 : 4]
           ...
      
           Roll 20: [1 : 1] and [5 : 2]
           
           The pair were equal 3 times.
      
      Run the program enough to be sure that your equals is correct. Note above that [6 : 2] and [4 : 4] are not equal even though the sum is the same but [3 : 4] and [4 : 3] are equal.

    Print PairOfDice.java and TestEquals.java to hand in.

  2. File Account.java contains a class representing a bank account similar to the one we used in earlier labs. (Note that the constructor has been modified so that it generates the account number randomly.) Save this file to your directory and use it in the exercises below.
    1. Suppose the bank wants to keep track of how many accounts exist.
      • Declare a private static integer variable numAccounts to hold this value. Like all instance and static variables, it will be initialized (to 0, since it's an int) automatically.
      • Add code to the constructor to increment this variable every time an account is created.
      • Add a static method numAccounts that returns the total number of accounts. (Think about why this method should be static -- its information is not related to any particular account.)
      Compile your revised Account class. Now open TestAccounts1.java, study it to see what it does, and save it to your directory. Use it to test your Account class.

    2. Add a method to the Account class that allows money to be transferred between accounts. This could be done by using two separate methods transferIn(Account otherAcct, double amt) and transferOut(Account otherAcct, double amt), or by using just one method transfer(Account otherAcct, double amt) and defining (and clearly documenting!) it so that it transfers money FROM the current account TO the account that is passed as a parameter. Use this second strategy (just one method). Inside the transfer method you can manipulate the balance directly or use the deposit and withdraw methods you have already written. Either way, first you'll still have to check that the balance in the from account is sufficient; if not, print a message and don't carry out the transfer.

    3. Now save TestAccounts2.java to your directory. Add code as indicated by the comments to transfer $50 from Madison's account to Spud's account and then to transfer $25 from Spud's account to Madison's account. Print both accounts after each transfer. Don't fill in the rest of the missing code yet. Run it to be sure it works.

    4. Add a static method to the Account class that lets the user transfer money between two accounts without going through either account. You can call the method transfer just like the other one -- you are overloading it. Your new method should take two Account objects and an amount and transfer the amount from the first account to the second account. The signature will look like this:
      public static void transfer(Account fromAcct, Account toAcct, double amt)
      
      Compile your revised Account class.

    5. Following the next comment in TestAccounts2.java, fill in code to use the static transfer method to transfer another $10 from Spud's account to Madison's account. Test your program.

    6. Add a method void close() to your Account class that closes an account. It should set the name to null (note: this is the null reference which is not the same as an empty string), the balance to 0, and the account number to 0. It should also decrement the total number of accounts.

      Also add a static method Account consolidate(Account acct1, Account acct2) to your Account class that creates a new account whose balance is the sum of the balances in acct1 and acct2 and closes acct1 and acct2. The new account should be returned. Two important rules of consolidation:

      • Only accounts with the same name can be consolidated. The new account gets the name on the old accounts.
      • Two accounts with the same number cannot be consolidated. (This would be an easy way to double your money!)

      Check these conditions before creating the new account. If either condition fails, do not create the new account or close the old accounts; print a useful message and return null.

    7. Following the comments in TestAccounts2.java, add code to create a second account for Madison with a balance of 500. Print this account and the total number of accounts. Then consolidate Madison's two accounts into account madConsolidated; print all three accounts and the total number of accounts.

    8. Finally, add code to consolidate Spud's account with itself, putting the new account into spudConsolidated. Of course, this consolidation won't work, but it's useful to see what happens when you try it. Print both spudAcct and spudConsolidated after the call.

    Print Account.java and TestAccounts2.java to turn in.

    Dialog Boxes

    We have been using the Scanner class to get input from the user, but there are other possibilities as well. One is to use dialog boxes, which are described on pages 267-270 of the text. A dialog box is a window that pops up and allows the user to interact with it. It might ask for text input, provide choices, or simply present a message. Dialog boxes are created using static methods of the JOptionPane class; two of the most useful methods are listed below:

    File Dialogs.java contains a simple program that uses dialog boxes to prompt the user for two test grades and then displays the average of those grades. Study this program; note that the value returned by the showInputDialog method is a String, so the parseInt method of the Integer class must be used to gets its integer value.

    Run the program the usual way entering integer test grades then run it again entering a value that is not an integer. The exception you see comes from the parseInt method -- it's saying that the value entered is not a legal format for the kind of number required (int).

    Modify the Dialogs class as follows (use dialog boxes for all input and output):

    1. Replace the code for entering two test grades with a loop (while or do) and that lets the user keep entering grades as long as he/she wishes. Each time through the loop display an input dialog box to enter a grade and a confirm dialog box to ask if there are more grades to enter. At the end use a message dialog box to display the average.

    2. When the user enters a grade, check to see if it is between 0 and 100. If not, display an input dialog box saying that the number must be between 0 and 100 and get a new value. Keep doing this until the value entered is in the appropriate range.

    Print Dialogs.java to turn in.

What to turn in

Turn in hardcopy of PairOfDice.java, TestEquals.java, Account.java, TestAccounts2.java, and Dialogs.java. Tar your lab12 directory and send it to your instructor.