views:

73

answers:

4

I'm trying to learn something about GUI, using NetBeans6.8, starting with the GUI section in The java tutorial.

There is a simple exercise for a Celsius-Fahrenheit converter. I want that to have two TextFields, one for Celsius and one for Fahrenheit temperature; if the user types in the celsius text field he got the result "printed" in the fahrenheit text filed. and vice versa.

So, i put on both the textfields one KeyTyped event, here's the code:

private void celsiusTextKeyTyped(java.awt.event.KeyEvent evt) {                                
    int cels = Integer.parseInt(celsiusText.getText());
    int fahr = (int)(cels * 1.8 + 32);
    fahrText.setText(fahr + ""); 
}                                    

private void fahrTextKeyTyped(java.awt.event.KeyEvent evt) {                                
    int fahr = Integer.parseInt(fahrText.getText());
    int cels = (int)(fahr / 1.8 - 32);
    celsiusText.setText(cels + ""); 
}

It doesn't work. If i type something in a textfield i got this exception: java.lang.NumberFormatException: For input string: ""

The code that attach the listeners:

celsiusText.addKeyListener(new java.awt.event.KeyAdapter() {
    public void keyTyped(java.awt.event.KeyEvent evt) {
        celsiusTextKeyTyped(evt);
    }
});

fahrText.addKeyListener(new java.awt.event.KeyAdapter() {
    public void keyTyped(java.awt.event.KeyEvent evt) {
        fahrTextKeyTyped(evt);
    }
});

[However, i can't modify it, it's autogenerated.]

+1  A: 

Method .getText() returns a string not a number, if that string contains non-numeric characters (i.e. a letter, a space, nothing at all) then parseInt will throw a NumberFormatException. Since your using KeyEvent, as soon as you press say "7", the event is fired before 7 is entered into the text box. Thus the text box still only contains "", which is where the error comes from. You may wish to also listen to the keyUp event instead.

You need to enclose your code in a try catch block.

private void fahrTextKeyTyped(java.awt.event.KeyEvent evt)
{   
    try
    {                             
        int fahr = Integer.parseInt(fahrText.getText());
        int cels = (int)(fahr / 1.8 - 32);
        celsiusText.setText(cels + "");
    }
    catch(NumberFormatException ex)
    {
        //Error handling code here, i.e. informative message to the user
    }
}

An alternative is you could filter out non-numbers on keydown event, see example here - http://www.javacoffeebreak.com/java107/java107.html (Creating a custom component - NumberTextField)

JonWillis
Integer.parseInt() takes a String and returns an int... Did you mean if it does not get a "numerical String"?
antonyt
I'll strongly recomend to use NumberFormatException instead of global Exception, and print the stack trace also. Nevertheless this do not solve the problem only hides him.
Vash
@Vash, Can't agree more, was just popping in a quick solution. I have edited the solution to match ;)@antonyt, "3" = 3, "63" = 63, "0" = 0, "a" = ERROR, "" = ERROR.
JonWillis
I'm saying your answer is misleading because you are suggesting that the getText() method can return something other than a String. "3" is still a String.
antonyt
@antonyt, what you have said has finally clicked with me, i will ammend my answer.
JonWillis
A: 

You probably set action to keyDown, this mean that even occur before the key value is "added" to textbox, while You retrieve the value from it is still empty "".

Vash
+1  A: 

I suspect that what's happened is that you added these handlers with something like celsiusText.addKeyListener, yes?

The thing is, that'll give you not just the KEY_TYPED events you wanted, but also KEY_DOWN and KEY_UP. The KEY_DOWN event will happen before the text is really entered into the field, so your code firing on that will see the field as blank still. Trying to convert the empty string to a number gives you a format exception.

The easiest way to fix this is the try/catch construct other people have been posting.

Daniel Martin
A: 

There is a simple exercise for a Celsius-Fahrenheit converter

That is a really old example. The better approach is to use a DocumentListener, not a KeyListener.

camickr