HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Basic Java Swing Calculator

Submitted by: @import:stackexchange-codereview··
0
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.

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 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.