Java Swing Calculator: Learn by Building | Step-by-Step | A Beginner's Guide


1. Introduction

    Welcome to this tutorial on creating a simple calculator using Java! In this article, we'll walk you through the process of building a basic calculator with a graphical user interface (GUI) using Java's Swing library. This project is not only a great way to practice your Java programming skills but also an excellent starting point for understanding how user interfaces and event-driven programming work.

    1.1 Brief Overview of the Simple Calculator Project in Java

    Our calculator will be able to perform basic arithmetic operations, such as addition, subtraction, multiplication, and division. It will also include some additional functions like calculating the square root and toggling the sign of the input number. We'll be using Java's Swing library to create the GUI, which will consist of buttons for each operation, a display for the input and output, and various panels for organizing the components.

    1.2 Importance of Building a Calculator as a Beginner's Project

    Creating a simple calculator as a beginner's project offers several benefits:

    • Reinforces basic Java programming concepts, such as variables, loops, and conditional statements.
    • Introduces event-driven programming, which is a fundamental aspect of building interactive applications.
    • Provides experience with the Swing library, a widely-used tool for creating graphical interfaces in Java applications.
    • Enhances problem-solving and debugging skills by working through the logic required for a calculator's operations.
    • Encourages creativity and customization, as you can expand the functionality or modify the design to suit your preferences.

    By the end of this tutorial, you'll have a fully functional calculator application that you can run on your computer and a solid foundation for further exploration in Java programming and GUI development.

    2. Setting Up the Calculator Interface

    In this section, we will discuss how to create the calculator's interface using Java's Swing library. We'll start by creating a JFrame, setting its properties, and defining the necessary UI elements, such as buttons, panels, and the display area. Finally, we'll arrange these elements using layout managers and dimensions.

    2.1 Creating a JFrame and Setting Its Properties

    A JFrame is a top-level container that provides the frame for our calculator application. To create a JFrame, we'll extend the Calculator class from the JFrame class:

    public class Calculator extends JFrame implements ActionListener {

    In the constructor of the Calculator class, we'll set the basic properties for our JFrame:

    Calculator() {
        super("Calculator");
        setDesign();
        setSize(500, 350);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        GridLayout grid = new GridLayout(5, 5);
        setLayout(grid);
        // ...
    }

    Here, we set the title of the window using super("Calculator"), disable resizing with setResizable(false), and specify the window's dimensions using setSize(500, 350). We also set the default close operation to EXIT_ON_CLOSE, which will terminate the application when the user closes the window.

    2.2 Defining Buttons, Panels, and Other UI Elements

    To create the calculator's interface, we'll need several UI elements, including buttons for each operation, a display area for input and output, and panels to organize the components. We define these elements as instance variables in the Calculator class:

    JPanel[] row = new JPanel[5];
    JButton[] button = new JButton[19];
    String[] buttonString = {"7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", ".", "/", "C", "√", "+/-", "=", "0"};
    // ...
    JTextArea display = new JTextArea(2, 25);

    2.3 Setting Up the Layout Managers and Dimensions for Elements

    To arrange the UI elements on the JFrame, we use layout managers. In this project, we'll primarily use GridLayout and FlowLayout.

    We set the GridLayout for the main calculator window:

    GridLayout grid = new GridLayout(5, 5);
    setLayout(grid);

    For each row of buttons, we create a JPanel and set its layout to FlowLayout. We then add the buttons to the respective panels and the panels to the JFrame:

    FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
    FlowLayout f2 = new FlowLayout(FlowLayout.CENTER, 1, 1);
    for (int i = 0; i < 5; i++) {
        row[i] = new JPanel();
    }
    row[0].setLayout(f1);
    for (int i = 1; i < 5; i++) {
        row[i].setLayout(f2);
    }
    
    // Add buttons to panels and panels to JFrame
    // ...
    
    add(row[0]);
    add(row[1]);
    add(row[2]);
    add(row[3]);
    add(row[4]);

    Lastly, we set the dimensions for the display and buttons:

    Dimension displayDimension = new Dimension(dimW[0], dimH[0]);
    Dimension regularDimension = new Dimension(dimW[1], dimH[1]);
    Dimension rColumnDimension = new Dimension(dimW[2], dimH[1]);
    Dimension zeroButDimension = new Dimension(dimW[3], dimH[1]);
    // ...
    
    display.setPreferredSize(displayDimension);
    // ...

    Now that we've set up the calculator's interface, we can move on to implementing the functionality behind each button.

    3. Implementing Calculator Functionality

    In this section, we will discuss implementing the functionality for our calculator. This includes initializing the calculator's state and variables, creating helper functions for various operations, and handling button actions and user input.

    3.1 Initializing the Calculator State and Variables

    To manage the calculator's state and store user input, we need to initialize several variables in the Calculator class:

    double[] temporary = {0, 0};
    JTextArea display = new JTextArea(1, 20);
    boolean[] function = new boolean[4];
    int[] dimW = {300, 45, 100, 90};
    int[] dimH = {35, 40};

    Here, we create an array called temporary to store the operands for arithmetic operations, a JTextArea called display for input and output, a boolean array called function to track the active operation, and two integer arrays called dimW and dimH to store dimensions for UI elements.

    3.2 Creating Helper Functions: clear(), getSqrt(), getPosNeg(), and getResult()

    To handle various calculator functions, we'll create several helper methods in the Calculator class:

    • clear(): Resets the calculator's state
    • getSqrt(): Calculates the square root of the current input value
    • getPosNeg(): Toggles the sign of the current input value
    • getResult(): Performs the selected arithmetic operation and displays the result

    Here's the implementation for the clear() method:

    public void clear() {
        try {
            display.setText(""); // Clear display
            for (int i = 0; i < 4; i++) {
                function[i] = false; // Reset functions
            }
            for (int i = 0; i < 2; i++) {
                temporary[i] = 0; // Reset temporary values
            }
        } catch (NullPointerException e) {
        }
    }

    To calculate the square root, we'll use the Math.sqrt() function. Here's the implementation for the getSqrt() method:

    public void getSqrt() {
        try {
            double value = Math.sqrt(Double.parseDouble(display.getText()));
            display.setText(Double.toString(value));
        } catch (NumberFormatException e) {
        }
    }

    To toggle the sign of the input number, we'll multiply the current input value by -1. Here's the implementation for the getPosNeg() method:

    public void getPosNeg() {
        try {
            double value = Double.parseDouble(display.getText());
            if (value != 0) {
                value = value * (-1);
                display.setText(Double.toString(value));
            }
        } catch (NumberFormatException e) {
        }
    }

    When the equals button is pressed, we store the current input value as the second operand (temporary[1]) and perform the operation corresponding to the active function. Here's the implementation for the getResult() method:

    public void getResult() {
        double result = 0;
        temporary[1] = Double.parseDouble(display.getText());
        try {
            if (function[2] == true) {
                result = temporary[0] * temporary[1];
            } else if (function[3] == true) {
                result = temporary[0] / temporary[1];
            } else if (function[0] == true) {
                result = temporary[0] + temporary[1];
            } else if (function[1] == true) {
                result = temporary[0] - temporary[1];
            }
            display.setText(Double.toString(result));
            for (int i = 0; i < 4; i++) {
                function[i] = false;
            }
        } catch (NumberFormatException e) {
        }
    }

    3.3 Handling Button Actions and User Input

    To handle button actions and user input, we need to implement the actionPerformed() method from the ActionListener interface in the Calculator class:

    public void actionPerformed(ActionEvent ae) {
        // Handle number and decimal point buttons
        for (int i = 0; i < 10; i++) {
            if (ae.getSource() == button[i]) {
                display.append(Integer.toString(i));
            }
        }
        if (ae.getSource() == button[10]) {
            display.append(".");
        }
    
        // Handle arithmetic operation buttons
        // Refer to the previous response for handling basic arithmetic operations
    
        // Handle special function buttons
        if (ae.getSource() == button[14]) {
            clear();
        }
        if (ae.getSource() == button[15]) {
            getSqrt();
        }
        if (ae.getSource() == button[16]) {
            getPosNeg();
        }
        if (ae.getSource() == button[17]) {
            getResult();
        }
    }

    In this method, we check which button triggered the actionPerformed() method and call the appropriate helper function or update the display accordingly.

    4. Calculator Code Explanation

    In this section, we will provide a detailed explanation of the main code structure, components, and key parts of the calculator code. Additionally, we will showcase the output examples for each function.

    4.1 Explanation of the Main Code Structure and Components

    The main components of the calculator code include the Calculator class, which extends JFrame and implements the ActionListener interface. The Calculator class contains various UI elements, such as buttons and panels, as well as methods to handle the calculator's functionality.

    4.2 List of Key Parts in the Code

    • Constructor: The constructor initializes the calculator UI, sets up the layout managers, and adds buttons and other UI elements to the frame. It also sets up the action listeners for the buttons.
    • setDesign(): This method sets the look and feel of the calculator to Nimbus.
    • actionPerformed(): This method handles button actions and user input by calling appropriate helper functions or updating the display.

    4.3 Output Examples for Each Function

    Here are some output examples for each calculator function:

    1. Addition:
      • Input: 7 + 8
      • Output: 15.0
    2. Subtraction:
      • Input: 9 - 4
      • Output: 5.0
    3. Multiplication:
      • Input: 5 * 6
      • Output: 30.0
    4. Division:
      • Input: 12 / 3
      • Output: 4.0
    5. Square Root:
      • Input: √(16)
      • Output: 4.0
    6. Positive/Negative Toggle:
      • Input: -(-7)
      • Output: 7.0

    For the above examples, the user would input the numbers and operators using the calculator buttons, and the output would be displayed in the calculator's display area.

    4.4 Complete Calculator Code

    To provide a clear and comprehensive view of the calculator project, we have included the entire code below. This code combines all the elements and functionality discussed in the previous sections. As you go through the code, refer back to the explanations provided in this article to understand each component's purpose and function. Feel free to copy and run this code on your own system, experiment with it, and modify it according to your preferences.

    Here is the complete code in the file Calculator.java:

    import java.awt.*;
    
    import javax.swing.*;
    
    import java.awt.event.*;
    
    public class Calculator extends JFrame implements ActionListener {    
        /**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	JPanel[] row = new JPanel[5];
        JButton[] button = new JButton[19];
        String[] buttonString = {"7", "8", "9", "+",
                                 "4", "5", "6", "-",
                                 "1", "2", "3", "*",
                                 ".", "/", "C", "√",
                                 "+/-", "=", "0"};
        int[] dimW = {430,70,150,140};
        int[] dimH = {50, 60};
        Dimension displayDimension = new Dimension(dimW[0], dimH[0]);
        Dimension regularDimension = new Dimension(dimW[1], dimH[1]);
        Dimension rColumnDimension = new Dimension(dimW[2], dimH[1]);
        Dimension zeroButDimension = new Dimension(dimW[3], dimH[1]);
        boolean[] function = new boolean[4];
        double[] temporary = {0, 0};
        JTextArea display = new JTextArea(2,25);
        Font font = new Font("Times new Roman", Font.BOLD, 20);
        
        Calculator() {
            super("Calculator");
            setDesign();
            setSize(500, 350);
            setResizable(false);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            GridLayout grid = new GridLayout(5,5);
            setLayout(grid);
            
            for(int i = 0; i < 4; i++)
                function[i] = false;
            
            FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
            FlowLayout f2 = new FlowLayout(FlowLayout.CENTER,1,1);
            for(int i = 0; i < 5; i++)
                row[i] = new JPanel();
            row[0].setLayout(f1);
            for(int i = 1; i < 5; i++)
                row[i].setLayout(f2);
            
            for(int i = 0; i < 19; i++) {
                button[i] = new JButton();
                button[i].setText(buttonString[i]);
                button[i].setBackground(Color.white);
                button[i].setFont(font);
                button[i].addActionListener(this);
            }
            
            display.setFont(font);
            display.setEditable(false);
            display.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
            display.setPreferredSize(displayDimension);
            
            for(int i = 0; i < 14; i++)
                button[i].setPreferredSize(regularDimension);
            for(int i = 14; i < 18; i++)
                button[i].setPreferredSize(rColumnDimension);
            button[18].setPreferredSize(zeroButDimension);
            
            row[0].add(display); // Adds text view to JPanel
            add(row[0]); // Adds JPanel to Frame
            
            for(int i = 0; i < 4; i++)
                row[1].add(button[i]);
            row[1].add(button[14]);
            add(row[1]);
            
            for(int i = 4; i < 8; i++)
                row[2].add(button[i]);
            row[2].add(button[15]);
            add(row[2]);
            
            for(int i = 8; i < 12; i++)
                row[3].add(button[i]);
            row[3].add(button[16]);
            add(row[3]);
            
            row[4].add(button[18]);
            for(int i = 12; i < 14; i++)
                row[4].add(button[i]);
            row[4].add(button[17]);
            add(row[4]);
            
            setVisible(true);
            
        }
        
        public void clear() {
            try {
                display.setText("");
                for(int i = 0; i < 4; i++)
                    function[i] = false;
                for(int i = 0; i < 2; i++)
                    temporary[i] = 0;
            } catch(NullPointerException e) {  
            }
        }
        
        public void getSqrt() {
            try {
                double value = Math.sqrt(Double.parseDouble(display.getText()));
                display.setText(Double.toString(value));
            } catch(NumberFormatException e) {
            }
        }
        
        public void getPosNeg() {
            try {
                double value = Double.parseDouble(display.getText());
                if(value != 0) {
                    value = value * (-1);
                    display.setText(Double.toString(value));
                }
                else {
                }
            } catch(NumberFormatException e) {
            }
        }
        
        public void getResult() {
            double result = 0;
            temporary[1] = Double.parseDouble(display.getText());
            try {
                if(function[2] == true)
                    result = temporary[0] * temporary[1];
                else if(function[3] == true)
                    result = temporary[0] / temporary[1];
                else if(function[0] == true)
                    result = temporary[0] + temporary[1];
                else if(function[1] == true)
                    result = temporary[0] - temporary[1];
                display.setText(Double.toString(result));
                for(int i = 0; i < 4; i++)
                    function[i] = false;
            } catch(NumberFormatException e) {
            }
        }
        
        public final void setDesign() {
            try {
                UIManager.setLookAndFeel(
                        "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
            } catch(Exception e) {   
            }
        }
        
        @Override
        public void actionPerformed(ActionEvent ae) {
        	
            if(ae.getSource() == button[0])
                display.append("7");
            if(ae.getSource() == button[1])
                display.append("8");
            if(ae.getSource() == button[2])
                display.append("9");
            if(ae.getSource() == button[3]) {
            	//button[3].setText("H");
                //add function[0]
                temporary[0] = Double.parseDouble(display.getText());
                function[0] = true;
                display.setText("");
            }
            if(ae.getSource() == button[4])
                display.append("4");
            if(ae.getSource() == button[5])
                display.append("5");
            if(ae.getSource() == button[6])
                display.append("6");
            if(ae.getSource() == button[7]) {
                //subtract function[1]
                temporary[0] = Double.parseDouble(display.getText());
                function[1] = true;
                display.setText("");
            }
            if(ae.getSource() == button[8])
                display.append("1");
            if(ae.getSource() == button[9])
                display.append("2");
            if(ae.getSource() == button[10])
                display.append("3");
            if(ae.getSource() == button[11]) {
                //multiply function[2]
                temporary[0] = Double.parseDouble(display.getText());
                function[2] = true;
                display.setText("");
            }
            if(ae.getSource() == button[12])
                display.append(".");
            if(ae.getSource() == button[13]) {
                //divide function[3]
                temporary[0] = Double.parseDouble(display.getText());
                function[3] = true;
                display.setText("");
            }
            if(ae.getSource() == button[14])
                clear();
            if(ae.getSource() == button[15])
                getSqrt();
            if(ae.getSource() == button[16])
                getPosNeg();
            if(ae.getSource() == button[17])
                getResult();
            if(ae.getSource() == button[18])
                display.append("0");
        }
        
        public static void main(String[] arguments) {
            Calculator c = new Calculator();
        }
    }
    

    5. Running the Calculator

    To run the calculator program, follow these steps:

    1. Copy the entire calculator code provided in Section 4.4 into a new file named Calculator.java.
    2. Open a terminal or command prompt and navigate to the directory where you saved the Calculator.java file.
    3. Compile the Java code by running the following command:

    javac Calculator.java

    1. If there are no errors in the code, the compilation will be successful, and you can proceed to run the program by executing the following command:

    java Calculator

    1. The calculator application will appear on your screen, and you can use it to perform various calculations.
    Calculator Java Programming

    6. Enhancements and Further Learning

    This section will provide ideas for extending the calculator's functionality, suggestions for improving the calculator's design and user experience, and links to resources for learning more about Java programming and Swing UI development.

    6.1 Ideas for Extending the Calculator's Functionality

    You can enhance the calculator's functionality by implementing the following features:

    1. Advanced mathematical functions such as exponentiation, logarithms, trigonometry, and factorials.
    2. Support for parentheses to evaluate complex expressions.
    3. Memory functions (M+, M-, MR, MC) to store and recall values.
    4. Implementing a history panel to display previous calculations.
    5. Keyboard input support to allow users to perform calculations using the keyboard.

    6.2 Suggestions for Improving the Calculator's Design and User Experience

    To improve the calculator's design and user experience, consider the following ideas:

    1. Use custom icons for buttons to create a more visually appealing interface.
    2. Implement tooltips for buttons to provide additional information about their functionality.
    3. Adjust the color scheme and fonts to make the calculator more visually appealing and easier to read.
    4. Add animation or transition effects to enhance the user experience.
    5. Improve the responsiveness of the application by optimizing the code and UI elements.

    For those interested in learning more about Java programming and Swing UI development, consider the following resources:

    1. Oracle's Java Tutorials: [Link: https://docs.oracle.com/javase/tutorial/]
    2. Java Swing Tutorial: [Link: https://www.javatpoint.com/java-swing]
    3. Java Programming Masterclass (Udemy course): [Link: https://www.udemy.com/course/java-the-complete-java-developer-course/]
    4. Java Swing (GUI) Programming: From Beginner to Expert (Udemy course): [Link: https://www.udemy.com/course/java-swing-complete/]
    5. Java Programming and Software Engineering Fundamentals Specialization (Coursera course): [Link: https://www.coursera.org/specializations/java-programming]

    7. Conclusion

    In this article, we have provided a comprehensive guide to building a simple calculator using Java programming language and Swing UI components. We have covered each step in detail, from setting up the user interface to implementing the calculator's functionality, and explaining the code.

    Here is a summary of the main points we have covered in this article:

    1. Introduction to the simple calculator project in Java, and its importance as a beginner's project.
    2. Setting up the calculator interface using JFrame, buttons, panels, and other UI elements, along with layout managers and dimensions.
    3. Implementing calculator functionality with the help of helper functions such as clear(), getSqrt(), getPosNeg(), and getResult().
    4. A thorough explanation of the code structure, components, and output examples for each function.
    5. Instructions on how to run the calculator program, along with a screenshot of the running application.
    6. Ideas for enhancing the calculator's functionality and design, and resources for further learning in Java programming and Swing UI development.

    We encourage you to experiment with the provided code, make changes, and explore new features to create your own unique calculator application. Building a calculator is an excellent way to learn Java programming concepts, Swing UI components, and event handling. It also serves as a stepping stone to creating more complex applications in the future.

    Don't be afraid to experiment, make mistakes, and learn from them. As you gain experience, you'll be better equipped to tackle more advanced projects in Java and other programming languages. Keep learning, practicing, and expanding your programming skills.

    I hope you found this article helpful.

    Cheers.

    Happy Coding!

    About the Author

    This article was authored by Rawnak

    1 thought on “Java Swing Calculator: Learn by Building | Step-by-Step | A Beginner's Guide”

    Comments are closed.