I have this calculator I've been working on in my free time. It works pretty good, except for the fact you can only have two operands..
Could someone take a look at it and tell me how I could make it so I can have more than two operands?
like this:
1-2+3/4*5
Right now I can only do this:
1+2 (or any operator)
Here is my code:
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Calculator extends JFrame implements ActionListener
{
JButton[] btnNums;
JButton btnBack;
JButton btnClear;
JButton btnCalculate;
String[] strNames;
String strOperand1;
String strOperand2;
Boolean wasClicked;
String answer;
double dd;
final String STR_MULTIPLY = "MULTIPLY";
final String STR_DIVIDE = "DIVIDE";
final String STR_ADD = "ADD";
final String STR_SUBTRACT = "SUBTRACT";
String whichOperator;
JTextField txtDisplay;
public Calculator()
{
Container content = getContentPane();
setSize(210,250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* construct a JPanel and the textfield that
* will show the inputed values and outputed
* results
*/
JPanel jpDisplay = new JPanel();
jpDisplay.setLayout(new BorderLayout());
txtDisplay = new JTextField(15);
txtDisplay.setHorizontalAlignment(JTextField.RIGHT);
jpDisplay.add(txtDisplay);
/* contstruct a JPanel that will contain a back
* button and a clear button.
*/
JPanel jpRow2 = new JPanel();
btnBack = new JButton("Backspace");
btnBack.addActionListener(this);
btnClear = new JButton("Clear");
btnClear.addActionListener(this);
btnClear.addActionListener(this);
jpRow2.add(btnBack);
jpRow2.add(btnClear);
/* construct a string array with all the names of the
* buttons, then in a for loop create the new buttons
* and add their name and an actionListener to them.
*/
String[] strNames = {"7","8", "9","/", "4", "5", "6","*", "1",
"2", "3","+", "0", "+/-", ".", "-"};
btnNums = new JButton[16];
JPanel jpButtons = new JPanel();
jpButtons.setLayout(new GridLayout(4,4));
for (int i = 0; i < 16; i++)
{
btnNums[i] = new JButton(strNames[i]);
btnNums[i].addActionListener(this);
jpButtons.add(btnNums[i]);
}
/* construct the final JPanel and add a
* calculate button to it.
*/
JPanel jpLastRow = new JPanel();
btnCalculate = new JButton("Calculate");
btnCalculate.addActionListener(this);
jpLastRow.add(btnCalculate);
//make wasClicked have a default value of false
wasClicked = false;
/* set the contentPane and create the layout
* add the panels to the container
*/
setContentPane(content);
setLayout(new FlowLayout());
setResizable(false);
content.add(jpDisplay, BorderLayout.NORTH);
content.add(jpRow2);
content.add(jpButtons);
content.add(jpLastRow);
setTitle("Mini Calculator");
setVisible(true);
}
public void actionPerformed(ActionEvent ae)
{
// if any of the array buttons was clicked append the button's text
for (int i =0; i < 16; i++)
{
if (ae.getSource() == btnNums[i])
{
txtDisplay.setText(txtDisplay.getText()
+ btnNums[i].getText());
}
}
/* if the backspace button was clicked, then create substring
* to to subtract the farthest character to the right
*/
if (ae.getSource() == btnBack)
{
String strAll = txtDisplay.getText();
int length = strAll.length();
String strShowThis = strAll.substring(0,length - 1);
txtDisplay.setText(strShowThis);
}
else if (ae.getSource() == btnClear)
{
txtDisplay.setText(null);
}
else if (ae.getSource() == btnCalculate)
{
String strText = txtDisplay.getText();
try
{
int equation = Integer.parseInt(strText);
txtDisplay.setText("" + equation);
}
catch (ArithmeticException aee)
{
aee.printStackTrace();
}
}
/* start the process of finding which operator was
* chosen, and the process the equation in a new
* method
*/
if (ae.getSource() == btnNums[3])
{
processDivide();
}
else if (ae.getSource() == btnNums[7])
{
processMultiply();
}
else if (ae.getSource() == btnNums[11])
{
processAdd();
}
else if (ae.getSource() == btnNums[13])
{
processPosOrNeg();
}
else if (ae.getSource() == btnNums[15])
{
processSubtract();
}
else
{
}
// and finally process the calculation
if (ae.getSource() == btnCalculate)
{
processCalc();
}
else
{
}
}
public void processDivide()
{
whichOperator = STR_DIVIDE;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
String s = strOperand1.substring(0, x - 1);
dd = Double.parseDouble(s);
txtDisplay.setText(null);
}
public void processMultiply()
{
whichOperator = STR_MULTIPLY;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
String s = strOperand1.substring(0, x - 1);
dd = Double.parseDouble(s);
txtDisplay.setText(null);
}
public void processAdd()
{
whichOperator = STR_ADD;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
System.out.println("variable x = " + x);
String s = strOperand1.substring(0, x - 1);
System.out.println("variable s = " + s);
dd = Double.parseDouble(s);
System.out.println("variable d = " + dd);
txtDisplay.setText(null);
}
public void processPosOrNeg()
{
}
public void processSubtract()
{
whichOperator = STR_SUBTRACT;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
String s = strOperand1.substring(0, x - 1);
dd = Double.parseDouble(s);
txtDisplay.setText(null);
}
public void processCalc()
{
strOperand2 = txtDisplay.getText();
int x = strOperand2.length();
String s = strOperand2.substring(0, x);
double d = Double.parseDouble(s);
if (whichOperator == STR_SUBTRACT)
{
double a = dd - d;
txtDisplay.setText(dd + "-" + d + " = " + a);
}
else if (whichOperator == STR_ADD)
{
double a = dd + d;
txtDisplay.setText(dd + "+" + d + " = " + a);
}
else if (whichOperator == STR_MULTIPLY)
{
double a = dd * d;
txtDisplay.setText(dd + "*" + d + " = " + a);
}
else if (whichOperator == STR_DIVIDE)
{
double a = dd / d;
txtDisplay.setText(dd + "/" + d + " = " + a);
}
else
{
}
}
public static void main(String[] args)
{
Calculator calc = new Calculator();
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Calculator extends JFrame implements ActionListener
{
JButton[] btnNums;
JButton btnBack;
JButton btnClear;
JButton btnCalculate;
String[] strNames;
String strOperand1;
String strOperand2;
Boolean wasClicked;
String answer;
double dd;
final String STR_MULTIPLY = "MULTIPLY";
final String STR_DIVIDE = "DIVIDE";
final String STR_ADD = "ADD";
final String STR_SUBTRACT = "SUBTRACT";
String whichOperator;
JTextField txtDisplay;
public Calculator()
{
Container content = getContentPane();
setSize(210,250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* construct a JPanel and the textfield that
* will show the inputed values and outputed
* results
*/
JPanel jpDisplay = new JPanel();
jpDisplay.setLayout(new BorderLayout());
txtDisplay = new JTextField(15);
txtDisplay.setHorizontalAlignment(JTextField.RIGHT);
jpDisplay.add(txtDisplay);
/* contstruct a JPanel that will contain a back
* button and a clear button.
*/
JPanel jpRow2 = new JPanel();
btnBack = new JButton("Backspace");
btnBack.addActionListener(this);
btnClear = new JButton("Clear");
btnClear.addActionListener(this);
btnClear.addActionListener(this);
jpRow2.add(btnBack);
jpRow2.add(btnClear);
/* construct a string array with all the names of the
* buttons, then in a for loop create the new buttons
* and add their name and an actionListener to them.
*/
String[] strNames = {"7","8", "9","/", "4", "5", "6","*", "1",
"2", "3","+", "0", "+/-", ".", "-"};
btnNums = new JButton[16];
JPanel jpButtons = new JPanel();
jpButtons.setLayout(new GridLayout(4,4));
for (int i = 0; i < 16; i++)
{
btnNums[i] = new JButton(strNames[i]);
btnNums[i].addActionListener(this);
jpButtons.add(btnNums[i]);
}
/* construct the final JPanel and add a
* calculate button to it.
*/
JPanel jpLastRow = new JPanel();
btnCalculate = new JButton("Calculate");
btnCalculate.addActionListener(this);
jpLastRow.add(btnCalculate);
//make wasClicked have a default value of false
wasClicked = false;
/* set the contentPane and create the layout
* add the panels to the container
*/
setContentPane(content);
setLayout(new FlowLayout());
setResizable(false);
content.add(jpDisplay, BorderLayout.NORTH);
content.add(jpRow2);
content.add(jpButtons);
content.add(jpLastRow);
setTitle("Mini Calculator");
setVisible(true);
}
public void actionPerformed(ActionEvent ae)
{
// if any of the array buttons was clicked append the button's text
for (int i =0; i < 16; i++)
{
if (ae.getSource() == btnNums[i])
{
txtDisplay.setText(txtDisplay.getText()
+ btnNums[i].getText());
}
}
/* if the backspace button was clicked, then create substring
* to to subtract the farthest character to the right
*/
if (ae.getSource() == btnBack)
{
String strAll = txtDisplay.getText();
int length = strAll.length();
String strShowThis = strAll.substring(0,length - 1);
txtDisplay.setText(strShowThis);
}
else if (ae.getSource() == btnClear)
{
txtDisplay.setText(null);
}
else if (ae.getSource() == btnCalculate)
{
String strText = txtDisplay.getText();
try
{
int equation = Integer.parseInt(strText);
txtDisplay.setText("" + equation);
}
catch (ArithmeticException aee)
{
aee.printStackTrace();
}
}
/* start the process of finding which operator was
* chosen, and the process the equation in a new
* method
*/
if (ae.getSource() == btnNums[3])
{
processDivide();
}
else if (ae.getSource() == btnNums[7])
{
processMultiply();
}
else if (ae.getSource() == btnNums[11])
{
processAdd();
}
else if (ae.getSource() == btnNums[13])
{
processPosOrNeg();
}
else if (ae.getSource() == btnNums[15])
{
processSubtract();
}
else
{
}
// and finally process the calculation
if (ae.getSource() == btnCalculate)
{
processCalc();
}
else
{
}
}
public void processDivide()
{
whichOperator = STR_DIVIDE;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
String s = strOperand1.substring(0, x - 1);
dd = Double.parseDouble(s);
txtDisplay.setText(null);
}
public void processMultiply()
{
whichOperator = STR_MULTIPLY;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
String s = strOperand1.substring(0, x - 1);
dd = Double.parseDouble(s);
txtDisplay.setText(null);
}
public void processAdd()
{
whichOperator = STR_ADD;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
System.out.println("variable x = " + x);
String s = strOperand1.substring(0, x - 1);
System.out.println("variable s = " + s);
dd = Double.parseDouble(s);
System.out.println("variable d = " + dd);
txtDisplay.setText(null);
}
public void processPosOrNeg()
{
}
public void processSubtract()
{
whichOperator = STR_SUBTRACT;
strOperand1 = txtDisplay.getText();
int x = strOperand1.length();
String s = strOperand1.substring(0, x - 1);
dd = Double.parseDouble(s);
txtDisplay.setText(null);
}
public void processCalc()
{
strOperand2 = txtDisplay.getText();
int x = strOperand2.length();
String s = strOperand2.substring(0, x);
double d = Double.parseDouble(s);
if (whichOperator == STR_SUBTRACT)
{
double a = dd - d;
txtDisplay.setText(dd + "-" + d + " = " + a);
}
else if (whichOperator == STR_ADD)
{
double a = dd + d;
txtDisplay.setText(dd + "+" + d + " = " + a);
}
else if (whichOperator == STR_MULTIPLY)
{
double a = dd * d;
txtDisplay.setText(dd + "*" + d + " = " + a);
}
else if (whichOperator == STR_DIVIDE)
{
double a = dd / d;
txtDisplay.setText(dd + "/" + d + " = " + a);
}
else
{
}
}
public static void main(String[] args)
{
Calculator calc = new Calculator();
}
}
Here is a class I wrote this weekend for evaluating Math expressions.
Code:
import java.util.Vector;
class ExpTree{
//used for precedence rules
private final static int IS_OPPAR=7; //open parenthesis
private final static int IS_CLPAR=6; //close parenthesis
private final static int IS_PLUS=5; //addition operator
private final static int IS_MINUS=5; //subtraction operator
private final static int IS_MULTI=4; //multiplication operator
private final static int IS_DIV=4; //division operator
private final static int IS_POWER=3; //power operator
//for error handling - not used at the moment
//private boolean errorOccured=false;
//private String errorMsg;
private Vector ops = new Vector(10,2); //vector where operators are stored to
private Vector postfix = new Vector(10,3); //vector which stores the postfix notation(RPN)
//used to find the first occuring operator
private static int nextOperatorPos(String subExpr){
for(int i=0;i<subExpr.length();i++){
if(getOperator(subExpr.substring(i,i+1))>0){
return i;
}
}
return -1;
}
//used to find out which operator it is and for precedence rules
private static int getOperator(String chr){
int ret=-1;
switch(chr.charAt(0)){
case '+': ret=IS_PLUS;break;
case '-': ret=IS_MINUS;break;
case '*': ret=IS_MULTI;break;
case '/': ret=IS_DIV;break;
case '^': ret=IS_POWER;break;
case '(': ret=IS_OPPAR;break;
case ')': ret=IS_CLPAR;break;
default : ret=-1;
}
return ret;
}
//the method which converts infix to postfix
private void doPostfix(boolean expEnd){
if(!expEnd){
if(ops.size()>1){
int actOp=getOperator((String)ops.elementAt(ops.size()-1));
if((actOp!=IS_OPPAR)&&(actOp!=IS_CLPAR)){
while((ops.size()>1)&&(actOp>=getOperator((String)ops.elementAt(ops.size()-2)))){
postfix.add((String)ops.elementAt(ops.size()-2));
ops.remove(ops.size()-2);
}
}else if(actOp==IS_CLPAR){
ops.remove(ops.size()-1);
while((ops.size()>0)&&(getOperator((String)ops.elementAt(ops.size()-1)))!=IS_OPPAR){
postfix.add((String)ops.elementAt(ops.size()-1));
ops.remove(ops.size()-1);
}
if(getOperator((String)ops.elementAt(ops.size()-1))==IS_OPPAR){
ops.remove(ops.size()-1);
}
}
}
}else{
for(int i=ops.size()-1;i>=0;i--){
postfix.add((String)ops.elementAt(i));
}
}
}
public double result(double xval){
String op;
double[] results=new double[postfix.size()];
int pos=0;
for(int i=0;i<postfix.size();i++){
op=(String)postfix.elementAt(i);
if(getOperator(op)>-1){
switch(op.charAt(0)){
case '+': results[pos-2]=results[pos-2]+results[pos-1];
;break;
case '-': results[pos-2]=results[pos-2]-results[pos-1];
;break;
case '*': results[pos-2]=results[pos-2]*results[pos-1];
;break;
case '/': results[pos-2]=results[pos-2]/results[pos-1];
;break;
case '^': results[pos-2]=Math.pow(results[pos-2],results[pos-1]);
;break;
}
results[pos-1]=0d;
pos--;
}else{
if((op.equals("x"))||(op.equals("X"))){
results[pos]=xval;
}else{
results[pos]=Double.valueOf(op).doubleValue();
}
pos++;
}
}
return results[pos-1];
}
//evaluation of the expression (parsing)
public void evalExp(String expr){
ops.clear();
postfix.clear();
int nextOpPos;
while(expr.length()>0){
nextOpPos=nextOperatorPos(expr);
if(nextOpPos>0){
postfix.add(expr.substring(0,nextOpPos));
expr=expr.substring(nextOpPos);
}else if(nextOpPos==0){
ops.add(expr.substring(nextOpPos,nextOpPos+1));
expr=expr.substring(nextOpPos+1);
doPostfix(false);
}else{
postfix.add(expr.substring(0));
expr="";
doPostfix(false);
}
}
doPostfix(true);
}
}
You can use it this way:
Code:
//initialize a new expression tree
ExpTree myExpression=new ExpTree();
//evaluating the expression
myExpression.evalExp("(1/30)*x^5-(1/2)*x^3");
// process the expression
double myresult = myExpression.result(2);
- the evalExp method requires the math expression as a String , in your case the String of the Textfield
- the result method requires a value for the variable x, if there is no variable in the expression use 0 or any other value. It returns a double value
Wow! That is extremely helpful..When I look this code over, and figure it out, I'll post the code with the finished calculator..Dude, I really appreciate this!
I'm trying to embed ExpTree in my version of the calculator, but currently it bugs out on the expression: 1/2, not to mention the example expression posted here....
Here is the method that bugs out w. ArrayIndexOutOfBoundsException
Code:
private String getValueString(String expression) throws CalculatorException2 {
expTree.evalExp(expression);
// this one fails, I have tried argument values 1->3
return Double.toString(expTree.result(1));
}
Bookmarks