1

Currently when user presses buttons on the calculator it displays value on the text box above, but I just cannot get it to solve the equation. Every button that is pressed displays in the TextField but when I press '=' (equals) I would like it so that it solves the equation. Could you help me with this problem please?

//Michael Moradi
//Period C1
//June 2, 2015
//Final Project Semester 2

import javax.swing.*; //imports all that is needed for the code

import java.awt.*;
import java.awt.event.*;

public class Calculator extends JFrame implements ActionListener {

    public JButton button1, button2, button3, button4, button5, button6, button7, button8, button9, button10, button11, button12, button13, button14, button15, button16;
    public JTextArea text; //makes these accessible throughout the code

    public Calculator()
    {
        setSize(350,300); //sets size to 300 by 300
        setResizable(false); //does not let user change the size of the window
        setDefaultCloseOperation(EXIT_ON_CLOSE);//makes app close when I press the x on the top left

        Container contentPane = getContentPane();//gets the contentPane
        contentPane.setBackground(Color.CYAN);//sets background color to white         

        contentPane.setLayout(new FlowLayout());//makes the contentPane read from left to right

        text = new JTextArea(1, 25);
        contentPane.add(text);
        text.setEditable(false);

        button1 = new JButton ("7");
        contentPane.add(button1);
        button1.addActionListener(this);

        button2 = new JButton ("8");
        contentPane.add(button2);
        button2.addActionListener(this);

        button3 = new JButton ("9");
        contentPane.add(button3);
        button3.addActionListener(this);

        button4 = new JButton ("÷");
        contentPane.add(button4);
        button4.addActionListener(this);

        button5 = new JButton ("4");
        contentPane.add(button5);
        button5.addActionListener(this);

        button6 = new JButton ("5");
        contentPane.add(button6);
        button6.addActionListener(this);

        button7 = new JButton ("6");
        contentPane.add(button7);
        button7.addActionListener(this);

        button8 = new JButton ("x");
        contentPane.add(button8);
        button8.addActionListener(this);

        button9 = new JButton ("1");
        contentPane.add(button9);
        button9.addActionListener(this);

        button10 = new JButton ("2");
        contentPane.add(button10);
        button10.addActionListener(this);

        button11 = new JButton ("3");
        contentPane.add(button11);
        button11.addActionListener(this);

        button12 = new JButton ("-");
        contentPane.add(button12);
        button12.addActionListener(this);

        button13 = new JButton ("0");
        contentPane.add(button13);
        button13.addActionListener(this);

        button14 = new JButton ("C");
        contentPane.add(button14);
        button14.addActionListener(this);

        button15 = new JButton ("=");
        contentPane.add(button15);
        button15.addActionListener(this);

        button16 = new JButton ("+");
        contentPane.add(button16);
        button16.addActionListener(this);



    }

    public static void main(String[] args)
    {
        Calculator guiWindow = new Calculator(); //uses GUI
        guiWindow.setVisible(true); //makes it visible

    }

    public void actionPerformed(ActionEvent e)
    {
        Container contentPane = getContentPane();

        String enteredNumbers = text.getText();

        if (e.getActionCommand().equals("7"))
        text.setText(enteredNumbers + ("7"));

        if (e.getActionCommand().equals("8"))
        text.setText(enteredNumbers + ("8"));

        if (e.getActionCommand().equals("9"))
        text.setText(enteredNumbers + ("9"));

        if (e.getActionCommand().equals("÷"))
        text.setText(enteredNumbers + ("÷"));

        if (e.getActionCommand().equals("4"))
        text.setText(enteredNumbers + ("4"));

        if (e.getActionCommand().equals("5"))
        text.setText(enteredNumbers + ("5"));

        if (e.getActionCommand().equals("6"))
        text.setText(enteredNumbers + ("6"));

        if (e.getActionCommand().equals("x"))
        text.setText(enteredNumbers + ("x"));

        if (e.getActionCommand().equals("1"))
        text.setText(enteredNumbers + ("1"));

        if (e.getActionCommand().equals("2"))
        text.setText(enteredNumbers + ("2"));

        if (e.getActionCommand().equals("3"))
        text.setText(enteredNumbers + ("3"));

        if (e.getActionCommand().equals("-"))
        text.setText(enteredNumbers + ("-"));

        if (e.getActionCommand().equals("0"))
        text.setText(enteredNumbers + ("0"));

        if (e.getActionCommand().equals("C"))
        text.setText("");

        if (e.getActionCommand().equals("="))
        text.setText(enteredNumbers + ("="));

        if (e.getActionCommand().equals("+"))
        text.setText(enteredNumbers + ("+"));




    }

}
Phani
  • 5,319
  • 6
  • 35
  • 43
  • 3
    Might just be me, but it looks like your code only sets text when the = button is pressed. Do you have any code pertaining to equation solving? – taylorc93 May 31 '15 at 01:52
  • See also this [calculator example](http://stackoverflow.com/a/7441804/418556). It uses `ScriptEngine` to evaluate the expression in the text field. – Andrew Thompson May 31 '15 at 02:14
  • 1
    A calculation is a group of `{value}{operator}{value}`, you need to generate these groups and perform the calculation, don't forget, order of precedence – MadProgrammer May 31 '15 at 05:18
  • BTW `text = new JTextArea(1, 25);` should probably better be `text = new JTextField(25);` (with appropriate changes in the declaration of the `text` field). – Andrew Thompson May 31 '15 at 06:07
  • @MadProgrammer , If I had a string with format `{value}{operator}{value}` like `"11-1"`, how would I parse the string into `int num1`,`char operator` and `int num2` so that each variable will hold `11`,`'-'` and `1`? Is there a function to do it? – Spikatrix May 31 '15 at 07:53
  • 1
    `String#split` might be my first port of call – MadProgrammer May 31 '15 at 08:00

2 Answers2

0

For something like this, you simply want to change your ActionListener. Every other button—which I strongly encourage you to give more meaningful names, by the way—simply adds a token of text to the calculator field. "=" is meant, by your description, to solve it. So,

if (e.getActionCommand().equals("="))
    text.setText(enteredNumbers + ("="));

should be more like this:

if (e.getActionCommand().equals("=")) {
    String math = text.getText();
    answerField.setText(solve(math));
}

private solve(String math) {
    //This is the tricky part, see description next.
}

For your solving method, I would suggest one of two things. The first would be to break it down with a series of regular expressions, which you can create and try out (before implementing) here. From there, you will know whether a provided field will be a number, or an operator. Operators are often best paired with enumerations and Function fields. Unfortunately, this still leaves the question of how to handle operator precedence open.

For that, you'll want to break it down into Reverse Polish Notation; with something like the Shunting-Yard algorithm. After that, you can just step through and apply each operation function in the order it appears.

If you're in a hurry, you could probably also use the Java Scripting Engine and simply implement your math as solvable JavaScript; a tutorial available here. Currently, Javascript/ECMAscript is available, but I'm sure there are plenty of others available through external libraries. (When you're dealing with frequently changing dynamic code, it's a godsend.)

Hopefully one of these resources will help you. I actually once implemented a script in Java that specifically focused on solving mathematical equations, using the first method; and now just plug it in to new applications with the second method. Best of luck!

Michael Macha
  • 1,729
  • 1
  • 16
  • 25
0

How about something like this, using the JavaScript library math.js via a Java Script Engine. You can download the file math.js from: http://mathjs.org/download.html

package org.mathjs;

import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class MathJS {
    protected static String MATHJS_SCRIPT = "./lib/mathjs/math.js";
    protected ScriptEngine engine;

    public MathJS () throws FileNotFoundException, ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager ();
        engine = manager.getEngineByName ("js");

        engine.eval(new FileReader(MATHJS_SCRIPT));
        engine.eval("var parser = math.parser();");
        engine.eval("var precision = 14;");
    }

    public String eval (String expr) throws ScriptException {
        String script = "math.format(parser.eval('" + expr + "'), precision);";
        return (String) engine.eval(script);
    }

    public static void main(String[] args) 
            throws FileNotFoundException, ScriptException {
        MathJS math = new MathJS();
        System.out.println(math.eval("a = 4.5"));
        System.out.println(math.eval("1.2 * (2 + a)"));
        System.out.println(math.eval("5.08 cm in inch"));
        System.out.println(math.eval("sin(45 deg) ^ 2"));   
        System.out.println(math.eval("9 / 3 + 2i") );   
        System.out.println(math.eval("det([-1, 2; 3, 1])"));
    }
}
Jos de Jong
  • 6,602
  • 3
  • 38
  • 58