Creating a Scientific Calculator in Java from Scratch

Himani Bansal
Wiki Flood
Published in
7 min readJun 29, 2024

Let’s make a Scientific Calculator in Java using Swing and event-driven programming.

About Java Scientific Calculator

Scientific Calculators are computing tools that we use in everyday life. They help us compute complex mathematical functions and basic arithmetic operations, solving problems requiring high-level math.

Our Java Scientific Calculator, with the help of a Graphical User Interface using Swing and event-driven programming, contains

1. Basic arithmetic operations: addition, subtraction, multiplication, and division.

2. Scientific functions: sine, cosine, tangent, logarithm, square root, exponentiation, and factorial.

3. Memory functions: memory clear (MC), memory recall (MR), memory addition (M+), and memory subtraction (M-).

Prerequisites for Java Scientific Calculator Project

You should know certain concepts before proceeding forward so that you can completely understand them. The Prerequisites are:

  • IDE Used: Visual Studio Code (you can use any IDE)
  • Java should be properly installed on the machine.
  • Your Concepts of Java should be clear.
  • Java provides by default packages such as Abstract Window Toolkit (AWT) & Swing packages to create graphical user interface (GUI) for our calculator.
  • Understanding of Event-Driven Programming
Java Scientific Calculator Project

Steps to Build Java Scientific Calculator Project

1. First we import the libraries which we need

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

Explanation:

  • The Swing package helps us build graphical user interfaces (GUIs) in Java. It provides us with components like buttons, frames, etc., which are important in this Java project.
  • The Abstract Window Toolkit (AWT) package contains all of the classes for creating user interfaces and for painting graphics and images. It will help us with more fundamental things like Font, Dimension, GridLayout etc.
  • ActionEvent and ActionListener are used so that when a user interacts with a GUI component, it can be handled.

2. Defining the class

public class Calculator extends JFrame implements ActionListener {
static JFrame frame;
static JTextField field;
String str, str1, str2;

Calculator() {
str = str1 = str2 = "";
}

public static void main(String args[]) {
frame = new JFrame("Flood Calculator");

Calculator c = new Calculator();
field = new JTextField(16);
field.setEditable(false);
field.setFont(new Font("Arial", Font.BOLD, 24));
field.setHorizontalAlignment(JTextField.RIGHT);
field.setPreferredSize(new Dimension(300, 50));

Explanation:

  • Define a public class as Calculator, which inherits JFrame methods and implements the ActionListener interface to handle user action.
  • We define static fields next which hold references to JFrame and JTextField and instance fields str, str1, str2 to store input as strings.
  • Calculator() is a constructor which initializes the instance fields to empty strings.
  • Next main method is defined, which is the entry point of the program and a new JFrame is created.
  • Create an object for calculator class.
  • Now it’s time to work on the display of our Calculator. We initialize a new TextField, which can display approximately 16 characters, and make it non-editable so that users can not modify the display.
  • With the help of setFont(), we make the display more presentable.
  • JTextField.RIGHT is used so that output displays on the right side of the displayand setPreferredSize() is used to set the size of TextField.

3. Initialize User Interface

We create the user interface (UI) of the project; for that, we use panels, buttons, labels, etc and handle user interaction.

JButton b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bs, bd, bm, be, bc, beq,
bsq, bexp, bfac, blog, bsin, bcos, btan, binv, bMC, bMR, bm1, bm2;

b0 = new JButton("0");
b1 = new JButton("1");
b2 = new JButton("2");
b3 = new JButton("3");
b4 = new JButton("4");
b5 = new JButton("5");
b6 = new JButton("6");
b7 = new JButton("7");
b8 = new JButton("8");
b9 = new JButton("9");

beq = new JButton("=");
ba = new JButton("+");
bs = new JButton("-");
bd = new JButton("/");
bm = new JButton("*");
bc = new JButton("C");
be = new JButton(".");
bsq = new JButton("√");
binv = new JButton("1/x");
bfac = new JButton("!");
blog = new JButton("Log");
bsin = new JButton("Sin");
bcos = new JButton("cos");
btan = new JButton("Tan");
bexp = new JButton("Exp");

bMC = new JButton("MC");
bMR = new JButton("MR");
bm1 = new JButton("M+");
bm2 = new JButton("M-");

Font buttonFont = new Font("Arial", Font.PLAIN, 18);
b0.setFont(buttonFont);
b1.setFont(buttonFont);
b2.setFont(buttonFont);
b3.setFont(buttonFont);
b4.setFont(buttonFont);
b5.setFont(buttonFont);
b6.setFont(buttonFont);
b7.setFont(buttonFont);
b8.setFont(buttonFont);
b9.setFont(buttonFont);

beq.setFont(buttonFont);
ba.setFont(buttonFont);
bs.setFont(buttonFont);
bd.setFont(buttonFont);
bm.setFont(buttonFont);
bc.setFont(buttonFont);
be.setFont(buttonFont);
bfac.setFont(buttonFont);
bsq.setFont(buttonFont);
binv.setFont(buttonFont);
blog.setFont(buttonFont);
bcos.setFont(buttonFont);
bsin.setFont(buttonFont);
btan.setFont(buttonFont);
bexp.setFont(buttonFont);

bm1.setFont(buttonFont);
bm2.setFont(buttonFont);
bMC.setFont(buttonFont);
bMR.setFont(buttonFont);

JPanel p = new JPanel();
p.setLayout(new GridLayout(7, 4, 5, 5));

bm.addActionListener(c);
bd.addActionListener(c);
bs.addActionListener(c);
ba.addActionListener(c);

b9.addActionListener(c);
b8.addActionListener(c);
b7.addActionListener(c);
b6.addActionListener(c);
b5.addActionListener(c);
b4.addActionListener(c);
b3.addActionListener(c);
b2.addActionListener(c);
b1.addActionListener(c);
b0.addActionListener(c);

bfac.addActionListener(c);
be.addActionListener(c);
bc.addActionListener(c);
beq.addActionListener(c);
bsq.addActionListener(c);
binv.addActionListener(c);
blog.addActionListener(c);
bsin.addActionListener(c);
bcos.addActionListener(c);
btan.addActionListener(c);
bexp.addActionListener(c);

bm1.addActionListener(c);
bm2.addActionListener(c);
bMC.addActionListener(c);
bMR.addActionListener(c);

p.add(bMR);
p.add(bMC);
p.add(bm1);
p.add(bm2);
p.add(b1);
p.add(b2);
p.add(b3);
p.add(ba);
p.add(b4);
p.add(b5);
p.add(b6);
p.add(bs);
p.add(b7);
p.add(b8);
p.add(b9);
p.add(bm);
p.add(b0);
p.add(bsq);
p.add(bexp);
p.add(bd);
p.add(bsin);
p.add(btan);
p.add(bcos);
p.add(be);
p.add(blog);
p.add(bfac);
p.add(bc);
p.add(beq);

frame.setLayout(new BorderLayout());

frame.add(field, BorderLayout.NORTH);
frame.add(p, BorderLayout.CENTER);

p.setBackground(Color.lightGray);
frame.setSize(400, 500);
frame.setVisible(true);
}

Explanation:

  • With the help of JButton class, we have defined the buttons that will be used in our project
  • After that, we provide labels to the buttons, which represent the text that will appear on each button
  • We set a standard Font with the help of buttonFont and use the same Font for each button.
  • We create a JPanel named p and set its layout to GridLayout, further defining GridLayout.
  • With the help of addActionListener() method, we handle the event whenever a button is clicked.
  • With the help of the add() method, we add the buttons to the panel in specific order.

4. The Main Logic behind Scientific Calculator

public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();

if ((s.charAt(0) >= '0' && s.charAt(0) <= '9') || s.charAt(0) == '.') {
if (!str1.equals("")) {
str2 = str2 + s;
} else {
str = str + s;
}
field.setText(str + str1 + str2);
} else if (s.charAt(0) == 'C') {
str = str1 = str2 = "";
field.setText("");
} else if (s.charAt(0) == '=') {
double te = 0;
try {
if (str1.equals("+")) {
te = (Double.parseDouble(str) + Double.parseDouble(str2));
} else if (str1.equals("-")) {
te = (Double.parseDouble(str) - Double.parseDouble(str2));
} else if (str1.equals("/")) {
te = (Double.parseDouble(str) / Double.parseDouble(str2));
} else if (str1.equals("*")) {
te = (Double.parseDouble(str) * Double.parseDouble(str2));
} else if (str1.equals("√")) {
te = Math.sqrt(Double.parseDouble(str));
} else if (str1.equals("1/x")) {
te = 1 / Double.parseDouble(str);
} else if (str1.equals("Log")) {
te = Math.log(Double.parseDouble(str));
} else if (str1.equals("Sin")) {
te = Math.sin(Math.toRadians(Double.parseDouble(str)));
}
else if (str1.equals("Tan")) {
te = Math.tan(Math.toRadians(Double.parseDouble(str)));
} else if (str1.equals("Exp")) {
te = Math.exp(Double.parseDouble(str));
} else if (str1.equals("!")) {
int value = Integer.parseInt(str);
if (value < 0) {
field.setText("Error");
} else {
long fact = factorial(value);
field.setText(str + "!" + "=" + fact);
str = Long.toString(fact);
}
str1 = str2 = "";
return;
} else if (str1.equals("cos")) {
te = Math.cos(Math.toRadians(Double.parseDouble(str)));
}
} catch (Exception ex) {
field.setText("Error");
str = str1 = str2 = "";
return;
}
field.setText(str + str1 + str2 + "=" + te);
str = Double.toString(te);
str1 = str2 = "";
} else if (s.equals("√") || s.equals("1/x") || s.equals("Log") ||
s.equals("Sin") || s.equals("cos") || s.equals("Tan") || s.equals("Exp") ||
s.equals("MC") || s.equals("MR") || s.equals("M+") || s.equals("M-") || s.equals("!")) {
str1 = s;
actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "="));
} else {
if (str1.equals("") || str2.equals("")) {
str1 = s;
} else {
double te = 0;
if (str1.equals("+")) {
te = (Double.parseDouble(str) + Double.parseDouble(str2));
} else if (str1.equals("-")) {
te = (Double.parseDouble(str) - Double.parseDouble(str2));
} else if (str1.equals("/")) {
te = (Double.parseDouble(str) / Double.parseDouble(str2));
} else if (str1.equals("*")) {
te = (Double.parseDouble(str) * Double.parseDouble(str2));
}
str = Double.toString(te);
str1 = s;
str2 = "";
}
field.setText(str + str1 + str2);
}
}

public static long factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException("Factorial is not defined for negative numbers");
}
long result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}

Explanation:

The actionPerformed method in the calculator class helps us in handling the events triggered by the user.

  • getActionCommand() method helps us retrieve the label on the button that is clicked.
  • Now, with the help of if else statements, we handle our inputs. It updates the TextField with the help of str, str1 and str2. We also add the condition that when C is pressed it clears the inputs.
  • Now, we handle events triggered when a user clicks the Equals button. With the help of if else statements, we handle all the mathematical operators in the calculator. Based on the operator in str1 we perform operations on inputs str and str2. (Single operand functions like log, Sin, Cos etc are handled as well)
  • For example, when str1 equals + then we add our inputs str and str2, similarly when str1 equals log then we use Math.log function to calculate the log value for our input values.
  • With the help of the setText method, we display the result of the operation and reset both str1 and str2.
  • In the end we have written code for operator assigning, i.e. when both str1 and str2 are empty, assign the operand to str1 and calculate the result accordingly.
  • In the end, we have defined a function for factorial because Math class does not contain any predefined method for it. You can also define functions for other operators if you want to add more functionality to this project.

Java Scientific Calculator Output

Java Scientific Calculator will look like

Java Scientific Calculator Output
Scientific Calculator Output
Scientific Calculator Project output

It can perform basic and complex mathematical operations. With this, we have finished our scientific calculator in the Java Project.

Summary

We have successfully completed our objective of creating a scientific calculator in Java. We have discussed the project details and its prerequisites. You can even add more complex mathematical operations to make this more challenging and useful.

I hope you liked this Java project. Thank You.

--

--

Himani Bansal
Wiki Flood

Doing my Best to Explain Data Science (Data Scientist, technology freak & Blogger)