0

iv created an android app, what my problem is that when i press the + = - / * buttons before i input a number my app stops working, is there anyway i can make it that if there is no number input it doesnt stop working?


package steven.mcilhone.calculatorcoursework;

import java.math.BigDecimal;


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


public class Calculator extends Activity {

EditText firstValue;
EditText secondValue;
TextView result;
Button addbtn, subtractbtn, dividebtn, multiplybtn, equalbtn, clearbtn;
BigDecimal firstNum, secondNum;



String Operator = "";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_calculator);

    addbtn = (Button) findViewById(R.id.addbtnID);
    subtractbtn = (Button) findViewById(R.id.subtractbtnID);
    dividebtn = (Button) findViewById(R.id.dividebtnID);
    multiplybtn = (Button) findViewById(R.id.multiplybtnID);
    equalbtn = (Button) findViewById(R.id.equalbtnID);
    clearbtn = (Button) findViewById(R.id.clearbtn);
    firstValue = (EditText) findViewById(R.id.edttxt1);
    secondValue = (EditText) findViewById(R.id.edttxt1);


    clearbtn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            EditText edttxt1 = (EditText) findViewById(R.id.edttxt1);
            edttxt1.setText("");
        }
    });



    addbtn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub

            Operator = "+";
            addandclear();
        }
    });

    subtractbtn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            Operator = "-";             
            addandclear();
        }
    });

    dividebtn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            Operator = "/";
            addandclear();

        }
    });

    multiplybtn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            Operator = "*";
            addandclear();
        }
    });

    equalbtn.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            secondNum = new          BigDecimal(secondValue.getText().toString());
            EditText edttxt1 = (EditText) findViewById(R.id.edttxt1);
            edttxt1.setText("");
            if (Operator == "+"){
                edttxt1.setText(firstNum.add(secondNum).toString());
            }
            else if (Operator == "-"){
                edttxt1.setText(firstNum.subtract(secondNum).toString());
            }
            else if (Operator == "/"){
                edttxt1.setText(firstNum.divide(secondNum).toString());
            }   
            else if (Operator == "*"){
                edttxt1.setText(firstNum.multiply(secondNum).toString());
            }   



        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_calculator, menu);
    return true;
}


        public void addandclear(){


            firstNum = new BigDecimal(firstValue.getText().toString());             
            EditText edttxt1 = (EditText) findViewById(R.id.edttxt1);
            edttxt1.setText("");
        }



}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<EditText
    android:id="@+id/edttxt1"
    android:layout_width="250dp"
    android:layout_height="100dp"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:background="?android:attr/editTextBackground"
    android:ems="15"
    android:inputType="numberDecimal" 
    android:gravity="right"/>

<Button
    android:id="@+id/addbtnID"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_below="@+id/edttxt1"
    android:layout_marginLeft="20dp"
    android:text="@string/add" />

<Button
    android:id="@+id/dividebtnID"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_below="@+id/edttxt1"
    android:layout_toRightOf="@+id/addbtnID"
    android:text="@string/divide" />

<Button
    android:id="@+id/multiplybtnID"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_below="@+id/edttxt1"
    android:layout_toRightOf="@+id/dividebtnID"
    android:text="@string/multiply" />

<Button
    android:id="@+id/subtractbtnID"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_alignBaseline="@+id/multiplybtnID"
    android:layout_alignBottom="@+id/multiplybtnID"
    android:layout_toRightOf="@+id/multiplybtnID"
    android:text="@string/subtract" />

<Button
    android:id="@+id/zerobtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_alignLeft="@+id/addbtnID"
    android:layout_alignParentBottom="true"
    android:layout_alignRight="@+id/twobtn"
    android:text="@string/zero" />

<Button
    android:id="@+id/onebtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/zerobtn"
    android:layout_alignLeft="@+id/zerobtn"
    android:text="@string/one" />

<Button
    android:id="@+id/twobtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/zerobtn"
    android:layout_toLeftOf="@+id/multiplybtnID"
    android:text="@string/two" />

<Button
    android:id="@+id/threebtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/zerobtn"
    android:layout_toLeftOf="@+id/subtractbtnID"
    android:text="@string/three" />

<Button
    android:id="@+id/fourbtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/onebtn"
    android:layout_toLeftOf="@+id/twobtn"
    android:text="@string/four" />

<Button
    android:id="@+id/fivebtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_alignBaseline="@+id/fourbtn"
    android:layout_alignBottom="@+id/fourbtn"
    android:layout_toLeftOf="@+id/threebtn"
    android:text="@string/five" />

<Button
    android:id="@+id/sixbtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_alignBaseline="@+id/fivebtn"
    android:layout_alignBottom="@+id/fivebtn"
    android:layout_toRightOf="@+id/fivebtn"
    android:text="@string/six" />

<Button
    android:id="@+id/sevenbtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/fourbtn"
    android:layout_toLeftOf="@+id/fivebtn"
    android:text="@string/seven" />

<Button
    android:id="@+id/eightbtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/fivebtn"
    android:layout_toLeftOf="@+id/sixbtn"
    android:text="@string/eight" />

<Button
    android:id="@+id/ninebtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_alignBaseline="@+id/eightbtn"
    android:layout_alignBottom="@+id/eightbtn"
    android:layout_toRightOf="@+id/eightbtn"
    android:text="@string/nine" />

<Button
    android:id="@+id/equalbtnID"
    android:layout_width="70dp"
    android:layout_height="120dp"
    android:layout_alignBottom="@+id/threebtn"
    android:layout_alignTop="@+id/sixbtn"
    android:layout_toRightOf="@+id/threebtn"
    android:text="@string/equal" />

<Button
    android:id="@+id/clearbtn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:layout_above="@+id/equalbtnID"
    android:layout_alignLeft="@+id/equalbtnID"
    android:text="@string/clear" />

</RelativeLayout>
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
john
  • 65
  • 1
  • 9
  • [This](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) may interest you. – Pshemo Nov 12 '12 at 19:05
  • For future reference: when your app crashes, you should always look at the logcat output of the exception. It provides invaluable information for diagnosing what's wrong. You should also always include the relevant logcat output (if any) in your Android questions to SO. – Ted Hopp Nov 12 '12 at 19:31
  • @Pshemo - Not the problem here. – Ted Hopp Nov 12 '12 at 19:38
  • @TedHopp Yes I've seen your comments and answer (you got +1 from me earlier :). But since OP is using == to compare Strings it is good thing to let him know why equals() is better, right? – Pshemo Nov 12 '12 at 20:00
  • @Pshemo - Fair enough. I misinterpreted the purpose of your comment. – Ted Hopp Nov 12 '12 at 20:21

3 Answers3

6
 if (Operator == "+"){

should be

 if (Operator.eqauls("+")){

Same applies for other if/else blocks in your code.

It is always better to us .equals() instead of == while comparing Strings (except the case of String literals, String literals may pass == condition).

== checks for reference equality. equals() checks for content equality. This discussion may help you.

EDIT:

As TedHopp commented, your code referring to compile time constants, String comparison may not be issue here, still above answers stands as good practice for String comparison.

Because there is no stacktrace available with question, assuming flow satisfies one of the if/else conditions, one other possibility for error is NumberFormatException.

Maek sure the numbers you are reading from EditText are valid Number before creating BigDecimal(String) instance.

Community
  • 1
  • 1
kosa
  • 65,990
  • 13
  • 130
  • 167
  • thanks, but it still crashes if i press + before entering a number, any advice? – john Nov 12 '12 at 19:09
  • Using `==` for comparison is not OP's problem here. As a rule, it's a good idea to use `equals()` instead of `==`. As it happens all string comparisons in this case are with compile-time constants, so all the strings are interned and `==` behaves the same as `equals()`. Besides, this wouldn't cause the app to crash. – Ted Hopp Nov 12 '12 at 19:12
  • @TedHopp: +1, After reviewing question closely I agree with your comment. Updated answer with extra content (which is essentially almost same as your answer). – kosa Nov 12 '12 at 19:19
4

In several places, you are converting the user input to a BigDecimal without doing any error checking. In particular, when there is no input, new BigDecimal(String) will generate a NumberFormatException because "" is not a valid number. From the docs:

The string must contain at least one digit in either the integer or the fraction.

Find every place where you are using the user input and put in some error checking. For instance, in addandclear():

public void addandclear(){
    String val = firstValue.getText().toString();
    try {
        firstNum = new BigDecimal(val);
        EditText edttxt1 = (EditText) findViewById(R.id.edttxt1);
        edttxt1.setText("");
    } catch (NumberFormatException e) {
        if (val.length() == 0) {
            // blank field
        } else {
            // something wrong with the input
        }
    }
}
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • i see thanks, could you explain what is happening above so i know how to do it next time? – john Nov 12 '12 at 19:20
  • @StevenMcilhone - The idea is to first retrieve the text in the input field in a separate step, so it is available for error reporting or whatever. Then the body of the method is enclosed in a try/catch block so that if an exception is raised, it won't crash the program, but instead gives you a chance to report the error in a controlled way. Since you might want to handle blank field errors in a different way than bad input, I showed how you could test for that in the catch block. – Ted Hopp Nov 12 '12 at 19:27
0

To reduce code you could add android:onClick="addandclear" to the buttons in the xml (make addandclear take View v as argument). Then get the operator by v.getText().toString()

Sonja
  • 49
  • 5