I am trying to create a calculator app.IN order to avoid duplication of operators i am checking if the previous character in the string is an operator.But i am getting stringindexoutofboundsexception when i type in the third character.
package com.example.calculatorproject;
import android.app.Activity;
import android.os.Bundle;
import android.text.InputType;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
public class MainActivity extends Activity {
EditText txtresult;
ImageButton ib_backspace;
String result="";
char value;
Button btnc,btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn0,btn_add,btn_sub,btn_multi,btn_divide,btn_decimal,btn_equal;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtresult=(EditText) findViewById(R.id.txtresult);
ib_backspace=(ImageButton) findViewById(R.id.ib_backspace);
txtresult.setInputType(InputType.TYPE_NULL);
btnc=(Button) findViewById(R.id.btnC);
btn1=(Button) findViewById(R.id.btn1);
btn2=(Button) findViewById(R.id.btn2);
btn3=(Button) findViewById(R.id.btn3);
btn4=(Button) findViewById(R.id.btn4);
btn5=(Button) findViewById(R.id.btn5);
btn6=(Button) findViewById(R.id.btn6);
btn7=(Button) findViewById(R.id.btn7);
btn8=(Button) findViewById(R.id.btn8);
btn9=(Button) findViewById(R.id.btn9);
btn0=(Button) findViewById(R.id.btn0);
btn_add=(Button) findViewById(R.id.btn_add);
btn_sub=(Button) findViewById(R.id.btn_sub);
btn_multi=(Button) findViewById(R.id.btn_multi);
btn_divide=(Button) findViewById(R.id.btn_divide);
btn_decimal=(Button) findViewById(R.id.btn_decimal);
btn_equal=(Button) findViewById(R.id.btn_equal);
ib_backspace.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result=txtresult.getText().toString();
if(result.length()!=0)
{
result = result.substring(0, result.length()-1);
setresult();
}
}
});
btnc.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
result="";
setresult();
}
});
btn0.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="0";
setresult();
}
});
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="1";
setresult();
}
});
btn2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="2";
setresult();
}
});
btn3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="3";
setresult();
}
});
btn4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="4";
setresult();
}
});
btn5.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="5";
setresult();
}
});
btn6.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="6";
setresult();
}
});
btn7.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="7";
setresult();
}
});
btn8.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="8";
setresult();
}
});
btn9.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+="9";
setresult();
}
});
btn_add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
value=result.substring(result.length()-1).charAt(result.length()-1);
if((value=='+')||(value=='-')||(value=='*')||(value=='/')||(value=='.'))
{
result=(result.substring(0,result.length()-1))+"+";
setresult();
}
else
{
result+="+";
setresult();
}
}
});
btn_sub.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
value=result.substring(result.length()-1).charAt(result.length()-1);
if((value=='+')||(value=='-')||(value=='*')||(value=='/')||(value=='.'))
{
result=result.substring(0,result.length()-1)+"-";
setresult();
}
else
{
result+="-";
setresult();
}
}
});
btn_divide.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
value=result.substring(result.length()-1).charAt(result.length()-1);
if((value=='+')||(value=='-')||(value=='*')||(value=='/')||(value=='.'))
{
result=result.substring(0,result.length()-1)+"/";
setresult();
}
else
{
result+="/";
setresult();
}
}
});
btn_multi.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
value=result.substring(result.length()-1).charAt(result.length()-1);
if((value=='+')||(value=='-')||(value=='*')||(value=='/')||(value=='.'))
{
result=result.substring(0,result.length()-1)+"*";
setresult();
}
else
{
result+="*";
setresult();
}
}
});
btn_decimal.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
result+=".";
setresult();
}
});
btn_equal.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
public void setresult()
{
txtresult.setText(result);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
For eg if i type "9+5-*" as the expression the * should replace the - sign.But even when i type 9+5 there is a stringoutofboundsexception when i type +.Please help!!
The logcat
05-15 06:03:50.317: E/AndroidRuntime(1492): FATAL EXCEPTION: main
05-15 06:03:50.317: E/AndroidRuntime(1492): Process: com.example.calculatorproject, PID: 1492
05-15 06:03:50.317: E/AndroidRuntime(1492): java.lang.StringIndexOutOfBoundsException: length=1; index=2
05-15 06:03:50.317: E/AndroidRuntime(1492): at com.example.calculatorproject.MainActivity$14.onClick(MainActivity.java:175)
05-15 06:03:50.317: E/AndroidRuntime(1492): at android.view.View.performClick(View.java:4424)
05-15 06:03:50.317: E/AndroidRuntime(1492): at android.view.View$PerformClick.run(View.java:18383)
05-15 06:03:50.317: E/AndroidRuntime(1492): at android.os.Handler.handleCallback(Handler.java:733)
05-15 06:03:50.317: E/AndroidRuntime(1492): at android.os.Handler.dispatchMessage(Handler.java:95)
05-15 06:03:50.317: E/AndroidRuntime(1492): at android.os.Looper.loop(Looper.java:137)
05-15 06:03:50.317: E/AndroidRuntime(1492): at android.app.ActivityThread.main(ActivityThread.java:4998)
05-15 06:03:50.317: E/AndroidRuntime(1492): at java.lang.reflect.Method.invokeNative(Native Method)
05-15 06:03:50.317: E/AndroidRuntime(1492): at java.lang.reflect.Method.invoke(Method.java:515)
05-15 06:03:50.317: E/AndroidRuntime(1492): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
05-15 06:03:50.317: E/AndroidRuntime(1492): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
05-15 06:03:50.317: E/AndroidRuntime(1492): at dalvik.system.NativeStart.main(Native Method)
This line is broken for any string with a length other than 1:
value = result.substring(result.length()-1).charAt(result.length()-1);
Consider different lengths:
result
is an empty string): result.substring(result.length() - 1)
will fail as you're calling result.substring(-1)
. Bang.result
is a single-character string): result.substring(0)
returns a one-character string (equivalent to result)
and then charAt(0)
returns that single characterresult.substring(result.length() - 1)
returns a one-character string, and then you're calling charAt
with a value more than 0. Bang.If you're just trying to find the last character of the string, you want:
value = result.charAt(result.length() - 1);
There's no need for a substring
call.
I'd also strongly urge you to consider using more local variables and fewer instance variables. Why is value
an instance variable for example? Why is result
an instance variable when you basically want to manipulate the text box contents?
See more on this question at Stackoverflow