views:

393

answers:

4

When running this code:

JTextField ansTxt;
...
ansTxt = new JTextField(5);
String aString = ansTxt.getText();
int aInt = Integer.parseInt(aString);

Why do I get this error?

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""

UPDATE:

JTextField ansTxt;
ansTxt = new JTextField(5);

ansTxt.addKeyListener(new KeyAdapter() {
   public void keyReleased(KeyEvent e) {
    ansTxt = (JTextField) e.getSource();
    String aString = ansTxt.getText().trim();
    int aInt = Integer.parseInt(aString);
   }
}
+1  A: 

You're trying to parse an empty string as an int, which does not work. Which int should "" be parsed as? The JTextField needs to have a text that can be parsed.

ansTxt.addKeyListener(new KeyAdapter() {
    public void keyReleased(KeyEvent e) {
        ansTxt = (JTextField) e.getSource();
        try {
            int aInt = Integer.parseInt(ansTxt.getText());
            //Do whatever you want with the int
        } catch(NumberFormatException nfe) {
            /*
             * handle the case where the textfield 
             * does not contain a number, e.g. show
             * a warning or change the background or 
             * whatever you see fit.
             */
        }
    }
}

It is probably also not a good idea to set ansTxt inside the KeyAdapter. I would suggest you use a local variable for this. That also makes it easier to move the adapter into a "real" class instead of an anonymous one.

Thomas Lötzer
+2  A: 

The integer argument to the JTextField constructor is actually the width in number of columns. From the docs:

public JTextField(int columns)

Constructs a new empty TextField with the specified number of columns. A default model is created and the initial string is set to null.

By constructing it with

ansTxt = new JTextField(5);

you'll basically get an empty text-field (slightly wider than if you constructed it using no-argument constructor). If you want it to contain the string "5" you should write

ansTxt = new JTextField("5");
aioobe
sorry for the confusion..yes, I've set the width as 5 ... I asked the user to type any string on the JTextField and not specifically 5...I've tried trim() but it doesn't work.
Jessy
@Jessy In your code in the question the user has no chance to do anything, since the JTextField is created and immediately parsed. Is this an error in the code above or also in your application?
Thomas Lötzer
@Jessy I'm not sure what you mean, but that's not what the code you posted does. It creates a new text field, retrieves the text it contains (which is an empty string by default), and tries to convert it to an integer. `getText` doesn't prompt the user for text, it just pulls the current text from the text field
Michael Mrozek
ansTxt = (JTextField) e.getSource();String aString = ansTxt.getText().trim();int aInt = Integer.parseInt(aString);
Jessy
You need to (update the question OR create a new question) AND (give more context). Where does `e` come from?
aioobe
My guess is that your `e` is generated from an event that is fired before the user even gets a chance to type (for instance an event that is fired upon focus). In either case, you should add a try { .. } catch (NumberFormatException nfe) { .. } in case the user writes anything else than an integer.
aioobe
Sorry again...I've updated the code.
Jessy
A: 

Try introducing the Apache's "commons Lang" library into your project and for your last line you can do

int aInt = 0;
if(StringUtils.isNotBlank(aString) && StringUtils.isNumeric(aString) ){
    aInt = Integer.parseInt(aString);
}

edit: Not sure why the downvote. The JtextField will take any string. If the text field is listening on each key press, every non-numeric value (including blank) that is entered will generate the NumberFormatException. Best to check if it is Numeric before doing anything with the new value.

edit2: As per Thomas' comments below. I ran a test to compare the try/catch vs the StringUtils way of solving this issue. The test was ran 5million times for each. The average time for the try/catch was 21 seconds. The average time for the StringUtils was 8 seconds. So using StringUtils for heavy load is considerably faster. If the load on the code is small you will notice little to no difference. The test ran was

try{
   result = Integer.parseInt(num);
}catch(NumberFormatException ex){
   result = -1;
}

vs

if(StringUtils.isNotBlank(num) && StringUtils.isNumeric(num)){
   result = Integer.parseInt(num);
}else{
   result = -1;
}

each loop through generated a new random string of 10 digits to avoid any optimization in the loops on the if statement. This added 6-7 seconds of overhead.

Sean
@gameaddict You're proposing an additional library without giving a reason why it should be used. Why is this better than just to try to parse it and handle the exception?
Thomas Lötzer
@Thomas There is overhead to catch an exception. There is also overhead in performing the isNumeric() check in StringUtils. So it comes down to maintainability. I prefer not to catch every exception that could possibly be thrown and check my types before parsing to avoid the exception, others may not. It comes down to preference.
Sean
@gameaddict This is in an interactive GUI, responding to key presses. The overhead of catching the exception in your test was 0,0000026 seconds per key pressed. I don't think the user will notice a response time difference of 0,0026 milliseconds
Thomas Lötzer
Yeah, for small applications the difference between either of our methods is very small. I have always heard that there was overhead in using catch statements but never knew how much it was. I used this problem as an exercise to find out for myself. For this question the difference will be very insignificant, but in a larger more time sensitive application the analysis above could help.
Sean
A: 

Your KeyAdapter will be run before your ansText will process the KeyEvent. In fact, you may e.consume() to prevent ansText from processing it at all. So the first time a key is pressed and released, ansText.getText() will still be "". That's why you get the exception first time. Pressing a numerical key twice, should work the second time.

Ishtar