Week Five

We'll be doing more of getting the program really functional this week. Right now when we run the program it will show the random number and what the user guessed. Let's now get the program to really analyze the guess and provide output.
  1. Go into the Java Perspective and at the top where all the fields are defined add a new field for tracking how many guesses have been made so far
  2. private int guessCount = 0;
  3. That will create the guessCount variable and initialize it to zero.
  4. Go to the guessFocusListener and look at the focusLost() method. It calls analyzeGuess. Double click on analyzeGuess within the focusLost and hit F3.
  5. F3 in eclipse is used alot! It will take you to that method so you can track the flow of the program and get around faster.
  6. Inside the analyzeGuess() method, on the first line add the following
  7. This will now increase the number of guesses and display it. Now we need to have the program compare the guess to the random number.
  8. Add the following at the beginning of the analyzeGuess() method:
  9. Save your work
  10. Run your program and test it.

Now you have very basic functionality. However there are still alot of things that could go wrong. What if the user enters a letter instead of a number in the guessText? The user won't see a problem, but try it and see what happens in Eclipse. The console gives an error: java.lang.NumberFormatException: For input string: "b" This ugly long error message is called a stack trace. It shows the execution that the program followed that resulted in the error. Look at the lines just below the "NumberFormatException". It shows all the objects used up to that point. Look for the first line that shows the source in blue (which is a link) that looks like this: at simple.HiLoGame.analyzeGuess(HiLoGame.java:65)

Click on the link. That will take you to the line of code that caused the Number Format Exception. A number format exception is when you are trying to convert a String to a number, and the String can't be converted into a number because it has a letter in it.

When we run the program the user doesn't get an error, it just doesn't do anything when they enter a letter. We should inform the user that the input was inappropriate and how they can fix it. So do the following:

  1. At the beginning of analyzeGuess() just before the "int guessedInt = Integer.parseInt(guessString);" enter "try {" and hit enter.
  2. This will automatically put the closing bracket after the "int guessedInt..." line. That is good.
  3. Right after the closing bracket on the try block type the following: "catch(NumberFormatException n) {" and hit enter
  4. Eclipse also puts a closing bracket on the catch block.
  5. Inside the catch block enter the following: "JOptionPane.showMessageDialog(getContentPane(), "Invalid guess. Must be a number with no letters. Try again.", "Number only!", JOptionPane.ERROR_MESSAGE);"
  6. Save your work
  7. Notice that Ecplise says there is a couple of errors with the red blocks on the right of the scroll bar. It underlined guessedInt. By putting the mouse over the red X on the left side of the window it says: "guessedInt cannot be resolved". Do you know why? Double click the red underlined "guessedInt" and hit F3. It doesn't go anywhere. Eclipse doesn't know where guessedInt is in relation to where it is in the if statement. That is because we defined the guessedInt variable inside the try block. Its only visible inside that try block. This is where programming sometimes can get tricky. You need to know the scope of your variables. In this case the guessedInt variables scope is limited to the try block. You can make the guessedInt extend to the scope of the entire analyzeGuess() method by putting the following BEFORE the try block: "int guessedInt = 0;". This now defines the guessedInt variable outside the try block and now can be referenced anywhere within the analyzeGuess() method. But that isn't all. You have a new error on the guessedInt within the try block. "Duplicate local variable guessedInt" if you mouseover the red 'X'. This means that you have defined guessedInt twice. Once above the try block and once inside the try block. They both have the same name. Since we already defined the guessedInt variable outside the try block you can just remove the "int" in the try block. This tells the compiler to not try to create the guessedInt, but use the one that was created before the try block.
  8. Save your work and run the program
Now when you run the program and enter an "a" as a guess you get an error message and you have "caught" the NumberFormatException and displayed a user friendly message to the user to fix it. You've done this using a Dialog.

Static Methods vs Instance Methods

Static methods - Example = Class.method()

Instance methods - Example = Class myClass = new Class();
                                                  myclass.method();

The difference with Static Methods and Instance Methods is that instance methods require you to have an instance of the class (You have an instance when you create a class using the "new" keyword. You have an instance of the class in the myClass object. You then access the methods referencing the myClass object you created. With static methods, you don't need to create an instance of the object, you can reference the Object type itself, and the static method inside the object. Look at the examples above to see the difference in how you can call a static and a instance method.

JOptionPane is an object that comes with a static method called "showMessageDialog". Static means that you can reference an objects methods without having to have an instance of it. Typically when you want to execute a method on an object that you don't have yet, you have to create the object first and then call the method. A static method allows for you to create an object and use its method all in the same line. You create the JOptionPane by just referencing it and then putting a dot and then the method name. You can't do this with every method. You can only do this on methods that are defined static.

The JOptionPane's showMessageDialog is overloaded - meaning that it can have varying numbers of parameters. You have to look at the definition of showMessageDialog to be aware of all the available options. The more complex you want your dialog to be, the more options you will use. In our case we want to show the message "Invalid guess. Must be a number with no letters. Try again." and include an error icon in the message. We also want the title bar on the dialog to say "Number only!". Then the last parameter is a static field (aka variable) in JOptionPane which specifies which type of icon we want displaying in the Dialog. Check out the Creating simple Dialogs page for details.

We've covered quite a bit of material this week. Let's stop there. Make sure you review what you've done and make sure you understand what we've covered. You may want to consider starting at week 2 and rebuilding your program again, so you can review everything we've covered so far. The more you build your program from scratch over and over, the more you will either understand it, or have questions about. Anyone can just follow a recipe which is what we're doing here. But do really get a taste and love for creating programs, you need to understand how to do it without following a recipe.

Homework

  1. UI Cleanup. Use the Form Editor to clean up the UI and make it better looking,
  2. Tell me what method call in the analyzeGuess() is static which we added in step 8 at the beginning of this week's lesson. - If you don't have any idea reread my notes on Static Methods vs Instance Methods above.

Concepts discussed

  1. NumberFormatException
  2. Creating simple Dialogs
  3. Variable Scope
  4. Static and Instance Methods

If you have questions please email me!