0

I'm having a problem handling exceptions. Honestly, I really don't understand how it works since I self study.

I'm working with a program where there would be a main menu with the following choices.

  1. Odd/Even - asks an integer input from user and identify if it is an odd or even. Program would continuously ask for an integer input if the user keeps on giving character inputs. (I was able to do this but I keep on getting errors when I use br.readLine() in getting input. Pls see codes below. So I used the normal parsing. Since I didn't use Buffered Reader, I try to delete it but the Odd/Even program wouldn't handle the exception without it.)

  2. Vowel/Consonant - asks the user for a character input and identify if it is a vowel or a consonant. Program should reject integer inputs. The program I made with the codes below doesn't reject integer inputs. I tried searching for answers but I can't find one.

      1. Please ignore for now.

My problem/s involve/s the following questions. 1. Why doesn't the program Odd/Even handle the NumberFormat exception whenever I try to delete the BufferedReader line even though it wasn't used in the whole program?

  1. How can I reject integer inputs for the Vowel/Consonant program?

Here is a video when I tried to run the program.

http://tinypic.com/r/24ou9kz/9

When I exit the program, the console shows this.

Exception in thread "main" java.lang.NumberFormatException: null at java.lang.Integer.parseInt(Unknown Source) at java.lang.Integer.parseInt(Unknown Source)

import javax.swing.JOptionPane;

import java.io.*;

import java.util.InputMismatchException;

public class DoWhileIf {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String input;
        int choice, num = 0;
        char again = 0;
        boolean err = true;
        do {
            input = JOptionPane.showInputDialog("Menu\n[1] Odd/Even\n[2] Vowel/Consonant\n[3] CQM\n[4] Fuel Efficiency\n[5] Scholarship\n[6] Exit program.\n\nEnter Choice.");
            choice = Integer.parseInt(input);

            if (choice == 1) {

                do {
                    do {
                        try {
                            input = JOptionPane.showInputDialog("Input an integer : ");
                            num = Integer.parseInt(input);
                            err = false;
                        } catch (NumberFormatException o) {
                            JOptionPane.showMessageDialog(null,"Error!");
                            err = true;
                        } 
                    } while (err);

                        if (num % 2 == 0) {
                            JOptionPane.showMessageDialog(null,"Even.");
                        }

                        else {
                            JOptionPane.showMessageDialog(null,"Odd.");
                        }
                        do {
                            input = JOptionPane.showInputDialog("Try again? Press Y for yes or N to go back to main menu.");
                            again = input.charAt(0);
                        } while (again != 'Y' && again != 'y' && again !='N' && again !='n');
                    } while (again == 'Y' || again == 'y');             
                }

            if (choice == 2) {
                char letter = 0;
                do {
                    do {
                        try {
                            input = JOptionPane.showInputDialog("Character : ");
                            letter = input.charAt(0);
                            err = false;
                        } catch (InputMismatchException a) {
                            JOptionPane.showMessageDialog(null,"Error!");
                            err = true;
                        }
                    } while (err); 

                    if (letter == 'a' || letter == 'A' || letter == 'e' || letter == 'E' || letter == 'i' || letter == 'I' || letter == 'o' || letter == 'O' || letter == 'u' || letter == 'U') {
                        JOptionPane.showMessageDialog(null,"Vowel");
                    }
                    else {
                        JOptionPane.showMessageDialog(null,"Consonant");
                    }
                    do {
                        input = JOptionPane.showInputDialog("Try again? Press Y for yes or N to go back to main menu.");
                        again = input.charAt(0);
                    } while (again != 'Y' && again != 'y' && again !='N' && again !='n');
                } while (again == 'Y' || again == 'y');
            }
        } while (choice <= 0 || choice > 6 || again == 'N' || again == 'n');
    }
Kei
  • 3
  • 4
  • 2
    Possible duplicate of [What is a NumberFormatException and how can I fix it?](http://stackoverflow.com/questions/39849984/what-is-a-numberformatexception-and-how-can-i-fix-it) – xenteros Nov 16 '16 at 14:14
  • Please refer to the attached ^article about [tag:numberformatexception] – xenteros Nov 16 '16 at 14:15
  • I take it that the `parseInt()` call that is failing is the first one: `choice = Integer.parseInt(input);` . Try to set a breakpoint on that line, or put a `System.out.println(input)` just above that line, to see what value the variable `input` has at that point, because the exception indicates that the content of that string does not represent a valid integer. – SantiBailors Nov 16 '16 at 14:17
  • Will do, thanks. But will this also fix #2 program since I'm trying to reject integer inputs? – Kei Nov 16 '16 at 14:19
  • I don't know, I did not analyze your design requirements, I just focused on the error. – SantiBailors Nov 16 '16 at 14:22
  • #2. Vowel/Consonant - asks the user for a character input and identify if it is a vowel or a consonant. Program should reject integer inputs. The program I made with the codes below doesn't reject integer inputs. I tried searching for answers but I can't find one. – Kei Nov 16 '16 at 14:27
  • 1
    Some suggestions: 1) Rather than checking against A and a, e and E etc, rather use input = input.toUpper() before assigning letter. Now you only need to check against the upper case letters eg A, E, I etc. 2) You cannot just use else and then assume that it is a consonant. The user can input numbers and many other characters. Rather, look into the Character.isLetter() function to determine if the character is in the alphabet. – mdewit Nov 16 '16 at 14:27

1 Answers1

0
  1. Why doesn't the program Odd/Even handle the NumberFormat exception whenever I try to delete the BufferedReader line even though it wasn't used in the whole program?

I am not able to duplicate this problem. I removed the BufferedReader and option #1 works the same as it did before. I entered integer values, special characters, letters, spaces and it works fine.

  1. How can I reject integer inputs for the Vowel/Consonant program?

You could modify your else condition from this:

else {
    JOptionPane.showMessageDialog(null,"Consonant");
}

to this:

else if(Character.isLetter(letter)){
    JOptionPane.showMessageDialog(null,"Consonant");
}
else{
    JOptionPane.showMessageDialog(null,"Error! You must enter a valid letter.");
}

When I exit the program, the console shows this. Exception in thread "main" java.lang.NumberFormatException: null at ...

Regarding the NumberFormatException you're seeing, I'm guessing you're pressing the Cancel button on the dialog. When you press cancel the variable input receives the value null. When you try to parse null as an integer it fails and throws the exception:

Exception in thread "main" java.lang.NumberFormatException: null
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at exception.DoWhileIf.main(DoWhileIf.java:18)

Line 18 is this line: choice = Integer.parseInt(input);

Notice how the exception told us - java.lang.NumberFormatException: null which tells us that the parameter being passed to the parseInt method is null.

Lastly some additional thoughts for you to consider:

Whenever you get input from the user you must account for all the possibilities somehow. For example when you have code like this:

letter = input.charAt(0);

you're not accounting for the possibility that the input could be null or empty in which case this logic will throw an exception.

A concrete example is when the user clicks Cancel on the dialog that asks whether they want to try again:

input = JOptionPane.showInputDialog("Try again? Press Y for yes or N to go back to main menu.");

When the user clicks Cancel on this dialog the same thing happens that I described above regarding the NumberFormatException - input becomes null. If you try to use input like this:

again = input.charAt(0);

it will fail with the exception:

Exception in thread "main" java.lang.NullPointerException

because you can't invoke a method on a null.

Another example is when the user enters nothing at the main menu but simply presses OK. The result is this exception:

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

This happens because input was set to an empty string and parseInt does not know how to convert empty string into an integer value.

Another item I want to bring up is that you're using this same piece of code over and over again. Whenever you have code you want to reuse you should not copy and paste it but instead create a method, object, or other construct so that you can refer to it.

do {
    input = JOptionPane.showInputDialog("Try again? Press Y for yes or N to go back to main menu.");
    again = input.charAt(0);
} while (again != 'Y' && again != 'y' && again !='N' && again !='n');

Breaking up your logic into smaller more manageable pieces will help you to debug, test, and maintain your code more easily.

Another point I want to touch on regarding this same block of logic is that you're using the same kind of dialog to ask for many different kinds of input. Since you're using a GUI dialog, you could use a dialog that is better suited to your task such as one that asks the user to press either a Yes button or No button.

You can learn more about different kinds of dialogs by reading the How to Make Dialogs Tutorial

Here is an example of how you could create a more friendly dialog:

/**
 * Asks the user if they want to try something again and
 * returns a boolean representing the user's response.
 * @return true if the user answers Yes, false otherwise.
 */
private static boolean promptToRepeatSelectedOption(){
    int n = JOptionPane.showOptionDialog(null,
            "Try again?",
            "Repeat Selection",
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE,
            null,
            null,
            null);
    return n == JOptionPane.YES_OPTION;
}

The above method, when invoked, will create and display a dialog with two buttons - Yes and No - and the user will have to select one of them or close the dialog. The logic simply looks for if the user said Yes (by clicking the Yes button) and returns true when that is the case. If the user closes the dialog or chooses the No option the method returns false simply because either of those two scenarios will cause the n == JOptionPane.YES_OPTION comparison to result in a value of false.

You can replace your entire loop with a call to this method like this:

First, define a variable to hold the user's response. boolean repeat = false;

Then invoke the method and set the variable to its result: repeat = promptToRepeatSelectedOption();

Now replace the outer loop condition while (again == 'Y' || again == 'y');

with this: while (repeat);

and finally replace part of the outermost loop condition again == 'N' || again == 'n'

with this: !repeat

One final thought is that you're using very general error messages when the user enters something incorrect or invalid: JOptionPane.showMessageDialog(null, "Error!");

It's always better to explain to the user a little bit about what they did wrong so that they know how to avoid the error next time. You should probably consider adding more detail to your error messages.

Hope this helps!

D.B.
  • 4,523
  • 2
  • 19
  • 39
  • I will keep everything you said in mind. Thank you so much. I'm only a beginner in Java and I only know few things (until looping only). I'm not familiar with most of the things you said but this would really help me. So, thanks! – Kei Nov 17 '16 at 15:16
  • Happy to help. I wasn't sure how much you knew and if you have questions about any of it feel free to e-mail me at the address in my profile. This site isn't really meant to be too conversational. – D.B. Nov 18 '16 at 00:18