Java Project – Scientific Calculator

FREE Online Courses: Elevate Skills, Zero Cost. Enroll Now!

Scientific calculators are essential for efficiently completing difficult mathematical tasks. With the help of Java, we created a scientific calculator for this project. This article will give a general overview of a scientific calculator, go over the necessary conditions for the project, describe how to generate the code and discuss its functionalities.

About Java Scientific Calculator

The scientific calculator is designed to provide users with a comprehensive set of mathematical operations. It offers a graphical user interface (GUI) and supports various mathematical functions and operations.

The following operations can be carried out with the help of this code:

  • Addition
  • Subtraction
  • Division
  • Multiplication
  • Exponentiation
  • Logarithm
  • Trigonometric Functions
  • Square Root
  • Cube Root
  • Factorial
  • Inverse Trigonometric Functions
  • Percentage Calculation
  • Absolute Value

Prerequisites For Scientific Calculator Using Java

  • IDE Used: IntelliJ
  •  Java 1.8 or above must be installed

Download Java Scientific Calculator Project

Please download the source code of the Java Scientific Calculator Project from the following link: Java Scientific Calculator Project Code

Steps to Create Java Scientific Calculator:

  • Importing packages and Main Class Setup.
  • Constructor to Main Class.
  • Implementing ActionListener Interface.
  • Evaluating the expression
  • The main () method
  • Test the Scientific Calculator

1. Import Packages and Main Class Setup:

This step involves importing the important packages required for the Graphic User Interface setup and event handling. Here, libraries and packages imported are ‘java. awt’ and ‘java. swing’.

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

The Main Class setup involves the creation of a class named ‘ScientificCalculator’. The following class extends from the class ‘JFrame’ and implements the interface name ‘ActionListener’.

public class ScientificCalculator extends JFrame implements ActionListener

2. Constructor to Main Class:

This Step defines the constructor to class ‘ScientificCalculator’ Class.

This handles the initial setup of the calculator, such as title, default close operation and frame layout. ‘textField’ is set up to display the calculator’s input and output along with property configurations. To hold the buttons, ‘buttonPanel’ is created, and its colour is set to ‘Orange’. To set up the calculator keys, an array of button labels is created. ‘buttonPanel’ accesses these labels using a for loop. This ‘buttonPanel’ is then added to the frame, which is then packed and finally made visible.

public ScientificCalculator() {
    setTitle("Project Gurukul's Scientific Calculator");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(new BorderLayout());

    textField = new JTextField();
    textField.setEditable(false);
    textField.setPreferredSize(new Dimension(300, 40));
    add(textField, BorderLayout.NORTH);

    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new GridLayout(9, 4));
    buttonPanel.setBackground(Color.ORANGE);
    buttonPanel.setForeground(Color.PINK);

    // Button labels for the calculator
    String[] buttonLabels = {
            "1", "2", "3", "/", "4", "5", "6", "*", "7", "8", "9", "-", "0", ".", "=", "+", "Clear",
            "(", ")", "^", "sqrt", "cbrt", "log", "sin", "cos", "tan", "asin", "acos", "atan", "!", "%", "|x|"
    };

    for (String label : buttonLabels) {
        JButton button = new JButton(label);
        button.addActionListener(this);
        buttonPanel.add(button);
    }

    add(buttonPanel, BorderLayout.CENTER);

    pack();
    setVisible(true);
}

3. Implementing ActionListener Interface:

This step is basically handling the button click event. It receives the command given by the user in ‘textField’ and also clears the same after evaluation.

public void actionPerformed(ActionEvent event) {
    String command = event.getActionCommand();
    String expression = textField.getText();

    switch (command) {
        case "=":
            try {
                double result = evaluateExpression(expression);
                textField.setText(Double.toString(result));
            } catch (ArithmeticException e) {
                textField.setText("Error: " + e.getMessage());
            }
            break;
        case "Clear":
            textField.setText("");
            break;
        case "<=":
            if (!expression.isEmpty()) {
                String newExpression = expression.substring(0, expression.length() - 1);
                textField.setText(newExpression);
            }
            break;
        default:
            textField.setText(expression + command);
            break;
    }
}

4. Evaluating the Expression:

This step involves the evaluation of commands given by the user.

Now, here we evaluate the following expressions: Addition, Subtraction, Division, Multiplication, Exponentiation, Logarithm, Trigonometric Function, Square Root, Cube Root, Factorial, Inverse Trigonometric Functions, Percentage Calculation, Absolute Value‘ExpressionParser’, a nested private class in the code, is in charge of evaluating mathematical and arithmetic expressions. Recursive descent parsing is used by the ‘ExpressionParser’ class to evaluate the expression. It offers methods for handling the parsing and evaluation of the many operations and components in the expression, such as ‘nextChar()’, ‘eat()’, ‘’parse()’, ‘parseExpression()’, ‘parseTerm()’, and ‘factorial()’.

private double evaluateExpression(String expression) {
    return new ExpressionParser().parse(expression);
}
// ExpressionParser handles parsing and evaluating mathematical expressions
private static class ExpressionParser {
    private int pos = -1;
    private int ch;
    // Move to the next character in the expression
    private void nextChar(String expression) {
        ch = (++pos < expression.length()) ? expression.charAt(pos) : -1;
    }
    // Skip whitespace characters and check if the current character matches the one to be eaten
    private boolean eat(int charToEat, String expression) {
        while (ch == ' ') nextChar(expression);
        if (ch == charToEat) {
            nextChar(expression);
            return true;
        }
        return false;
    }
    // Parse the entire expression and return the result
    private double parse(String expression) {
        nextChar(expression);
        double x = parseExpression(expression);
        if (pos < expression.length()) throw new RuntimeException("Unexpected: " + (char)ch);
        return x;
    }

    // Parse the expression by evaluating the terms and handling addition and subtraction
    private double parseExpression(String expression) {
        double x = parseTerm(expression);
        while (true) {
            if (eat('+', expression)) x += parseTerm(expression);
            else if (eat('-', expression)) x -= parseTerm(expression);
            else return x;
        }
    }

    // Parse the term by evaluating the factors and handling multiplication, division, and exponentiation
    private double parseTerm(String expression) {
        double x = parseFactor(expression);
        while (true) {
            if (eat('*', expression)) x *= parseFactor(expression);
            else if (eat('/', expression)) x /= parseFactor(expression);
            else if (eat('^', expression)) x = Math.pow(x, parseFactor(expression));
            else return x;
        }
    }

    // Parse the factor by handling positive/negative signs, parentheses, numbers, and functions
    private double parseFactor(String expression) {
        if (eat('+', expression)) return parseFactor(expression);
        if (eat('-', expression)) return -parseFactor(expression);

        double x;
        int startPos = this.pos;
        if (eat('(', expression)) {
            // Handle parentheses by recursively parsing the expression inside them
            x = parseExpression(expression);
            eat(')', expression);
        } else if ((ch >= '0' && ch <= '9') || ch == '.') {
            // Parse numbers (integer or decimal)
            while ((ch >= '0' && ch <= '9') || ch == '.') nextChar(expression);
            x = Double.parseDouble(expression.substring(startPos, this.pos));
        } else if (ch >= 'a' && ch <= 'z') {
            // Parse functions (such as sqrt, sin, cos, etc.)
            while (ch >= 'a' && ch <= 'z') nextChar(expression);
            String func = expression.substring(startPos, this.pos);
            x = parseFactor(expression);
            switch (func) {
                case "sqrt":
                    x = Math.sqrt(x);
                    break;
                case "cbrt":
                    x = Math.cbrt(x);
                    break;
                case "log":
                    x = Math.log10(x);
                    break;
                case "sin":
                    x = Math.sin(Math.toRadians(x));
                    break;
                case "cos":
                    x = Math.cos(Math.toRadians(x));
                    break;
                case "tan":
                    x = Math.tan(Math.toRadians(x));
                    break;
                case "asin":
                    x = Math.toDegrees(Math.asin(x));
                    break;
                case "acos":
                    x = Math.toDegrees(Math.acos(x));
                    break;
                case "atan":
                    x = Math.toDegrees(Math.atan(x));
                    break;
                case "!":
                    x = factorial((int) x);
                    break;
                case "%":
                    x = x / 100.0;
                    break;
                case "|x|":
                    x = Math.abs(x);
                    break;
                default:
                    throw new RuntimeException("Unknown function: " + func);
            }
        } else {
            throw new RuntimeException("Unexpected: " + (char)ch);
        }

        return x;
    }

    // Compute the factorial of a number
    private int factorial(int n) {
        if (n == 0) return 1;
        int fact = 1;
        for (int i = 1; i <= n; i++) {
            fact *= i;
        }
        return fact;
    }
}

5. The main () method:

The main() method is the entry point of the code. It instantiates the SwingUtilities.invokeLater() method to run the ScientificCalculator constructor in the event dispatch thread, ensuring thread safety in GUI operations.

public static void main(String[] args) {
    // Create and display the calculator GUI
    SwingUtilities.invokeLater(ScientificCalculator::new);
}

6. Test the Scientific Calculator:

Run the respective code to test the calculator.

Interface of Calculator

addition

subtraction

multiplication

Division

exponentiation

logarithm

trigonometric-functions

inverse-trigonometric-functions

square root

Conclusion

The offered Java code, in conclusion, offers an effective and user-friendly scientific calculator. Basic arithmetic, exponentiation, logarithm, and trigonometric functions are all part of the wide variety of operations it provides. For managing erroneous options and avoiding division by zero, the code includes exception handling. This scientific calculator code functions as an efficient tool for carrying out numerous mathematical tasks thanks to its menu-based user interface and precise computations.

If you are Happy with ProjectGurukul, do not forget to make us happy with your positive feedback on Google | Facebook

Leave a Reply

Your email address will not be published. Required fields are marked *