Null pointer exception when JOptionPane.showMessageDialog is cancelled - java

Despite efforts reading on how Null Pointer Exceptions are generated, I literally have no clue how this error is generating itself within my code.
I don't think this affects my code directly, as I could just catch the exception, but before I do that, I'd still like to learn more about the error.
Part of my code where the error is generating, I am opening a new Input dialog and waiting for the user's input. If the user cancels the input dialog, it's just meant to close the dialog, in which it does. However, it's giving me an error every time I cancel.
Here's the code:
String newInput = JOptionPane.showInputDialog(null, "Your current holdings are: "
+ cable.getHoldings(), "Edit Holdings", JOptionPane.CANCEL_OPTION);
if (newInput.isEmpty())
{
//Error generated here
JOptionPane.showMessageDialog(null, "Please enter in a number!");
}
else
{...}
The message dialog is only triggered if the user presses the 'OK' button on the input dialog. Otherwise, if a user cancels or exits the input dialog, a null pointer exception error is generated.
Does anyone mind helping me and letting me know why this is happening?
Thank you.

From docs
Returns: user's input, or null meaning the user canceled the input
so it retruns null if user cancel the dialog
From showInputDialog source code
if (value == UNINITIALIZED_VALUE) {
return null;
}
Solutions : put a nullity check before doing anything
if (newInput==null || newInput.isEmpty())
you don't need newInput.isEmpty() because it checks the length of a string so even user enters a space length will be 1 or length will be null in case of cancelled input so nullity check is only enough for checking some input.
Improvement : you can use regex to validate your input, is digit or not ,like this
if (newInput==null || !newInput.matches("\\d+"))
{
JOptionPane.showMessageDialog(null, "Please enter in a number!");
}
\\d+ check the input should contain at-least one or more integer digits.

The issue what I understood is that you are checking the isEmpty() method on a null (newInput) value which will throw the null pointer exception. You should check this below:
Instead of this:
if (newInput.isEmpty())
{
//Error generated here
JOptionPane.showMessageDialog(null, "Please enter in a number!");
}
Do this :
if (newInput == null)
{
//Error generated here
JOptionPane.showMessageDialog(null, "Please enter in a number!");
}
This should work fine. Hope this helps...!!!

Related

Continuously ask for a user input

I have two available options for a user to input, and what I am trying to accomplish is if the user does not enter either of the inputs the program will continuously ask them again until they enter a valid one. Here is the code right now
String userLIB = user_input.next();
if (userLIB.contentEquals(UBC.acro)){
printDetails(UBC);
} else {
if (userLIB.contentEquals(ORL.acro)){
printDetails(ORL);
} else {
while (!userLIB.contentEquals(UBC.acro) || !userLIB.contentEquals(ORL.acro)){
System.out.println("Invalid input");
break;
}
}
}
I have a break to keep the code from looping the "Invalid input" indefinetly but it just ends the program right now which isn't what I want to happen. Is there a way to make the program go back to the start of the if statement?
You're breaking your code when the Invalid input condition is met.
Do as following,
String userLIB = "";
do {
userLIB = user_input.next();
if (userLIB.contentEquals(UBC.acro)){
printDetails(UBC);
} else if (userLIB.contentEquals(ORL.acro)) {
printDetails(ORL);
} else {
System.out.println("Invalid input. Try again!");
}
} while (!userLIB.contentEquals(UBC.acro) || !userLIB.contentEquals(ORL.acro));
This, tries to get the only 2 possible inputs and terminate the loop.
Else will loop again and again, until the required input is provided.
I figured it out with the help of #Carcigenicate, I put a while loop outside of the whole code and then put a userLIB = user_input.next(); inside of the incorrect if statement. Also thanks to #Sridhar for giving an answer that also works

How to retry input after an InputMismatchException?

I am creating a program that takes input from the user.Now I want to re-run the input option if a user enters an invalid command. Like here only integer input are preferred but if the user inputs text, then I want to catch the exception and rerun the method.
I have tried this but it turns me into an infinite loop.What would be the best way to achieve this. It would be great if someone helps me on this.
boolean retry = true;
while(retry){
try{
//considering response from the user
System.out.print("\nEnter Your Command : ");
f_continue = processresponse(scanner.nextInt());
retry = false;
}catch(InputMismatchException e){
System.err.println("\nPlease Input a Valid Command from 1-5 or 0 for Exit");
}
}
If you enter something other than an integer, nextInt() will throw an exception, and what was entered will still be in the input buffer, so the next time you call nextInt(), you will read the same bad input. You should first call hasNextInt() to see if the input is an integer; if not, just call nextLine() to skip the bad input (and write a message telling the user to re-try).
Or you can just call scanner.nextLine() in the catch block.

Keep on prompting user after invalid input

Now I know that there is a thread called "Validating input using java.util.Scanner". I already looked there and that thread only answered 1/2 of my problems. The other half is when someone enters a number greater than 2 I get Array Index Out of Bounds Exception. I just need help on if someone enters a 3 for either row or column, the console should prompt something like this:
"Enter the coordinates to place an 'X'. Row then Column."
//enters 3 and 3
"Please enter a valid input"
It would keep and asking the user for a valid number until he gives one.
Would I need to do something like the !keyboard.hasNextInt() but for integers? And that would run smoothly with the rest of my code?
You could use a do-while loop. Something like
do {
//prompt
//input
} while (input not valid);
Where prompt and input should be replaced by code to prompt the user and accept input. In the while section, check if input is valid.
You're question isn't too clear but I'll try to make sense of it.
I'm assuming you've named your scanner "keyboard"
Before I try running this code, the first problem I can see is this (Note that I grabbed this from your code before you edited the question):
while (board[row][col] != ' ')
{
System.out.println("Already occupied space");
System.out.println("Choose again");
row = keyboard.nextInt();
col = keyboard.nextInt();
}
Earlier, you made sure that the user enters integers. However, you have abandoned that completely in this case.
Assuming you're trying to avoid an error if the user enters something other than an integer, this is what I would do:
while(true){
boolean valid = true;
if(!keyboard.hasNextInt()){
valid = false;
keyboard.next();
}
else{
row = keyboard.nextInt();
}
if(!keyboard.hasNextInt()){
valid = false;
keyboard.next();
}
else{
col = keyboard.nextInt();
}
if (valid && (row > 2 || col > 2)){
System.out.println("Please enter a valid input");
continue;
}
else if(!valid){
System.out.println("Please enter a valid input");
continue;
}
else
break;
}
There are a couple reasons this code might seem a bit long. First off, we're trying to test if the input is an integer before we attempt to store it as an int. Secondly, we want to compare the input after we store it successfully to see if it's less than 3. If the input isn't an integer, the boolean "valid" will be false. The way a compiler works, if valid is false in the if statement it will ignore anything to the right of the &&, avoiding an error.
I admit, this is using some commands that I haven't learned before, so this might not be the most efficient way. But you get the idea :)
P.S. You should probably throw the above code into a method.

Null String for Scanner

I have a problem over my application. I want the app to detect that if the user does not input any value for the string (in other words, just press enter after being asked to input something), the app then asks whether he/she wishes to quit the program or not.
Am I doing it right?
words = s.nextLine();
if (words.equals(null)) {
No, you're not doing it right.
nextLine() will return an empty string if the user just hits return. As far as I can tell it will never return null. If the end of the input has been reached, it will throw NoSuchElementException (unlike BufferedReader.readLine() which will return null in that case). So you want:
if (words.equals(""))
or
if (words.length() == 0)
or
if (words.isEmpty())
... and use hasNextLine() if you want to detect the end of input first.
No, you're not.
If the user simply presses enter, you'll get an empty string, not null. This can be checked as
if(words.equals(""))
If there are whitespaces, this would fail. In that case
if(words.trim().equals(""))
should work.
null is not correct, because what you get is an empty String:
use:
words.isEmpty()
or
words.equals("")
or
words.length()==0
This should work:
if (words == null || words.length() == 0) {
the returned string isnt null, its just an empty string.
words.equals("");
should be correct

does not loop and display the error message

Ok, I have this code that asks an input for a username and a password. I used JOptionPane. What I want with the program is to display an error message if the the input on the username field has a number, and goes back to the previous dialog box asking for the username again. I have this while loop yet it does not function the way it should. Please do help. The program does not show the error message on my catch method and neither does it loop for the dialog box to display.
public class SwingExercise {
public static void main(String[] args) {
String name = "";
String pw = "";
boolean input = true;
boolean hasDigit = false;
while (input) {
try {
while (name.equals("")) {
name = JOptionPane.showInputDialog(null, "Enter username:");
if (name.equals("")) {
JOptionPane.showMessageDialog(
null, "No input.", "Error", JOptionPane.ERROR_MESSAGE);
name = "";
}
while (hasDigit) {
for (int i = 0; i < name.length(); i++) {
if (Character.isDigit(name.charAt(i))) {
throw new InputMismatchException();
}
}
hasDigit = false;
}
}
input = false;
while (pw.equals("")) {
pw = JOptionPane.showInputDialog(null, "Enter password:");
if (pw.equals("")) {
JOptionPane.showMessageDialog(
null, "No input.", "Error", JOptionPane.ERROR_MESSAGE);
pw = "";
}
}
} catch (NullPointerException e) {
System.exit(0);
} catch (InputMismatchException e) {
JOptionPane.showMessageDialog(
null, "Invalid input.", "Error", JOptionPane.INFORMATION_MESSAGE);
}
}
}
Please do mention any comments regarding the other lines in my code and if there are any unnecessary lines. Thank you in advance :)
There seems to be absolutley no way to get into the while(hasDigit) loop because you have it set to false, and there is nothing setting it to true.
One problem is that the value of hasDigit will always remain false. You probably will want to define hasDigit as true initially.
boolean hasDigit = true;
Some comments on style, since you asked:
In general, you want your try() blocks to be as short as possible, so it's clear which lines you're expecting to throw an exception. Otherwise you may unexpectedly catch an exception from a line that you didn't think could generate it, and then handle it incorrectly. This means the code will probably be longer, but it's far more important that it be easier to maintain and debug.
When it's legitimate for a string to be null, it's common to write if ("".equals(name)) rather than if (name.equals("")). Since the hard-coded empty string can never be null, you needn't surround the code with a try/catch block.
There's no need to set name or pw to the empty string inside an if() that tests to see if they're empty.
You probably don't want to echo the password. See JOptionPane to get password.
The code explicitly forbids digits in the name but accepts every other character, including punctuation and special characters. It's generally good programming practice to use a whitelist of acceptable input, rather than a blacklist of forbidden input. That way you'll never be surprised by invalid data that's unexpectedly accepted.
The outermost while() loop will exit if the password is invalid, since input only depends on the name. Better to set input to false at the top of the loop, then set it to true if either input is invalid.
Since the name and pw blocks are almost identical (they prompt for a non-empty string), consider extracting them into a helper function. You'll want to pass parameters that specify the prompt and whether or not to echo the input back to the user.

Categories

Resources