Reputation: 33
before I jump into my issue I want to note, that actually I do not mainly need help with coding, I have just been thinking about the problem for several days, so maybe this is not exactly a programming-based question.
After approximately 2 years of absence from programming, I decided to refresh my knowledge some days ago. I wrote a swing-based GUI for a calculator and was able to create a working calculator for the operations +,* but only for single digit numbers. You can see the code below.
My question now is, does anyone of you know an algorithm that can be used to use the same GUI as i have for equations with numbers with more digits?
Writing the code should not be a problem, but unfortunately I am not able to figure out something useful.
I am hoping for creative solutions and even if it is just a basic idea, I would gladly join its further development :)
Max
Code:
Main.java:
public class Main {
public static void main(String[] args) {
new CalculatorController();
}
}
CalculatorController.java:
public class CalculatorController {
private CalculatorView view;
private NumberAction nmbAction;
private OperatorAction opAction;
private CalcObject currentValue, savedValue;
CalculatorController() {
currentValue = new CalcObject();
savedValue = new CalcObject();
nmbAction = new NumberAction(this);
opAction = new OperatorAction(this);
view = new CalculatorView(this);
view.setSize(250, 220);
view.setVisible(true);
}
public void printResult(double result) {
view.getCALCULATION().setText(String.valueOf(result));
}
public CalculatorView getView() {
return view;
}
public NumberAction getNmbAction() {
return nmbAction;
}
public OperatorAction getOpAction() {
return opAction;
}
public CalcObject getCurrentValue() {
return currentValue;
}
public CalcObject getSavedValue() {
return savedValue;
}
public void setCurrentValue(CalcObject currentValue) {
String str = currentValue.getOperator();
this.currentValue.setOperator(str);
this.currentValue.setNumber(currentValue.getNumber());
}
public void setSavedValue(CalcObject stripeValue) {
String str = stripeValue.getOperator();
this.savedValue.setOperator(str);
this.savedValue.setNumber(stripeValue.getNumber());
}
}
CalculatorView.java:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class CalculatorView extends JFrame {
private String equation = "";
private CalcObject object = new CalcObject();
private JPanel pane;
private JPanel contentPane;
private JTextField CALCULATION;
private JButton NMB_0;
private JButton NMB_1;
private JButton NMB_2;
private JButton NMB_3;
private JButton NMB_4;
private JButton NMB_5;
private JButton NMB_6;
private JButton NMB_7;
private JButton NMB_8;
private JButton NMB_9;
private JButton CALC;
private JButton MULTIPLY;
private JButton DIVIDE;
private JButton ADD;
private JButton SUBTRACT;
public CalculatorView(CalculatorController controller) {
setDefaultCloseOperation(CalculatorView.EXIT_ON_CLOSE);
pane = new JPanel(new FlowLayout());
setContentPane(pane);
CALCULATION = new JTextField();
CALCULATION.setColumns(16);
pane.add(CALCULATION);
contentPane = new JPanel(new GridLayout(0, 3));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
pane.add(contentPane);
NMB_1 = new JButton(controller.getNmbAction());
NMB_1.setText("1");
contentPane.add(NMB_1);
NMB_2 = new JButton(controller.getNmbAction());
NMB_2.setText("2");
contentPane.add(NMB_2);
NMB_3 = new JButton(controller.getNmbAction());
NMB_3.setText("3");
contentPane.add(NMB_3);
NMB_4 = new JButton(controller.getNmbAction());
NMB_4.setText("4");
contentPane.add(NMB_4);
NMB_5 = new JButton(controller.getNmbAction());
NMB_5.setText("5");
contentPane.add(NMB_5);
NMB_6 = new JButton(controller.getNmbAction());
NMB_6.setText("6");
contentPane.add(NMB_6);
NMB_7 = new JButton(controller.getNmbAction());
NMB_7.setText("7");
contentPane.add(NMB_7);
NMB_8 = new JButton(controller.getNmbAction());
NMB_8.setText("8");
contentPane.add(NMB_8);
NMB_9 = new JButton(controller.getNmbAction());
NMB_9.setText("9");
contentPane.add(NMB_9);
MULTIPLY = new JButton(controller.getOpAction());
MULTIPLY.setText("*");
contentPane.add(MULTIPLY);
NMB_0 = new JButton(controller.getNmbAction());
NMB_0.setText("0");
contentPane.add(NMB_0);
DIVIDE = new JButton(controller.getOpAction());
DIVIDE.setText("/");
contentPane.add(DIVIDE);
DIVIDE.setEnabled(false);
ADD = new JButton(controller.getOpAction());
ADD.setText("+");
contentPane.add(ADD);
CALC = new JButton(controller.getOpAction());
CALC.setText("=");
contentPane.add(CALC);
SUBTRACT = new JButton(controller.getOpAction());
SUBTRACT.setText("-");
contentPane.add(SUBTRACT);
SUBTRACT.setEnabled(false);
}
public String getEquation() { return equation; }
public void setEquation(String equation) { this.equation = equation; }
public JTextField getCALCULATION() {
return CALCULATION;
}
}
OperatorAction.java:
import javax.swing.*;
import java.awt.event.ActionEvent;
public class OperatorAction extends AbstractAction {
private String operator;
private CalculatorController controller;
OperatorAction(CalculatorController controller) {
this.controller = controller;
this.operator = "";
}
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
this.operator = button.getText();
controller.getView().setEquation(controller.getView().getEquation().concat(this.operator));
controller.getView().getCALCULATION().setText(controller.getView().getEquation());
controller.getCurrentValue().setOperator(operator);
if (controller.getCurrentValue().getOperator() == "=") {
if (controller.getSavedValue().getOperator() == "+") {
controller.printResult(Double.parseDouble(controller.getSavedValue().getNumber()) + Double.parseDouble(controller.getCurrentValue().getNumber()));
} else {
controller.printResult(Double.parseDouble(controller.getCurrentValue().getNumber()));
}
controller.getView().setEquation("");
controller.getCurrentValue().setNumber("0");
controller.getSavedValue().setNumber("0");
controller.getCurrentValue().setOperator("");
controller.getSavedValue().setOperator("");
}
}
}
NumberAction.java:
import javax.swing.*;
import java.awt.event.ActionEvent;
public class NumberAction extends AbstractAction {
private String number;
private CalculatorController controller;
NumberAction(CalculatorController controller) {
this.controller = controller;
this.number = "";
}
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
this.number = button.getText();
controller.getView().setEquation(controller.getView().getEquation().concat(this.number));
controller.getView().getCALCULATION().setText(controller.getView().getEquation());
if (controller.getSavedValue().getOperator() == "") {
if (controller.getCurrentValue().getOperator() == "") {
controller.getCurrentValue().setNumber(number);
}
if (controller.getCurrentValue().getOperator() == "*") {
controller.getCurrentValue().setNumber(String.valueOf(Double.parseDouble( controller.getCurrentValue().getNumber()) * Double.parseDouble(number)));
controller.setSavedValue(controller.getCurrentValue());
}
if (controller.getCurrentValue().getOperator() == "+") {
controller.setSavedValue(controller.getCurrentValue());
controller.getCurrentValue().setNumber(number);
}
} else {
if (controller.getCurrentValue().getOperator() == "*") {
controller.getCurrentValue().setNumber(String.valueOf(Double.parseDouble( controller.getCurrentValue().getNumber()) * Double.parseDouble(number)));
}
if (controller.getCurrentValue().getOperator() == "+") {
controller.getCurrentValue().setNumber(String.valueOf(Double.parseDouble(controller.getSavedValue().getNumber()) + Double.parseDouble(controller.getCurrentValue().getNumber()) + Double.parseDouble(number)));
controller.getSavedValue().setOperator("");
}
}
}
}
CalcObject.java:
public class CalcObject {
private String NUMBER;
private String OPERATOR;
CalcObject() {
NUMBER = "0";
OPERATOR = "";
}
CalcObject(String number, String operator) {
NUMBER = number;
OPERATOR = operator;
}
public void setNumber(String number) { NUMBER = number; }
public void setOperator(String operator) { OPERATOR = operator; }
public String getNumber() { return NUMBER; }
public String getOperator() { return OPERATOR; }
}
Well, while checking the program again I found out, that this algorithm for single digit number neither works properly, but my question remains the same. I would also be happy about some opinions or ideas to make it easier or smoother or in whatever way better.
Upvotes: 0
Views: 4581
Reputation: 4667
For the multidigit numbers, you should use a string, so that when the user clicks on a digit, that digit is appended to string. With JTextField, you can combine typing with clicking on digit buttons.
For the simple case, you can convert the string into a number and store it as "previous value" when the user clicks +-*/. You also need a field to store the operation. On the second operation (or "="), you'd then use the previous value, stored opration and current value to calculate the result.
On a more advanced level, you can add buttons for parentheses. Instead of a single previous number, you'd then use a stack of previous numbers to push and pop them when entering/exiting a parenthesis.
On an expert level, you can use a parser and a grammar. With that, you'll have your own programming language. You'll learn a lot, and you'll be able to calculate any valid expression from the input string. See here for example.
Upvotes: 0
Reputation: 88707
Another suggestion: if might be easier to create a calculator that parses and evaluates a string. There are plenty of examples on this on the net so this should be an interesting and not too hard task, especially since you're trying to improve your programming skills (you could even implement and provide several parsers to play around with).
The UI would then have the simple task of creating the string, i.e. each button just adds one character to the current equation string and the =
button will then run the parser.
Upvotes: 1