Java Scientific calculator GUI - java

I am working on a calculator with a GUI. I'm not sure how I should gather all the numbers from the user and do the math for them. I tried storing them in variables, but that doesn't really work since I need to be able to have multiple numbers and operators at one time. Any input would be greatly appreciated. Thanks!
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI extends JFrame implements ActionListener {
private JFrame frame;
private JPanel buttons;
//
private JPanel text;
private JTextField field;
//
private ImageIcon WCU;
private JLabel labelWCU;
///
JButton[] nums = new JButton[10];
JButton[] functions = new JButton[15];
ArrayList<Double> Addition = new ArrayList<>();
double A;
double S;
double M;
double D;
double Answer;
private JButton num1, num2, num3, num4, num5, num6, num7, num8, num9, num0;
private JButton decimal, add, subtract, multiply, divide, equals, squareRoot;
private JButton sin, cos, tan, exclamation, oneOverX, xSquared, log;
private JButton clear;
double input1 = 0, input2 = 0, answer = 0;
char op;
public GUI() {
frame = new JFrame();
buttons = new JPanel();
//
text = new JPanel();
field = new JTextField(30);
//
WCU = new ImageIcon("WCU.png");
labelWCU = new JLabel(WCU);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Calculator"); // make sure to center
frame.setSize(525,750);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setLayout(new BorderLayout());
frame.add(text, BorderLayout.NORTH);
frame.add(buttons, BorderLayout.CENTER);
text.add(field);
field.setEditable(false);
text.setBackground(Color.RED);
buttons.setBackground(Color.red);
buttons.setBorder(BorderFactory.createEmptyBorder(20,50,300,50));
buttons.setLayout(new GridLayout(6,4,20,20));
//
buttons.add(decimal = new JButton ("."));
functions[0] = decimal;
buttons.add(add = new JButton ("+"));
functions[1] = add;
buttons.add(subtract = new JButton ("-"));
functions[2] = subtract;
buttons.add(multiply = new JButton ("*"));
functions[3] = multiply;
buttons.add(divide = new JButton ("/"));
functions[4] = divide;
buttons.add(equals = new JButton ("="));
functions[5] = equals;
buttons.add(squareRoot = new JButton ("√"));
functions[6] = squareRoot;
buttons.add(num1 = new JButton ("1"));
nums[1] = num1;
buttons.add(num2 = new JButton ("2"));
nums[2] = num2;
buttons.add(num3 = new JButton ("3"));
nums[3] = num3;
buttons.add(num4 = new JButton ("4"));
nums[4] = num4;
buttons.add(num5 = new JButton ("5"));
nums[5] = num5;
buttons.add(num6 = new JButton ("6"));
nums[6] = num6;
buttons.add(num7 = new JButton ("7"));
nums[7] = num7;
buttons.add(num8 = new JButton ("8"));
nums[8] = num8;
buttons.add(num9 = new JButton ("9"));
nums[9] = num9;
buttons.add(num0 = new JButton ("0"));
nums[0] = num0;
buttons.add(sin = new JButton ("sin"));
functions[7] = sin;
buttons.add(cos = new JButton ("cos"));
functions[8] = cos;
buttons.add(tan = new JButton ("tan"));
functions[9] = tan;
buttons.add(exclamation = new JButton ("!"));
functions[10] = exclamation;
buttons.add(oneOverX = new JButton ("1/x"));
functions[11] = oneOverX;
buttons.add(xSquared = new JButton ("x^2"));
functions[12] = xSquared;
buttons.add(log = new JButton ("log"));
functions[13] = log;
text.add(clear = new JButton("Clear"));
functions[14] = clear;
labelWCU.setIcon(WCU);
frame.setVisible(true);
//
for (int i = 0; i < 15; i++){
functions[i].addActionListener(this);
functions[i].setFocusable(false);
}
for (int i = 0; i < 10; i++){
nums[i].addActionListener(this);
nums[i].setFocusable(false);
}
}
public void actionPerformed(ActionEvent e){
for (int i = 0; i < 10; i++){
if(e.getSource() == nums[i]){
field.setText(field.getText().concat(String.valueOf(i)));
}
}
if(e.getSource() == decimal){
field.setText(field.getText().concat("."));
}
if(e.getSource() == add){
A = Double.parseDouble(field.getText());
op = '+';
field.setText("");
}
if(e.getSource() == subtract){
input1 = Double.parseDouble(field.getText());
op = '-';
field.setText("");
}
if(e.getSource() == multiply){
input1 = Double.parseDouble(field.getText());
op = '*';
field.setText("");
}
if(e.getSource() == divide){
input1 = Double.parseDouble(field.getText());
op = '/';
field.setText("");
}
if(e.getSource() == equals){
field.setText(String.valueOf(Addition));
}
if(e.getSource() == clear){
field.setText("");
A = 0;
}
}
}

I don't fully understand the purpose of all fields in your class, so I'll propose my own set. If we (ab)use the text field as storage for the current value, two state fields are enough for the basic functionality. It's not necessary to store any more data:
private String firstBinaryOperand = null;
private char binaryOp = ' ';
These fields are used if there is a pending binary operation such as + or -. We don't need them for unary operations. For example, if the user types "700 + 200 =", then
When the "+" button is pressed for the first time, the currently displayed value (700) is stored in firstBinaryOperand and '+' in binaryOp.
When the "=" button is pressed, the current value (200) and the value cached in firstBinaryOperand are added and the result (900) written into the text field.
We therefore need a method that evaluates a pending binary operation if there is one and writes the result into the text field:
// Evaluate pending binary operation, if there is one.
private void evaluateBinaryOp() {
if (binaryOp != ' ') {
double firstOperand = Double.parseDouble(firstBinaryOperand);
double secondOperand = Double.parseDouble(field.getText());
double result;
if (binaryOp == '+') {
field.setText(Double.toString(firstOperand + secondOperand));
} else if (binaryOp == '-') {
field.setText(Double.toString(firstOperand - secondOperand));
}
// Implementation of further binary operands ...
// Update state, there is no longer a pending binary operation
firstBinaryOperand = null;
binaryOp = ' ';
}
}
Addition as an example of a binary operation:
if (e.getSource() == add){
evaluateBinaryOp(); // evaluate pending binary op, if any
firstBinaryOperand = field.getText();
binaryOp = '+';
field.setText("0");
}
Unary operations are simpler, but we still have to check whether there is a pending binary operation and evaluate it first if this is the case:
if (e.getSource() == oneOverX) {
evaluateBinaryOp(); // evaluate pending binary op, if any
double currentValue = Double.parseDouble(field.getText());
field.setText(Double.toString(1.0 / currentValue));
}
All other unary and binary operations can be implemented using the same pattern.
This is going to give you a very basic calculator whose behavior differs a bit from the usual. For example, if the user presses +, they will not see the intermediate result but always 0. The intermediate result isn't lost though as it is stored in the firrstBinaryOperand field in the background. The correct result will be shown once = or another unary operator is used. I hope this answers your question and is enough to get you started, you can then refine the behavior in a second step.

Related

Java Gui Sum of Two Number

I made a GUI which basically adds the numbers from the two textfield. The problem is, if I leave the other textfield blank and the other textfield has a number, the result textfield is not updating.
public class AdditionGui extends JFrame implements ActionListener {
private TextField tf1 , tf2 , tf3;
private Label sign, equalsign;
private int sum = 0;
AdditionGui(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
tf1 = new TextField(5);
add(tf1);
tf1.addActionListener(this);
sign = new Label("+");
add(sign);
tf2 = new TextField(5);
add(tf2);
tf2.addActionListener(this);
equalsign = new Label("=");
add(equalsign);
tf3 = new TextField(5);
add(tf3);
setTitle("Sum of two numbers");
setSize(220,120);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
int val1 = Integer.parseInt(tf1.getText());
int val2 = Integer.parseInt(tf2.getText());
sum = val1 + val2;
tf3.setText("" + sum);
}
}
A blank text field means its contents cannot be parsed to an Integer. In that case this line of your code will throw NumberFormatException (if tf1 is blank).
int val1 = Integer.parseInt(tf1.getText());
In your actionPerformed() method, check that getText() returns a number.
I suggest setting a blank text field to zero, for example:
String text1 = tf1.getText();
if (text1.length() == 0) {
text1 = "0";
}
int val1 = Integer.parseInt(text1);
String text2 = tf2.getText();
if (text2.length() == 0) {
text2 = "0";
}
int val2 = Integer.parseInt(text2);
int sum = val1 + val2;
tf3.setText(Integer.toString(sum));
Now something for you to think about.
What happens if the user enters a non-digit into one of the text fields?

Simple java calculation code not working fully

I have been creating a calculator as a beginner in Java. I have added in buttons that have a more complex functionality, and for some reason they just don't work.
Can somebody please educate me on why these java calculations are not working properly?
The buttons that work fine are the plus, minus, multiply and divide.
The buttons that aren't working so well are the percentage, squareRt, and the PlusMinus buttons.
You can see in the calculator engine that I have implemented the correct method of calculation, however when the problematic buttons are pressed, the text display area of the calculator goes blank, when for example, if you press in 64 on the calculator and then press sqrt, it is suppose to display the Square root of 64, but is not doing so. Thanks for any help in advance. (take it easy on me i'm a beginner)
Here is the calculator
package Calculator;
import javax.swing.*;
import java.awt.GridLayout;
import java.awt.BorderLayout;
public class Calculator {
// Declare and instantiate window components
JButton button0 = new JButton("0");
JButton button1 = new JButton("1");
JButton button2 = new JButton("2");
JButton button3 = new JButton("3");
JButton button4 = new JButton("4");
JButton button5 = new JButton("5");
JButton button6 = new JButton("6");
JButton button7 = new JButton("7");
JButton button8 = new JButton("8");
JButton button9 = new JButton("9");
JButton buttonPoint = new JButton(".");
JButton buttonEqual = new JButton("=");
JButton buttonPlus = new JButton("+");
JButton buttonMinus = new JButton("-");
JButton buttonDivide = new JButton("/");
JButton buttonMultiply = new JButton("*");
JButton buttonSquareRt = new JButton("sqrt");
JButton buttonPercentage = new JButton("%");
JButton buttonPlusMinus = new JButton("+/-");
JButton buttonClear = new JButton("C");
JPanel windowContent = new JPanel();
JTextField displayField = new JTextField(30);
// Constructor
Calculator() {
// Set the layout manager for this panel
BorderLayout bl = new BorderLayout();
windowContent.setLayout(bl);
// Add the display field to the top of the window
windowContent.add("North", displayField);
// Create the panel with the GridLayout
// that will contain 12 buttons - 10 numeric ones, and
// buttons with the point and the equal sign
JPanel p1 = new JPanel();
GridLayout gl = new GridLayout(4, 3);
p1.setLayout(gl);
p1.add(button1);
p1.add(button2);
p1.add(button3);
p1.add(button4);
p1.add(button5);
p1.add(button6);
p1.add(button7);
p1.add(button8);
p1.add(button9);
p1.add(button0);
p1.add(buttonPoint);
p1.add(buttonEqual);
// Add the panel p1 to the centre area of the window
windowContent.add("Center", p1);
// Create the panel with the GridLayout
// that will contain 4 action buttons -
// Plus, Minus, Divide and Multiply
JPanel p2 = new JPanel();
GridLayout gl2 = new GridLayout(4, 1);
p2.setLayout(gl);
p2.add(buttonPlus);
p2.add(buttonMinus);
p2.add(buttonMultiply);
p2.add(buttonDivide);
//adding the task buttons to go on extra column
p2.add(buttonSquareRt);
p2.add(buttonPercentage);
p2.add(buttonPlusMinus);
p2.add(buttonClear);
// Add the panel p2 to the east area of the window
windowContent.add("East", p2);
// Create the frame and add the content pane to it
JFrame frame = new JFrame("Calculator");
frame.setContentPane(windowContent);
// set the size of the window to be big enough to
// accommodate all window controls
frame.pack();
// Display the window
frame.setVisible(true);
// Instantiate the event listener and
// register each button with it
CalculatorEngine calcEngine = new CalculatorEngine(this);
button0.addActionListener(calcEngine);
button1.addActionListener(calcEngine);
button2.addActionListener(calcEngine);
button3.addActionListener(calcEngine);
button4.addActionListener(calcEngine);
button5.addActionListener(calcEngine);
button6.addActionListener(calcEngine);
button7.addActionListener(calcEngine);
button8.addActionListener(calcEngine);
button9.addActionListener(calcEngine);
buttonPoint.addActionListener(calcEngine);
buttonPlus.addActionListener(calcEngine);
buttonMinus.addActionListener(calcEngine);
buttonDivide.addActionListener(calcEngine);
buttonMultiply.addActionListener(calcEngine);
buttonEqual.addActionListener(calcEngine);
buttonSquareRt.addActionListener(calcEngine);
buttonPercentage.addActionListener(calcEngine);
buttonPlusMinus.addActionListener(calcEngine);
buttonClear.addActionListener(calcEngine);
}
public static void main(String[] args) {
// Instantiate the class Calculator
Calculator calc = new Calculator();
}
}
And here is the engine with the problematic code
package Calculator;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
public class CalculatorEngine implements ActionListener {
Calculator parent; // a reference to Calculator window
char selectedAction = ' '; // +, -, /, or *
double currentResult = 0;
// Constructor stores the reference to the Calculator
// window in the member variable parent
CalculatorEngine(Calculator parent) {
this.parent = parent;
}
public void actionPerformed(ActionEvent e) {
// Get the source of this action
JButton clickedButton = (JButton) e.getSource();
String dispFieldText = parent.displayField.getText();
double displayValue = 0;
// Get the number from the text field
// if it’s not empty
if (!"".equals(dispFieldText)) {
displayValue = Double.parseDouble(dispFieldText);
}
Object src = e.getSource();
// For each action button memorize selected
// action +, -, /, or *, store the current value
// in the currentResult, and clean up the display
// field for entering the next number
if (src == parent.buttonPlus) {
selectedAction = '+';
currentResult = displayValue;
parent.displayField.setText("");
} else if (src == parent.buttonMinus) {
selectedAction = '-';
currentResult = displayValue;
parent.displayField.setText("");
} else if (src == parent.buttonDivide) {
selectedAction = '/';
currentResult = displayValue;
parent.displayField.setText("");
} else if (src == parent.buttonMultiply) {
selectedAction = '*';
currentResult = displayValue;
parent.displayField.setText("");
} else if (src == parent.buttonSquareRt) {
selectedAction = 's';
currentResult = displayValue;
parent.displayField.setText("");
} else if (src == parent.buttonPercentage){
selectedAction = 'p';
currentResult = displayValue;
parent.displayField.setText("");
} else if (src == parent.buttonPlusMinus){
selectedAction = 'm';
currentResult = displayValue;
parent.displayField.setText("");
}
else if (src == parent.buttonEqual) {
// Perform the calculations based on selectedAction
// update the value of the variable currentResult
// and display the result
if (selectedAction == '+') {
currentResult += displayValue;
// Convert the result to String by concatenating
// to an empty string and display it
parent.displayField.setText("" + currentResult);
} else if (selectedAction == '-') {
currentResult -= displayValue;
parent.displayField.setText("" + currentResult);
} else if (selectedAction == '/') {
currentResult /= displayValue;
parent.displayField.setText("" + currentResult);
} else if (selectedAction == '*') {
currentResult *= displayValue;
parent.displayField.setText("" + currentResult);
} else if (selectedAction == 's') {
currentResult = Math.sqrt(displayValue);
parent.displayField.setText("" + currentResult);
} else if (selectedAction == 'p') {
currentResult = currentResult / 100;
parent.displayField.setText("" + currentResult);
} else if (selectedAction == 'm') {
displayValue = currentResult * -1;
parent.displayField.setText("" + currentResult);
}
} else {
// For all numeric buttons append the button's
// label to the text field
String clickedButtonLabel = clickedButton.getText();
parent.displayField.setText(dispFieldText + clickedButtonLabel);
}
}
}
It appears that this code would work as expected where you would type a number like 64, then you would press the square root button - which would clear the displayField - then you would press the equals button, and it would display the result.
If you want to make it more obvious that you should be pressing the equals button to get the result, you might want to echo the users entry surrounded by text that represents the function to be performed, for example:
else if (src == parent.buttonSquareRt) {
selectedAction = 's';
currentResult = displayValue;
parent.displayField.setText("sqrt(" + currentResult + ")");
}

How to make "=" sign work on my java-calculator

I have been trying to create a (ugly) calculator and I am having problems with "=" sign. I know how to convert numbers (in string) to numbers (in int), but the problem here is mainly */-+. I have absolutely no idea what to do when they are added to the situation.
Here is a gif of the calculator: http://gyazo.com/98781eaaca0b3152967e6370cad3df15
package megetenkelkalkis;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
class Kalkulator extends JFrame{
private String textfield = "";
private String replace ="";
private JButton btn0 = new JButton("0");
private JButton btn1 = new JButton("1");
private JButton btn2 = new JButton("2");
private JButton btn3 = new JButton("3");
private JButton btn4 = new JButton("4");
private JButton btn5 = new JButton("5");
private JButton btn6 = new JButton("6");
private JButton btn7 = new JButton("7");
private JButton btn8 = new JButton("8");
private JButton btn9 = new JButton("9");
private JButton btnlik = new JButton("=");
private JButton btngange = new JButton("*");
private JButton btndele = new JButton("/");
private JButton btnpluss = new JButton("+");
private JButton btnminus = new JButton("-");
private JTextField tekst = new JTextField();
private JButton btndel= new JButton("DEL");
JPanel p = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
public Kalkulator(String tittel){
tekst.setPreferredSize(new Dimension(310,25));
setTitle(tittel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.add(btn0);
p.add(btn1);
p.add(btn2);
p.add(btn3);
p.add(btn4);
p.add(btn5);
p.add(btnlik);
p2.add(btn6);
p2.add(btn7);
p2.add(btn8);
p2.add(btn9);
p2.add(btndele);
p2.add(btngange);
p2.add(btnpluss);
p2.add(btnminus);
p3.add(tekst);
p3.add(btndel);
add(p, BorderLayout.SOUTH);
add(p2, BorderLayout.CENTER);
add(p3, BorderLayout.NORTH);
pack();
Knappelytter knappelytteren = new Knappelytter();
btn0.addActionListener(knappelytteren);
btn1.addActionListener(knappelytteren);
btn2.addActionListener(knappelytteren);
btn3.addActionListener(knappelytteren);
btn4.addActionListener(knappelytteren);
btn5.addActionListener(knappelytteren);
btn6.addActionListener(knappelytteren);
btn7.addActionListener(knappelytteren);
btn8.addActionListener(knappelytteren);
btn9.addActionListener(knappelytteren);
btnlik.addActionListener(knappelytteren);
btndele.addActionListener(knappelytteren);
btngange.addActionListener(knappelytteren);
btnminus.addActionListener(knappelytteren);
btnpluss.addActionListener(knappelytteren);
btndel.addActionListener(knappelytteren);
}
class Knappelytter implements ActionListener{
public void actionPerformed (ActionEvent hendelse){
JButton valgtKnapp = (JButton) hendelse.getSource();
String knapp = valgtKnapp.getText();
if (knapp.equals("0")){
textfield += "0";
tekst.setText(textfield);
}else if(knapp.equals("1")){
textfield += "1";
tekst.setText(textfield);
}else if(knapp.equals("2")){
textfield += "2";
tekst.setText(textfield);
}else if(knapp.equals("3")){
textfield += "3";
tekst.setText(textfield);
}else if(knapp.equals("4")){
textfield += "4";
tekst.setText(textfield);
}else if(knapp.equals("5")){
textfield += "5";
tekst.setText(textfield);
}else if(knapp.equals("6")){
textfield += "6";
tekst.setText(textfield);
}else if(knapp.equals("7")){
textfield += "7";
tekst.setText(textfield);
}else if(knapp.equals("8")){
textfield += "8";
tekst.setText(textfield);
}else if(knapp.equals("9")){
textfield += "9";
tekst.setText(textfield);
}else if(knapp.equals("*")){
textfield += "*";
tekst.setText(textfield);
}else if(knapp.equals("/")){
textfield += "/";
tekst.setText(textfield);
}else if(knapp.equals("-")){
textfield += "-";
tekst.setText(textfield);
}else if(knapp.equals("+")){
textfield += "+";
tekst.setText(textfield);
}else if(knapp.equals("DEL")){
tekst.setText(" ");
textfield = " ";
}else if(knapp.equals("=")){
else if(knapp.equals("=")){
/EDIT RIGHT HERE
String[] parts = textfield.split("-*/+");
for (int i = 0; i < textfield.length(); i++){
if (textfield.charAt(i) == ('-')){
String one = parts[0];
String two = parts[1];
int one1 = Integer.parseInt(one);
int one2 = Integer.parseInt(two);
int one3 = one1-one2;
String one4 = String.valueOf(one3);
tekst.setText(one4);
}
}
}
}
public class MegetEnkelKalkis {
public static void main(String[] args) {
Kalkulator Skole = new Kalkulator("Kalkulator");
Skole.setVisible(true);
}
}
Get the Input
Seperate it from the Operands ( *, /, -, + )
Cast the strings to int's ( Integer.valueOf() throws a NumberFormatException)
Do a if else for the operands and then multiply, divide, add or substract the ints
What you need is a string calculator. You basically parse the contents of textfield following the regular maths rules. It is a bit of work but not too hard.
Basically just follow this:
Recursion might be quite suitable for that, so build a function that takes a string and returns the result as an int.
Search for all occurrences of a parameter (e.g. ) starting with the highest priority ones ( and /)
If you encounter that parameter split the string there into two halves (left of the parameter and right of the parameter)
Recursively follow the same rules with the left and right part of the string.
If the String only contains one number, parse that number using Integer.parseInt() and return it.
Calculate the result of left operator right, so e.g. left * right, if the operator is *
Return the result of the calculation.
Or you calculate via nashorn (javascript) engine ;)
private ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
double result = (double) scriptEngine.eval(formula)
You should build a reverse polish notation, which is the easiest way to parse and evaluate methmatical formulas. there are plenty of examples how to do that in Java on the web.
There are anumber of ways to do this, but recommendation is that you create two doubles. When the user clicks +,-,\ or * parse the number before it into a double. Thenwhen they press = parse everything between + and = into a double, then perform the calculation using those two doubles and output the result. You can set a flag to determine which operation to perform. for example the + button could set a boolean called Plus = true; Then when you perform the operation check which bools are true. IF more or less than one, tell the user the input was invalid, otherwise perform the operation
There is definitely lot of scope of improvement in the code, as suggested by others, but if you want to keep it as it is and working, then here is the code:
.
.
.
}else if(knapp.equals("=")){
String nytekst = textfield;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
try {
Double result = (Double) engine.eval(nytekst);
System.out.println(result);
tekst.setText(result.toString());
} catch (ScriptException e) {
e.printStackTrace();
}
}
.
.
.

Retrieving a double from a JTextArea while solving for X

Ok, I'm kinda new to java. I'm making a program that solves for one step equations. I'm having some difficulties running it though. Here is the code for my main file, Main.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
Solve solve = new Solve();
JButton add = new JButton("Add");
JButton sub = new JButton("Subtract");
JButton mult = new JButton("Multiply");
JButton div = new JButton("Divide");
JButton solv = new JButton("Solve!");
JTextArea one = new JTextArea();
JLabel two = new JLabel(" = ");
JLabel three = new JLabel("X");
JLabel four = new JLabel();
JTextArea five = new JTextArea();
JLabel solved = new JLabel();
JPanel row1 = new JPanel();
JPanel row2 = new JPanel();
JPanel row3 = new JPanel();
public double funct;
public Main() {
super("Solving a one step equation!");
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
GridLayout layout = new GridLayout();
setLayout(layout);
FlowLayout layout1 = new FlowLayout(FlowLayout.CENTER);
row1.setLayout(layout1);
row1.add(add);
row1.add(sub);
row1.add(mult);
row1.add(div);
row1.add(solv);
add(row1);
add.addActionListener(this);
sub.addActionListener(this);
mult.addActionListener(this);
div.addActionListener(this);
solv.addActionListener(this);
GridLayout layout2 = new GridLayout(1, 1, 1, 1);
row2.setLayout(layout2);
row2.add(one, BorderLayout.CENTER);
row2.add(two, BorderLayout.CENTER);
row2.add(three, BorderLayout.CENTER);
row2.add(four, BorderLayout.CENTER);
row2.add(five);
add(row2, BorderLayout.CENTER);
GridLayout layout3 = new GridLayout(5, 5, 5, 5);
row3.setLayout(layout3);
row3.add(solved);
add(row3);
}
public static void main(String[] args) {
Main frame = new Main();
}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if(source == add)
{
four.setText(" + ");
funct = 1;
}
else if(source == sub)
{
four.setText(" - ");
funct = 2;
}
else if(source == mult)
{
four.setText(" * ");
funct = 3;
}
else if(source == div)
{
four.setText(" / ");
funct = 4;
}
if(source == solv)
{
if(funct == 1)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Add(Ones, Twos));
}
else if(funct == 2)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Sub(Ones, Twos));
}
else if(funct == 3)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Mult(Ones, Twos));
}
else if(funct == 4)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Div(Ones, Twos));
}
}
}
}
Here is the code for my other file, Solve.java
public class Solve {
public double Add(double One, double Two)
{
return One - Two;
}
public double Sub(double One, double Two)
{
return One + Two;
}
public double Mult(double One, double Two)
{
return One / Two;
}
public double Div(double One, double Two)
{
return One * Two;
}
}
Some help would be appreciated. Anyone see what I'm doing wrong?
You get a NumberFormatException once 'Solve' button is clicked. It seems like a copy/paste issue - you are not retrieving the correct numbers. You are trying to convert 'X' string to double. It is best if you give meaningful names to your variables. To fix the exception, try this, replace :
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
with:
double Ones = Double.parseDouble(one.getText());
double Twos = Double.parseDouble(five.getText());
Get familiar with Java Code Conventions, Naming Conventions section in particular.
In addition to #Max's helpful answer, here are a few other suggestions:
Setting the frame's layout to new GridLayout() defaults to a single row and column with no padding. As an alternative, consider new GridLayout(0, 1, 5, 5), which produces any number of rows in one column with 5x5 padding. Then you can focus on the layout of each row:
row1.setLayout(new FlowLayout(FlowLayout.CENTER));
row2.setLayout(new FlowLayout(FlowLayout.CENTER));
row3.setLayout(new GridLayout(1, 1, 5, 5));
Move your setVisible() call to the end of the frame's constructor:
pack();
setLocationRelativeTo(null);
setVisible(true);
Consider getRootPane().setDefaultButton(solv) to make the Solve button the default.
Consider making addition the default:
private JLabel four = new JLabel("+");
private int funct = 1; // add by default
Consider using JTextField for number entry:
private JTextField one = new JTextField(10);
private JTextField five = new JTextField(10);

Programming a calculator that performs the operations in the DMAS order

I have created a GUI calculator program, that performs calculations in a linear order, but i want it to perform calculations in an order of "Divide, multiply, add, subtract".
I'm a beginner, so please suggest me if there is any other simpler way to implement the same thing, which I have coded.
Please help me with the 'DMAS' thing.
My code:
public class keypadGUI extends JFrame{
private JTextField lcd;
private JButton n1,n2,n3,n4,n5,n6,n7,n8,n9,n0;
private JButton plus,minus,multiply,divide,equalTo,dot;
//private JButton[] buttons = new JButton[10];
//private JButton[] opButtons = new JButton[6];
private double ans = 0; //For storing final ans
char[] op; //Character array for stroing operators
private double[] nums; //For storing the numbers
public JPanel keypad;
private StringBuilder sb = new StringBuilder(); //For storing the input of the user as string
public keypadGUI(){
setLayout(new BorderLayout(10,10));
lcd = new JTextField();
lcd.setEditable(false);
Border low = BorderFactory.createLoweredSoftBevelBorder();
lcd.setBorder(low);
lcd.setHorizontalAlignment(JTextField.RIGHT);
lcd.setFont(new Font("Serif",Font.BOLD,30));
lcd.setText("0");
Font numFont = new Font("Serif",Font.BOLD,20);
n1 = new JButton("1"); n2 = new JButton("2"); n3 = new JButton("3"); n4 = new JButton("4");
n5 = new JButton("5"); n6 = new JButton("6"); n7 = new JButton("7"); n8 = new JButton("8");
n9 = new JButton("9"); n0 = new JButton("0"); dot = new JButton(".");
plus = new JButton("+");
minus = new JButton("-");
multiply = new JButton("*");
divide = new JButton("/");
equalTo = new JButton("=");
n1.setFont(numFont); n2.setFont(numFont); n3.setFont(numFont); n4.setFont(numFont);
n5.setFont(numFont); n6.setFont(numFont); n7.setFont(numFont); n8.setFont(numFont);
n9.setFont(numFont); n0.setFont(numFont); dot.setFont(numFont); plus.setFont(numFont);
minus.setFont(numFont); multiply.setFont(numFont); divide.setFont(numFont); equalTo.setFont(numFont);
plus.setForeground(Color.DARK_GRAY); minus.setForeground(Color.DARK_GRAY); multiply.setForeground(Color.DARK_GRAY);
divide.setForeground(Color.DARK_GRAY); equalTo.setForeground(Color.DARK_GRAY);
listen listener = new listen();
n1.addActionListener(listener); n2.addActionListener(listener); n3.addActionListener(listener); n4.addActionListener(listener);
n5.addActionListener(listener); n6.addActionListener(listener); n7.addActionListener(listener); n8.addActionListener(listener);
n9.addActionListener(listener); n0.addActionListener(listener); plus.addActionListener(listener); minus.addActionListener(listener);
multiply.addActionListener(listener); divide.addActionListener(listener);
equalTo.addActionListener(new equalListener());
keypad = new JPanel(new GridLayout(4,4,10,10));
keypad.add(n7); keypad.add(n8); keypad.add(n9); keypad.add(divide);
keypad.add(n4); keypad.add(n5); keypad.add(n6); keypad.add(multiply);
keypad.add(n1); keypad.add(n2); keypad.add(n3); keypad.add(plus);
keypad.add(n0); keypad.add(dot); keypad.add(equalTo); keypad.add(minus);
add(lcd,BorderLayout.NORTH);
add(keypad,BorderLayout.CENTER);
setVisible(true);
setLookAndFeel();
setSize(280,280);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("MY Calc");
}
private void setLookAndFeel(){
try{
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}catch(Exception ae){}
}
private class listen implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
String bName = ((JButton)e.getSource()).getText();
sb.append(bName);
lcd.setText(sb.toString());
}
}
private class equalListener implements ActionListener{
public void actionPerformed(ActionEvent e){
String[] tokkens = sb.toString().split("-|\\+|\\*|\\/");
nums = new double[tokkens.length];
for(int i=0;i<nums.length;i++){
nums[i] = Double.parseDouble(tokkens[i]);
}
op = new char[10];
op[0]='+';
int c =1;
for(int i=0;i<sb.length();i++){
if(sb.charAt(i)=='+' || sb.charAt(i)=='-' || sb.charAt(i)=='*' || sb.charAt(i)=='/')
{ op[c]=sb.charAt(i); c++; }
}
performOP();
sb = sb.delete(0, sb.length());
sb.append(ans);
lcd.setText(sb.toString());
System.out.println(op);
System.out.println(Arrays.toString(tokkens));
}
}
private void performOP(){
for(int i=0;i<nums.length;i++){
switch(op[i]){
case '+':
ans = ans + nums[i];
break;
case '-':
ans = ans - nums[i];
break;
case '*':
ans = ans * nums[i];
break;
case '/':
ans = ans / nums[i];
break;
default:
System.out.println("INVALID CASE !!!");
}
}
}
}
You currently have a linear approach to understanding the expression, you build a list of operators and execute them in order.
You need to build something more like a tree so that you can give your desired meaning to
3 + 4 * 5
and you probably want to allow parentheses too
2 + ( 3 * 4) + ( 5 * ( 6 + 7 ) )
This is a very common parsing problem, generally known as recursive descent parsing. You will be able to find libraries that implement such parsers. For example ANTLR. It's quite a big jump from where you are to this sort of stuff. If you dig around you'll probably find simple implementations you can clone, but if you really want to understand the area then you'd need to study quite a bit: articles such as this may help.
Umm , how about if you just store all the characters that you take as operands and operators in a linked list. Store all the operators in an array, according to their precedence. Such as, arr[]={'/','*','+','-'}, iterate through these operators. While you are doing that detect any of the operation that needs to be applied first , store its answer in a new node, then delete those nodes containing the detected operations and operands.Link the new node to the node after the last operand upon which operation was being performed upon. You can repeat this process, until the base or head node's next pointer becomes zero.And yeah honestly, iam also kind of a beginner to this matter,so this solution is obviously not great. I also kind of thought this just right now and ofcourse havenot implemented this idea myself. But yeah , you can give it a shot, if you want to though.Hope it helps, even if just a bit.

Categories