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) {
outputText.addText(text2a);
if (text2a.equals("=")) {
try {
outputText.addText(workingOutMathExpression.getCalculationOfExpression());
} catch (ScriptException e) {
e.printStackTrace();
}
} else {
mathmaticalExpression = mathmaticalExpression + text2a;
//System.out.println(mathmaticalExpression);
WorkoutExpression.setMathExpression(mathmaticalExpression);
}
}
}
});
add(formpanel, BorderLayout.WEST);
add(outputText, BorderLayout.CENTER);
}
}
Formpanel is the panel which contains all the buttons:
package calculator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class FormArea extends JPanel implements ActionListener {
private ButtonTemplate No1;
private ButtonTemplate No2;
private ButtonTemplate No3;
private ButtonTemplate No4;
private ButtonTemplate No5;
private ButtonTemplate No6;
private ButtonTemplate No7;
private ButtonTemplate No8;
private ButtonTemplate No9;
private ButtonTemplate No0;
private ButtonTemplate addition;
private ButtonTemplate substraction;
private ButtonTemplate division;
private ButtonTemplate total;
private ButtonTemplate multiplication;
private JButton clearButton;
private ButtonTemplate decimalPoint;
private DigitListener digitListener;
private MathOperatorListener operatorListener;
public FormArea() {
// SetSize
setPreferredSize(new Dimension(300, 500));
// Create all Objects
No1 = new ButtonTemplate("1");
No2 = new ButtonTemplate("2");
No3 = new ButtonTemplate("3");
No4 = new ButtonTemplate("4");
No5 = new ButtonTemplate("5");
No6 = new ButtonTemplate("6");
No7 = new ButtonTemplate("7");
No8 = new ButtonTemplate("8");
No9 = new ButtonTemplate("9");
No0 = new ButtonTemplate("0");
addition = new ButtonTemplate("+");
substraction = new ButtonTemplate("-");
division = new ButtonTemplate("/");
total = new ButtonTemplate("=");
multiplication = new ButtonTemplate("*");
clearButton = new JButton("CLEAR");
decimalPoint = new ButtonTemplate(".");
clearButton.setPreferredSize(new Dimension(100, 60));
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
// Layout
// Column 1
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No1, gc);
gc.gridx = 0;
gc.gridy = 1;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No4, gc);
gc.gridx = 0;
gc.gridy = 2;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No7, gc);
// Column 2
gc.gridx = 1;
gc.gridy = 0;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No2, gc);
gc.gridx = 1;
gc.gridy = 1;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No5, gc);
gc.gridx = 1;
gc.gridy = 2;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No8, gc);
// Column3
gc.gridx = 2;
gc.gridy = 0;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No3, gc);
gc.gridx = 2;
gc.gridy = 1;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No6, gc);
gc.gridx = 2;
gc.gridy = 2;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No9, gc);
// Operators
gc.gridx = 0;
gc.gridy = 3;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(addition, gc);
gc.gridx = 1;
gc.gridy = 3;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(No0, gc);
gc.gridx = 2;
gc.gridy = 3;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(substraction, gc);
// Operator 2
gc.gridx = 0;
gc.gridy = 4;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(division, gc);
gc.gridx = 1;
gc.gridy = 4;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(multiplication, gc);
gc.gridx = 2;
gc.gridy = 4;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(total, gc);
gc.gridx = 1;
gc.gridy = 5;
gc.weightx = 0.1;
gc.weighty = 5;
add(clearButton, gc);
gc.gridx = 0;
gc.gridy = 5;
gc.weightx = 0.1;
gc.weighty = 0.1;
add(decimalPoint, gc);
// ActionButton
No1.addActionListener(this);
No2.addActionListener(this);
No3.addActionListener(this);
No4.addActionListener(this);
No5.addActionListener(this);
No6.addActionListener(this);
No7.addActionListener(this);
No8.addActionListener(this);
No9.addActionListener(this);
No0.addActionListener(this);
ArrayList<ButtonTemplate> operatorsArrayList =
new ArrayList<ButtonTemplate>(Arrays.asList(iterateThroughOperators()));
for (ButtonTemplate btn : operatorsArrayList) {
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ButtonTemplate source1 = (ButtonTemplate) e.getSource();
if (source1 == btn) {
operatorListener.OperatorEmitter(btn.getText());
}
}
});
}
clearButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton s1 = (JButton) e.getSource();
operatorListener.OperatorEmitter(s1.getText());
}
});
}
public void setStringListener(DigitListener digitlistener) {
this.digitListener = digitlistener;
}
public void setOperatorListener(MathOperatorListener operatorListener) {
this.operatorListener = operatorListener;
}
public ButtonTemplate[] iterateThroughButton() {
ButtonTemplate btn[] = { No1, No2, No3, No4, No5, No6, No7, No8, No9, No0 };
return btn;
}
public ButtonTemplate[] iterateThroughOperators() {
ButtonTemplate operatorBtn[] = { addition, substraction, division, total, multiplication,decimalPoint
};
return operatorBtn;
}
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
for (ButtonTemplate SingleButton : iterateThroughButton()) {
if (source == SingleButton) {
digitListener.StringEmmiter(SingleButton.getText());
}
}
}
}
Button Template is just a standard button with a specified size:
package calculator;
import java.awt.Dimension;
import javax.swing.JButton;
public class ButtonTemplate extends JButton{
private String nameOfTheButton;
public ButtonTemplate(String nameOfButton){
this.nameOfTheButton = nameOfButton;
this.setText(nameOfTheButton);
this.setPreferredSize(new Dimension(70,50));
}
}
DigitListener
listens for the digits and sends them to the mainframe:
package calculator;
public interface DigitListener {
public void StringEmmiter(String text1);
}
Operator listener listens to the operators and sends them to the mainframe:
package calculator;
public interface MathOperatorListener {
public void OperatorEmitter(String text2);
}
MathExpression
works out the mathematical expression using scriptengine:
package calculator;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptEngine;
public class WorkoutExpression {
private static String mathExpression;
public static void setMathExpression(String mathExpression) {
WorkoutExpression.mathExpression = mathExpression;
}
public String getCalculationOfExpression() throws ScriptException{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
return engine.eval(mathExpression).toString();
}
public void resetMathExpression(){
mathExpression = "0";
}
}
Output area is whether the calculation is displayed:
package calculator;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class OutputArea extends JPanel {
private JTextArea textarea;
public OutputArea() {
textarea = new JTextArea();
setLayout(new BorderLayout());
add(new JScrollPane(textarea));
}
public void addText(String text){
textarea.append(text);
}
public void refreshTextArea(){
textarea.setText(null);
}
}