Activity 3, COSC 110 A, March 2, 2005
Goals: The purpose of this activity is to introduce you to the basic operations of the BlueJ debugger (that allow you to explore source code "one line at a time" and could be used to check for logical errors in code), and gain some practice in object interaction, and using external and internal method calls.
Work in groups of two (or alone). You should only submit one file for your group (via Blackboard).
  1. Login and navigate to G:\Lintont\introcs\ and copy the folder named activity3. Paste this copy on your H:\ drive.
  2. Start BlueJ and open your activity3 project (the one on your H:\ drive).
  3. The project should contain two classes, Date and Person. These have been modified slightly since the last time you saw them. In particular, the Date class now has the ability to create and return information about the current date (i.e. about today's month, day of the month, and year). In addition, all constructors for the Person class now properly calculate the age (as of today) of the Person object being created. Make sure the project is compiled, and then use BlueJ to create a Date object named date1, using the no-parameter constructor (which sets the date to represent today). Once date1 appears on the object bench, call its getDate() method (to see that it corresponds to today) and then call its tomorrow() method (just to see that this also works).
  4. Remove date1 from the object bench (right click it and select remove) and then create 2 new Date objects using the three parameter constructor. Name the first one leap, and have it correspond to February 29, 2004. Name the second one newyear and have it correspond to December 31, 1987.
  5. One thing that a debugger does is allow you to stop a program (or source code) in the middle of execution. This allows you to quickly run the code you know works properly, and stop at a spot where you want to see more closely what is happening. We don't really need to see code run more closely today, but this is a useful skill, and one can gain a better understanding of what code is doing, if you can see it run one line at a time, and see the values of all relevant variables before and after each command is executed. You instruct a debugger to "stop" at a certain command by placing a breakpoint "at" the line of code where you want it to stop. BlueJ's debugger only allows breakpoints to be placed (or set) at commands that actually perform some task (so not on comment lines, method header lines, or lines that only declare a variable). As well, a class must be compiled before you can set breakpoints (and each time you re-compile a class, the old breakpoints are removed). Setting breakpoints in BlueJ is quite easy, you simply open the editor for the source code file (you can do this by double clicking on the class icon in the main BlueJ project window), and then clicking (once with the left mouse button) in the left "gutter" (a thin vertical strip on the left edge of the editor window) on the line where you want a breakpoint. If you succeed, a stop sign icon appears in the gutter. Open the Date class's source code file in the editor. About 2/3 of the way through this file, you should find the source code for the tomorrow method. Set a breakpoint on the first line of code in the body of this method (it reads int tMonth = month;).
  6. We will now see how to "step through code" one line at a time with BlueJ's debugger. Invoke the tomorrow() method of leap. When BlueJ executes this method, it will reach the breakpoint you just set and both the editor window and the debugger window will appear. Rearrange these 2 windows so that you can see both of them. You may need to resize these windows, and you should be aware that you can resize the sub-windows of the debugger by dragging the borders up, down, left, or right. One critical fact is that the editor indicates "where" you are in the source code file using a black arrow, and remember that the arrow is on the line of code that is about to be executed (so BlueJ hasn't yet executed the command with the arrow pointing to it). Some of the most useful features of the debugger are the displayed values of instance variables (fields), local variables, and the execution control "buttons" at the bottom of the debugger window. It is often quite informative to see what happens to the variable values as each line executes. Here is a brief explanation of the execution buttons (from left to right).
  7. Press the STEP button. You should see a local variable appear in the debugger window, along with its value. Press the STEP button until all 4 local variables have appeared, and the arrow is pointing at the first if statement. Click in the editor window and scroll down a bit (if needed) so that you can see the next few commands (at least far enough to see the first line of code in the else clause). BlueJ doesn't really indicate the result of the test in if statements, but you can determine the result by watching whether the arrow jumps to the true block or to the false block (but the arrow will jump over all lines that don't really perform a task). Press the STEP button so that the if test gets executed. You should see the arrow jump down to the false block, indicating that the test was false (since 2-30-2004 is not a valid date). Notice how when using STEP, the entire body of the isValid() method was executed as if it were one command.
  8. You should now be on another line of code that contains a call to the isValid() method. This time, press the STEP INTO button. The arrow should jump to the body of the isValid() method. STEP through that method. YOu should see that the first 4 if tests are false (since their true code is skipped over), but the fifth if test yields true, and eventually the value of true is returned. Once you jump back to the tomorrow() method (after the return statement of the isVaid() is executed), press the CONTINUE button to complete the execution. You should see the correct date (March 1, 2004) as the result. You have now seen the basic features of stepping through code with BlueJ's debugger. If you're interested, you can call the tomorrow() method of newyear and see how that value is actually calculated one line at a time. When your code is producing unexpected results, or you want to try and better understand what certain blocks of code are doing, remember the debugger. It can be very useful. To delete a breakpoint, just click on the stop sign icon, or edit the source code file and re-compile it. You should delete the breakpoint you set earlier.
  9. Now let's add some things to the Person class. Be sure to add this new method at the bottom of your Person.java file (so I know where to look for it). You may wish to invoke leap's (or newyear's) getCurrentYear() method to see how this method works, before attempting this part. Add a method named dayAfter (with no inputs) that returns a String corresponding to the day after the person's birthday "this year". For example, my birthday is 8/21/1961, and if you had a Person object corresponding to me, your method should return "August 21, 2005", if it was called this year, and it should return "August 21, 2006" if it was called next year (so don't use "2005" as the year, but use the birthday field's getCurrentYear() method to get the year). You can look at the setAge() method in this class to see an example of the code that creates a Date object (your's will look a little different however), and the tomorrow() method in the Date class declares some local variables (in case you're wondering how you do that). Here is one possible strategy for the body of your method:
    1. Declare three local variables all of type int, say m, d, and y.
    2. Use the standard accessor methods of the birthday field to store the month and day of the Person's birthday in m and d, respectively.
    3. Use birthday's getCurrentYear() method to store the current year in y.
    4. Construct a new Date object (you pick the name) using m, d, and y as parameters.
    5. Return the result of calling your new Date object's tomorrow() method.
  10. Be sure to add this new method just below the dayAfter() method of your Person.java file. You may want to invoke newyear's (or leap's) getCurrentDay()and getCurrentMonth() methods to see what they do before proceeding on this part. Add a method to the Person class that prints (to the standard terminal window), whether or not the person's birthday has already occured this year. There should be 3 possibilities, either print "Happy Birthday!" if today is their birthday, or print "Your birthday is past.", if they have had their birthday this year, or print "Your birthday is coming.", if they haven't had their birthday yet. You should name your method birthdayMessage, it should have no inputs, and a void return type. You will need to call a few of the birthday field's methods, like getCurrentMonth() and getCurrentDay(), in your method, and these will be external method calls (since they are defined in the Date class). The code for the setAge() method in the Date class contains "tests" similar to those that you might chose to perform.
  11. When you are finished, go to the Assignments section of the Blackboard site for this class, and use the View/Complete link for acticity 3 to "Submit" your Person.java file.