I made a calculator on android. I get results for only two numbers (1+1), but I would like to be able to do more then one calculation at a time instead of hitting enter every time I need a new answer (1+1-2).
Something like this: 2 + 2 (new operator pressed) 4 + 3 (equals is pressed) 7
But I'm not sure how to implement this on my code.
This is the button code for every operator:
btnPlus.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
perform();
operation = "+";
}
}); // end btnPlus
This is my calculation method:
private void calculate() {
if (operation == null) {
numberInput.setText(null);
} else if (operation.equals("+")){
numResult = (secondNum + firstNum);
numberInput.setText(String.valueOf(numResult));
} else if (operation.equals("-")) {
numResult = (secondNum - firstNum);
numberInput.setText(String.valueOf(numResult));
} else if (operation.equals("/")) {
numResult = (secondNum / firstNum);
numberInput.setText(String.valueOf(numResult));
} else if (operation.equals("*")) {
numResult = (secondNum * firstNum);
numberInput.setText(String.valueOf(numResult));
} // end if statement
}
Also, perform if needed:
private void perform() {
str = "";
secondNum = firstNum;
}
A quick way to solve your problem given your current code is to use textChangeListener/TextWatcher(assuming you have an EditText or TextView) to detect every time an operator is entered then call the operate function. It would look something like this.
myEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
// if 2nd operator is detected
// call calculate
// append 2nd operator
}
});
You could do as i suggested in the comment, and just make a list for every operation, and then calculate it every time the current data changes (there may be difffrent ways to "know" if some of the result is final depending on how you can delete from the app.
SOmething like this is what i would do, and then just everytime a button is pressed call the logic for adding the input, and then calculate it and write it out
public class Calc {
private List<String> inputs = new ArrayList<>();
public String calculate(List<String> input){
String result = "";
for(String current : input){
switch (current) {
case "(":
// do stuff
case "+":
//do stuff
default:
// do stuff
}
}
return result;
}
btnPlus.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// add to list, and call calculate
}
}); // end btnPlus
}
Related
I'm creating a Java calculator (only buttons - like T9 keys) in an Android XML Application, and I want to fix the "Cancel" button.
When I click it, I want to cancel the last digit from a String that contains only numbers (or '.', because you can also add '.' to write decimal numbers).
There is a problem: if the user writes an int number (34) and I convert it to double, it becomes 34.0 and, if I cancel the last digit, it cancels the 0.
I also tried with String.substring(start,end), but it doesn't work...
Have you got any suggestions about the cancel handle? Thank you!
This is the function that cancels the last digit.
/* tv -> TextView
- tvResult contains what the user writes and the result when he clicks "=", - tvCalc contains the calc that the user is entering.
For example, if the user writes with the 0-9 buttons and the operator of the operations, in tvCalc there will be "34+50=", and in tvResult "84" */
public void handleCancel(View v) {
//tv -> TextView, tvResult contains what the user writes and the result when he clicks "=", tvCalc contains the calc that the user is entering: for example if user writes with the 0-9 buttons and the operator of the operations, in tvCalc there will be "34+50=", and in tvResult "84"
if (tvResult.length() == 0) {
errorToast = Toast.makeText(MainActivity.this, "Error! There's nothing to cancel!", Toast.LENGTH_LONG);
errorToast.show();
} else {
tvResult.setText(tvResult.toString().substring(0, tvResult.toString().length() - 1))
if (tvCalc.toString().contains("=")) {
tvCalc.setText(tvResult.toString());
operand1 = tvResult.toString();
} else {
tvCalc.setText(tvCalc.toString().substring(0, tvCalc.toString().length() - 1));
if (operator == "") operand1 = tvResult.toString();
else {
operand2 = tvResult.toString();
try {
int conv = Integer.parseInt(tvCalcolo.toString());
operazione = "";
} catch(Exception e) {}
}
}
}
}
The function that adds the choice of the user:
public void userChoice(View v)
{
Button clicked=(Button)findViewById(v.getId());
String choice=clicked.getText().toString();
try
{
int number=Integer.parseInt(choice);
if (operator=="")
{
operand1+=choice;
if (tvCalc.toString().contains("=")) tvCalc.setText(operand1);
} else operand2+=choice;
} catch (Exception e)
{
if (choice.equals('.'))
{
if (operator=="") operand1+=choice;
else operand2+=choice;
} else
{
if (operand2!="")
{
handleEqual(v);
operand1=tvResult.toString();
}
operator=choice;
tvCalc.append(operator);
tvResult.setText("");
return;
}
}
tvCalc.append(choice);
tvResult.append(choice);
}
I edited the function "handleCancel" thanks to Cardinal System:
public void handleCancel (View v)
{
double d;
try
{
d=Double.parseDouble(tvRisultato.toString());
} catch (Exception e)
{
bCanc.setText("Error"); //It's the button 'Cancel'
}
String newVal;
if (d%1==0)
{
int val=(int)d;
newVal=String.valueOf(val);
newVal=newVal.substring(0,newVal.length()-1);
} else
{
newVal=String.valueOf(d);
newVal=newVal.substring(0,newVal.length()-1);
if (newVal.endsWith("."))
{
newVal=newVal.substring(0,newVal.length()-1);
}
}
tvResult.setText(newVal);
if ((tvCalc.toString().contains("+")||tvCalc.toString().contains("-")||tvCalc.toString().contains("*")||tvCalc.toString().contains("/")||tvCalc.toString().contains("^"))&&tvCalc.toString().contains("="))
{
tvCalc.setText(tvResult.toString());
operand1=tvResult.toString();
} else if ((tvCalc.toString().contains("+")||tvCalc.toString().contains("-")||tvCalc.toString().contains("*")||tvCalc.toString().contains("/")||tvCalc.toString().contains("^"))&&!tvCalc.toString().contains("="))
{
if (tvCalc.toString().endsWith("+")||tvCalc.toString().endsWith("-")||tvCalc.toString().endsWith("*")||tvCalc.toString().endsWith("/")||tvCalc.toString().endsWith("^")) operator="";
tvCalc.setText(tvCalc.toString().substring(0,tvCalc.toString().length()-1));
}
}
See if this helps you:
// Let's make it a double so we have something to work with.
double d = Double.parseDouble(tvResult.getText().toString());
String newText;
if (d % 1 == 0) { // See if the number is a whole number
int i = (int) d; // If it is, cast it to an int to get rid of the decimal
newText = String.valueOf(i); // Parse it to a string so we can clip off the end
newText = newText.substring(0, newText.length() - 1); // Clip off the end
} else {
// If it's not a whole number, just parse it to a string.
newText = String.valueOf(d);
newText = newText.substring(0, newText.length() - 1); // Clip off the end
if (newText.endsWith(".")) {
// If the number we clipped off was a tenth, clip off the decimal
newText = newText.substring(0, newText.length() - 1);
}
}
tvResult.setText(newText);
Looks like you could fulfill your requirements at least in two ways:
pattern searching symbols to be removed (something like (.0|\d|+|-|*|/) ) - would not recommend
remembering last input string before new digit/operation is added. F.e. on button . pressed you would remember your current input to calculator to variable and in case you need to cancel, you simply set current input line to that variable
Hope my suggestions were helpfull.
I have to add add recursion inside ActionListener to calculate fibonacci sequence of a given number, i've tried to add recursion in this way, but it didn't work.
fibonacci.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
int a = Integer.parseInt(input1.getText());
if(a == 0)
result.setText(String.valueOf("0"));
else if(a == 1)
result.setText(String.valueOf("1"));
else
result.setText(String.valueOf(fibonacci(a - 1) + fibonacci(a - 2)));
} catch (Exception f) {
JOptionPane.showMessageDialog(rootPane, "ERROR: " + (f.getMessage()));
}
String aField = input1.getText();
if (e.getSource() == fibonacci) {
if ("".equals(aField)) {
String emptyFieldWarning;
emptyFieldWarning = "One or more fields is/are empty!";
JOptionPane.showMessageDialog(rootPane, emptyFieldWarning);
}
}
}
});
The recursion should happen within it's own method, the ActionListener should stand as the initiation of that recursion.
Something along the lines of
fibonacci.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String fibonacciStr = fibonacciRecursion(0, 1, 10);
}
}
String fibonacciRecursion(int value0, int value1, int depth){
StringBuilder fibStr = new StringBuilder();
if(depth > 0){
fibStr.append(fibonacciRecursion(value1, value0 + value1, depth-1));
}
return fibStr;
}
As you didn't mention any limit, the depth parameter is meant so your recursion has a way of stopping, as to avoid a SO.
I haven't tested this, but it should be enough to get you closer to a solution of your own design.
Edit
As per #Tom Hawtin - tackline 's comment, this can also be done via lambda expression
fibonacci.addActionListener(actionEvent->
System.our.println(fibonacciRecursion(0, 1, 10)));
I have an operation in which the value of a variable changes during the following process. The following code shows this operation.
private long checkOffCode(String pChode) {
final long[] percent = {0};
APIGettingPosts apiGettingPosts = new APIGettingPosts(MainActivity.this, "get_off_code.php");
apiGettingPosts.getOffCode(new APIGettingPosts.OnOffCodeReceived() {
#Override
public void onReceived(List<Posts> posts) {
if (posts == null || posts.isEmpty()) {
// There is no value on sever...
} else {
for (int i = 0; i < posts.size(); ++i) {
// If the code in serve is equal with pCode],
// change the price value....
if (pChode.equals(posts.get(i).getCode())) {
percent[0] = Long.valueOf(posts.get(i).getPercent());
}
}
}
}
});
return percent[0];
}
The checkOffCode function receives a code, and returns a variable named percent if its value is equal to the value stored in the server.
In the event setOnClickListener of the btnPurchase button, this value is called, and using of its value, the price variable is computed.
The code for this section is as follows:
btnPurchase.setOnClickListener(new View.OnClickListener(){
long percent = 0;
#Override
public void onClick (View view){
percent = checkOffCode("MYCODE");
if (percent != 0) {
// update price value...
price = price - price * percent / 100;
Log.e("Success >>", String.valueOf(price));
} else {
Log.e("Failure >>", String.valueOf(price));
}
}
});
The problem is that when I click on the btnPurchase button for the first time, the previous value of percent [percent = 0] is calculated in the operation, but when I click on the button for the second time, the variable price is calculated with the new percent value.
The output Log cat is shown in both first and second clicks respectively as follow:
08-28 00:45:04.589 28467-28467/? E/Success >>: 125000
08-28 00:45:11.425 28467-28467/? E/Success >>: 16000
The question is: How can I calculate the value of price with the new percent value at the first time?
There is no relation with whether you click the button first or second time.
The problem is that you try to get the return value from checkOffCode directly without being sure about that onReceived has been called. You can change the code like this:
private void checkOffCode(String pChode) {
final long[] percent = {0};
APIGettingPosts apiGettingPosts = new APIGettingPosts(MainActivity.this, "get_off_code.php");
apiGettingPosts.getOffCode(new APIGettingPosts.OnOffCodeReceived() {
#Override
public void onReceived(List<Posts> posts) {
if (posts == null || posts.isEmpty()) {
// There is no value on sever...
} else {
for (int i = 0; i < posts.size(); ++i) {
// If the code in serve is equal with pCode],
// change the price value....
if (pChode.equals(posts.get(i).getCode())) {
percent[0] = Long.valueOf(posts.get(i).getPercent());
}
}
}
if (percent[0] != 0) {
// update price value...
price = price - price * percent[0] / 100;
Log.e("Success >>", String.valueOf(price));
} else {
Log.e("Failure >>", String.valueOf(price));
}
}
});
}
btnPurchase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkOffCode("MYCODE");
}
});
You can try adding boolean that if firstClicked, calculate the price, so if you tap again for the second time, the calculation will not triggered. This is the example:
First make boolean variable outside the onClick function:
private Boolean isFirstClicked = false;
Then modify your onClick function:
if (!isFirstClicked) {
// update price value...
isFirstClicked = true
price = price - price * percent / 100;
Log.e("Success >>", String.valueOf(price));
} else {
Log.e("Failure >>", String.valueOf(price));
}
I am attempting to create a calculator app, when I try to add 2 decimals together, I do not get the results I anticipated.
examples:
user inputs [1.1 + 1.1] and [1.1 + 1] or 2.1 is returned.
It is as if as if second value is being truncated, I am not entirely sure where this would be occurring
user inputs[2.1 + 2] and [2.1 + 2] or 4.1 is returned
user inputs [2 + 2.1] and [2 + 2] or 4 is returned
I have not used the debugger, though I have placed print line statements through out the code and I have not been able to see the issue.
Code:
information
I only attached a single number (image button) as all numbers 1-9 have identical code
variables that are not instantiated in code below have been instantiated as "" if they are a string and 0.0 if they are a double
I am using an array list called values which takes in strings, and using double.parsedouble() to convert it to a double, this occurs in the equals method
please let me know if their is anything I need to add to make this question easier to understand, and any help is appreciated
thank you!
1 button
one_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (plus_selected) {
update_selected_buttons(); //for boolean variables and to change mathematical function button image
screen_value = "";
updateScreen("1");
System.out.println(screen_value);
values.add(screen_value);
} else {
updateScreen("1");
System.out.println(screen_value);
}
}
});
addition button
addition_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!plus_selected) {
plus_selected = true;
addition_button_ET.setImageResource(R.drawable.addition_selected_500_500);
if(Double.parseDouble(screen_value) == current_value){
}
else
values.add(screen_value);//
} else {
plus_selected = false;
addition_button_ET.setImageResource(R.drawable.addition_button_500_500);
}
}
});
update screen
private void updateScreen(String value) { //being used for only one_button
//to reset title text
if (screen_value.equals(initial_screen_value)) {
screen_value = "0.0";
screen_TV.setTextSize(50);
}
//clears default value (0.0), allowing user to enter in a number
if (screen_value.equals("0.0")) {
screen_value = value;
screen_TV.setText(screen_value);
} else {
screen_value += value;
System.out.println(screen_value);
screen_TV.setText(screen_value);
}
}
clear button (clear button calls this method, and that is the only parameter it has)
private void resetScreen() {
screen_value = "0.0";
//values.clear();
screen_TV.setTextSize(50);
screen_TV.setText(screen_value);
}
equals button
equals_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
current_value = 0;
sum = 0;
System.out.println(values);
for(int i = 0; i<values.size();i++) {
sum += Double.parseDouble(values.get(i));
}
current_value = sum;
screen_value = "" + sum;
screen_TV.setText(screen_value);
}
});
So basically i need to be able to click a button, and each time its clicked it takes away 10 from 100. so after 10 clicked it should display 0.
public class numberclass{
public String numbermethod() {
int number = 100;
String result = Integer.toString(number);
return result;
}
}
//part of swing class below
String numberString = numberclass.numbermethod();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textArea.append(numberString);
}
}
});
obviously as it stands it only displays 100 in the text field upon a click. I have tried many ways to make this work, but i feel like i'm missing something crucial. i have tried to google this basic, basic problem, however i seem to not be able to word it correctly.
Start by subtracting something from something. Now, there's any number of ways you might achieve this, but lets start by using a method and maintain the class encapsulation...
public class NumberClass {
private int number = 100;
public void update() {
number -= 10;
}
public String numbermethod() {
String result = Integer.toString(number);
return result;
}
}
Then update the text to be displayed
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
numberClass.update();
String numberString = numberClass.numbermethod();
textArea.append(numberString);
}
});
You numbermethod() is flawed. You set number to 100 and return that value (100) as a String. It will never be something other than "100"! Move int number = 100; outside the method (member variable)
In your button listener add:
number -= 10; // or number = number - 10;