Below I have just the function to do the math for each evaluation, but for some reason, my numbers aren't appearing in the text field as I'm pushing them, which means its not adding them to my string. Is there anything noticeable missing that would cause this? When I run, I do get the message saying wrong input. Thanks in advance!
private double eval(final String str) {
class Parser {
int pos = -1, c;
void eatChar() {
c = (++pos < str.length()) ? str.charAt(pos) : -1;
}
void eatSpace() {
while (Character.isWhitespace(c)) eatChar();
}
double parse() {
eatChar();
double v = parseExpression();
if (c != -1) throw new RuntimeException("Unexpected: " + (char)c);
return v;
}
// Grammar:
// expression = term | expression `+` term | expression `-` term
// term = factor | term `*` factor | term `/` factor | term brackets
// factor = brackets | number | factor `^` factor
// brackets = `(` expression `)`
double parseExpression() {
double v = parseTerm();
for (;;) {
eatSpace();
if (c == '+') { // addition
eatChar();
v += parseTerm();
} else if (c == '-') { // subtraction
eatChar();
v -= parseTerm();
} else {
return v;
}
}
}
double parseTerm() {
double v = parseFactor();
for (;;) {
eatSpace();
if (c == '/') { // division
eatChar();
v /= parseFactor();
} else if (c == '*' || c == '(') { // multiplication
if (c == '*') eatChar();
v *= parseFactor();
} else {
return v;
}
}
}
double parseFactor() {
double v;
boolean negate = false;
eatSpace();
if (c == '(') { // brackets
eatChar();
v = parseExpression();
if (c == ')') eatChar();
} else { // numbers
if (c == '+' || c == '-') { // unary plus & minus
negate = c == '-';
eatChar();
eatSpace();
}
StringBuilder sb = new StringBuilder();
while ((c >= '0' && c <= '9') || c == '.') {
sb.append((char)c);
eatChar();
}
if (sb.length() == 0) throw new RuntimeException("Unexpected: " + (char)c);
v = Double.parseDouble(sb.toString());
}
eatSpace();
if (c == '^') { // exponentiation
eatChar();
v = Math.pow(v, parseFactor());
}
if (negate) v = -v; // exponentiation has higher priority than unary minus: -3^2=-9
return v;
}
}
return new Parser().parse();
}
public void actionPerformed(ActionEvent e){
String input = ((JButton)e.getSource()).getText();
if(input.equals("C")){
formula = "";
}else if(input.equals("=")){
try{
double result = eval(formula);
formula = "" + result;
} catch(RuntimeException re){
JOptionPane.showMessageDialog(null, "Wrong input: " + formula);
formula = "";
}
}else{
formula += input;
}
eqDisplay.setText(formula);
}
public static void main(String[] args) {
Calculator calc = new Calculator();
}
}
Update: Here's the layout too.
public class Calculator extends JFrame implements ActionListener {
String formula;
JTextField eqDisplay;
public Calculator() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new Dimension(230, 250));
this.setTitle("Calculator");
this.setLayout(new BorderLayout());
formula = "";
JPanel centerPanel = new JPanel(new GridBagLayout());
for (int i = 1; i <= 9; i++) {
GridBagConstraints constraint = new GridBagConstraints();
constraint.gridx = (i-1)%3;
constraint.gridy = (i-1)/3;
constraint.insets = new Insets(5, 5, 5, 5);
JButton b = new JButton("" + i);
centerPanel.add(b, constraint);
}
GridBagConstraints constraint = new GridBagConstraints();
constraint.insets = new Insets(5, 5, 5, 5);
constraint.gridx = 0;
constraint.gridy = 3;
constraint.gridwidth = 2;
constraint.fill = GridBagConstraints.BOTH;
JButton num_0 = new JButton("0");
centerPanel.add(num_0, constraint);
num_0.addActionListener(this);
constraint.gridx = 2;
constraint.gridy = 3;
constraint.gridwidth = 1;
constraint.fill = GridBagConstraints.NONE;
JButton point = new JButton(".");
centerPanel.add(point, constraint);
point.addActionListener(this);
constraint.gridx = 3;
constraint.gridy = 0;
JButton divide = new JButton("/");
centerPanel.add(divide, constraint);
divide.addActionListener(this);
constraint.gridx = 3;
constraint.gridy = 1;
JButton multiply = new JButton("*");
centerPanel.add(multiply, constraint);
multiply.addActionListener(this);
constraint.gridx = 3;
constraint.gridy = 2;
JButton minus = new JButton("-");
centerPanel.add(minus, constraint);
minus.addActionListener(this);
constraint.gridx = 3;
constraint.gridy = 3;
JButton plus = new JButton("+");
centerPanel.add(plus, constraint);
plus.addActionListener(this);
constraint.gridx = 0;
constraint.gridy = 4;
constraint.gridwidth = 3;
constraint.fill = GridBagConstraints.BOTH;
JButton result = new JButton("=");
centerPanel.add(result, constraint);
result.addActionListener(this);
constraint.gridx = 3;
constraint.gridy = 4;
constraint.gridwidth = 1;
constraint.fill = GridBagConstraints.NONE;
JButton cButton= new JButton("C");
centerPanel.add(cButton, constraint);
cButton.addActionListener(this);
this.add(centerPanel, BorderLayout.CENTER);
JPanel northPanel = new JPanel(new FlowLayout());
eqDisplay = new JTextField(15);
northPanel.add(eqDisplay);
this.add(northPanel, BorderLayout.NORTH);
this.setVisible(true);
}