patternjavaMinor
Basic Java Swing Calculator
Viewed 0 times
javaswingcalculatorbasic
Problem
I am new to Java Swing and have decided to create a calculator to learn some of the basic. I would like someone to look over my code to see if they can give me any improvements.
I have 6 classes and 2 interfaces. I have chosen to split the communication of both operators and digits. The mainframe is the controller and actually creates the objects. The other classes are the different components.
```
package calculator;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptEngine;
public class MainFrame extends JFrame {
private FormArea formpanel;
private OutputArea outputText;
private WorkoutExpression workingOutMathExpression;
private static String mathmaticalExpression = "";
public MainFrame() {
super("Calculator");
setVisible(true);
setSize(800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
formpanel = new FormArea();
outputText = new OutputArea();
workingOutMathExpression = new WorkoutExpression();
setLayout(new BorderLayout());
formpanel.setStringListener(new DigitListener() {
public void StringEmmiter(String text) {
outputText.addText(text);
mathmaticalExpression = mathmaticalExpression + text;
//System.out.println(mathmaticalExpression);
WorkoutExpression.setMathExpression(mathmaticalExpression);
}
});
formpanel.setOperatorListener(new MathOperatorListener() {
public void OperatorEmitter(String text2a) {
if (text2a.equals("CLEAR")) {
outputText.refreshTextArea();
mathmaticalExpression = "";
workingOutMathExpression.resetMathExpression();
} else if (text2a.equals("CLEAR") == false) {
outputT
I have 6 classes and 2 interfaces. I have chosen to split the communication of both operators and digits. The mainframe is the controller and actually creates the objects. The other classes are the different components.
MainFrame (creates all objects):```
package calculator;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptEngine;
public class MainFrame extends JFrame {
private FormArea formpanel;
private OutputArea outputText;
private WorkoutExpression workingOutMathExpression;
private static String mathmaticalExpression = "";
public MainFrame() {
super("Calculator");
setVisible(true);
setSize(800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
formpanel = new FormArea();
outputText = new OutputArea();
workingOutMathExpression = new WorkoutExpression();
setLayout(new BorderLayout());
formpanel.setStringListener(new DigitListener() {
public void StringEmmiter(String text) {
outputText.addText(text);
mathmaticalExpression = mathmaticalExpression + text;
//System.out.println(mathmaticalExpression);
WorkoutExpression.setMathExpression(mathmaticalExpression);
}
});
formpanel.setOperatorListener(new MathOperatorListener() {
public void OperatorEmitter(String text2a) {
if (text2a.equals("CLEAR")) {
outputText.refreshTextArea();
mathmaticalExpression = "";
workingOutMathExpression.resetMathExpression();
} else if (text2a.equals("CLEAR") == false) {
outputT
Solution
Use Arrays
At a glance, your creating and instantiating the
e.g.
It would allow you to use a simple loop to instantiate, and add the ActionListener, e.g.
Employ Lambda Expressions
If you have access to Java 8, You can use lambda expressions to simply the code where you use Functional Interfaces, e.g.
instead of:
You can simply write:
I also use
Read up on what I linked, but just as an additional example, your
Can be replaced with:
The e is just a variable used to refer to the text2a that is passed. You can name it anything. Same deal of course for your
At a glance, your creating and instantiating the
ButtonTemplate objects could be done as an array.e.g.
private ButtonTemplate[] buttons = new ButtonTemplate[10];It would allow you to use a simple loop to instantiate, and add the ActionListener, e.g.
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new ButtonTemplate(Integer.toString(i));
buttons[i].addActionListener(this);
}Employ Lambda Expressions
If you have access to Java 8, You can use lambda expressions to simply the code where you use Functional Interfaces, e.g.
instead of:
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ButtonTemplate source1 = (ButtonTemplate) e.getSource();
if (source1 == btn) {
operatorListener.OperatorEmitter(btn.getText());
}
}
});You can simply write:
btn.addActionListener(e -> {
if ((ButtonTemplate)e.getSource() == btn) {
operatorListener.OperatorEmitter(btn.getText());
}
});I also use
e.getSource() directly here rather than storing it as a variable since we're only doing one thing with it anyway, but feel free to use it your way if you find it makes it more understandable/readable.Read up on what I linked, but just as an additional example, your
MathOperatorListener is a functional interface. So this section where you call setOperatorListener formpanel.setOperatorListener(new MathOperatorListener() {
public void OperatorEmitter(String text2a) {Can be replaced with:
formpanel.setOperatorListener(e -> {
// content
});The e is just a variable used to refer to the text2a that is passed. You can name it anything. Same deal of course for your
DigitListener interface. You may start using the @FunctionalInterface annotation so the compiler would check and confirm for you, albeit Functional Interfaces are easily identifiable since they only have a single method).Code Snippets
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new ButtonTemplate(Integer.toString(i));
buttons[i].addActionListener(this);
}btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ButtonTemplate source1 = (ButtonTemplate) e.getSource();
if (source1 == btn) {
operatorListener.OperatorEmitter(btn.getText());
}
}
});btn.addActionListener(e -> {
if ((ButtonTemplate)e.getSource() == btn) {
operatorListener.OperatorEmitter(btn.getText());
}
});formpanel.setOperatorListener(new MathOperatorListener() {
public void OperatorEmitter(String text2a) {formpanel.setOperatorListener(e -> {
// content
});Context
StackExchange Code Review Q#102059, answer score: 3
Revisions (0)
No revisions yet.