Issue
I am trying to learn java while building an android app. I have a points calculator without a button it uses a textchange listener to calculate the total. When backspace key is pressed and the box has null it crashes. I tried validating using the code below (only validated on field to begin with). But it does not work. Any help would be greatly appreciated.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wwcalc);
etFat = (EditText)findViewById(R.id.editTextFat);
etFiber = (EditText)findViewById(R.id.editTextFiber);
etProtein = (EditText)findViewById(R.id.editTextProtein);
etCarbs = (EditText)findViewById(R.id.editTextCarbs);
tvTotal = (TextView)findViewById(R.id.textViewPoints);
TextWatcher watcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if(isEmpty(etFat) == false){
intFat = Integer.parseInt(etFat.getText().toString());
}
else{
etFat.setText("0");
etFat.hasFocus();
return;
}
intProtein = Integer.parseInt(etProtein.getText().toString());
intFiber = Integer.parseInt(etFiber.getText().toString());
intCarbs = Integer.parseInt(etCarbs.getText().toString());
calculate();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
};
etFat.addTextChangedListener(watcher);
etProtein.addTextChangedListener(watcher);
etFiber.addTextChangedListener(watcher);
etCarbs.addTextChangedListener(watcher);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_wwcalc, menu);
return true;
}
public void calculate(){
//intTot = intFat + intCarbs + intFiber + intProtein;
intTot = (int) Math.ceil((intFat * (4/35)) + (intCarbs * (4/36.84)) - (intFiber* (4/50))+ (intProtein * (4/43.75)) ) ;
tvTotal.setText(Integer.toString(intTot));
}
private boolean isEmpty(EditText etText)
{
if(etText.getText().toString().trim().length() > 0 || etText.getText().toString().trim() != null)
return false;
else
return true;
}
}
Thanks for the help all. I got it working not sure if it is the best solution if anyone thinks there is a better way let me know. The try catch as suggested by conor catches the exception, then just insert a 0 set focus and select the 0
try {
intFat = Integer.parseInt(etFat.getText().toString());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
etFat.setText("0");
etFat.hasFocus();
etFat.selectAll();
}
Solution
Without seeing the stacktrace it is hard to know but i'm going to make a stab it anyway.
The following piece of your isEmpty()
function is allowing false to be returned when the box could still be emtpy.
etText.getText().toString().trim() != null
This means that when you press backspace and clear the field it is empty but your function says it's not. Then the kicker, when your app thinks the field is not empty it tried to parse the contents for an integer value (which is not present). This attempt at parsing throws an exception and crashes your app.
I expect the stacktrace to show the app crashing at this line
intFat = Integer.parseInt(etFat.getText().toString());
It's worth noting that you should always surround calls like Integer.parseInt()
with a try, catch block.
Hope that helps.
Answered By - jim
Answer Checked By - Pedro (JavaFixing Volunteer)