rishi rishi - 1 month ago 10
Java Question

Calculator with single edittext field

I am new to android development and I am trying to develop a calculator with single edit text field. It's not showing any compiler error but it crashes as soon as I press any button. I'm first taking the input for num1 and clearing the edit text field followed by a switch case to detect the operation and collecting the data of the second number.

public class MainActivity extends Activity implements OnClickListener{

EditText ino;

Button btnadd;
Button btnsub;
Button btnmult;
Button btndiv;
Button btneq;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ino=(EditText) findViewById(R.id.ino);

btnadd=(Button) findViewById(R.id.add);
btndiv=(Button) findViewById(R.id.div);
btnsub=(Button) findViewById(R.id.sub);
btnmult=(Button) findViewById(R.id.mult);
btneq=(Button) findViewById(R.id.eq);

btnadd.setOnClickListener((OnClickListener) this);
btnsub.setOnClickListener(this);
btnmult.setOnClickListener(this);
btndiv.setOnClickListener(this);

}

@Override
public void onClick(View v)
{

float num1=0,num2=0,res=0;
String xyz="",ans;
num1=Float.parseFloat(ino.getText().toString());

ino.setText(xyz);
switch(v.getId())
{
case R.id.add:

num2=Float.parseFloat(ino.getText().toString());

res=num2+num1;

ans=Float.toString(res);

break;
case R.id.div:
num2=Float.parseFloat(ino.getText().toString());
ino.setText(xyz);
res=num1/num2;

ans=Float.toString(res);
ino.setText(ans);
break;
case R.id.mult:
num2=Float.parseFloat(ino.getText().toString());
ino.setText(xyz);
res=num2*num1;

ans=Float.toString(res);
ino.setText(ans);
break;
case R.id.sub:
num2=Float.parseFloat(ino.getText().toString());
ino.setText(xyz);
res=num1-num2;

ans=Float.toString(res);
ino.setText(ans);
break;
case R.id.eq:
ans=Float.toString(res);
ino.setText(ans);
break;
default: break;
}



}
}


Here is the copy of stack trace.

12-28 00:49:52.646 2125-2125/com.example.rishabh.calculator2
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rishabh.calculator2, PID: 2125
java.lang.NumberFormatException: Invalid float: ""
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseFloat(StringToReal.java:308)
at java.lang.Float.parseFloat(Float.java:306)
at com.example.rishabh.calculator2.MainActivity.onClick(MainActivity.java:56)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Answer

Your code contains several problems. The first is that Float.parseFloat() will throw a java.lang.NumberFormatException if the string is empty or contains letters. This should be handled with try/catch.

The second problem is that the variables num1, num2 and res cannot be declared locally, because they will be initialized to 0.0 every time a button is clicked.

For the calculator to work it is necessary to remember the operation that is going to be performed when the user clicks the "equals"-button. The previous clicked button can be stored using an int.

The following code is tested and works.

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.view.View.*;
import android.view.View;

public class MainActivity extends Activity implements OnClickListener {

    EditText ino;

    Button btnadd;
    Button btnsub;
    Button btnmult;
    Button btndiv;
    Button btneq;

    private float num1 = 0;
    private float num2 = 0;
    private float res = 0;

    private int operation = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ino=(EditText) findViewById(R.id.ino);

        btnadd=(Button) findViewById(R.id.add);
        btndiv=(Button) findViewById(R.id.div);
        btnsub=(Button) findViewById(R.id.sub);
        btnmult=(Button) findViewById(R.id.mult);
        btneq=(Button) findViewById(R.id.eq);

        btnadd.setOnClickListener(this);
        btnsub.setOnClickListener(this);
        btnmult.setOnClickListener(this);
        btndiv.setOnClickListener(this);
        btneq.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        String s = ino.getText().toString();
        try
        {
            Float.parseFloat(s);
        }
        catch (NumberFormatException e)
        {
            s = "0.0";
        }

        String xyz="",ans;
        ino.setText(xyz);

        switch(v.getId())
        {
            case R.id.eq:
                num1=Float.parseFloat(s);

                switch (operation) {
                    case R.id.add:
                        res = num2 + num1;
                        break;
                    case R.id.sub:
                        res = num2 - num1;
                        break;
                    case R.id.mult:
                        res = num2 * num1;
                        break;
                    case R.id.div:
                        res = num2 / num1;
                        break;
                    default:
                        res = 0;
                        break;
                }
                ans=Float.toString(res);
                ino.setText(ans);
                break;
        }
        num2 = Float.parseFloat(s);
        operation = v.getId();
    }
}