Java implementation of mimic win10 calculator

Article Directory

1. Experimental purposes:

1. Master the programming design method of Java GUI;
2. Master the programming method of exception handling.
3. Master the methods of component monitoring and action response processing.

II. EXPERIMENTAL CONTENTS

Implement a calculator.Requirement:
1. Referring to the function of Windows calculator, add, subtract, multiply and divide operations are implemented;
2. Declare as an array of buttons;
3. Use the same algorithm for 0~9 digital operations;
4. Solve the problem of dividing by zero;
5. It has the functions of clearing one number, clearing all, squaring and squaring.
6. Keep 4 decimal places in the calculation results.
7. When the interface is scaled, all components are scaled synchronously to keep the overall style of the interface unchanged.

3. Experimental Principles

  • By first analyzing the layout of the interface, you can divide the interface into upper and lower parts
    Use one panel to mount the text box on top and one panel to mount the buttons for the calculator on the bottom.
    The default layout of the frame is BorderLayout, so I'll put the panel where the text box is located in the north and the panel where the buttons are located in the middle of the calculator to achieve the desired effect.
    The panel on which the button is located uses a grid layout (GridLayout), which enables all components to scale synchronously while resizing the interface, keeping the overall style of the interface unchanged.
    In order to restore the win10 calculator as much as possible, I removed the border styles of buttons and text boxes, as well as the color, spacing, and so on, on the boundary.(It's hard to find rgb with the same color as win10's own calculator. I've been comparing colors online for a long time (_).
  • The way I add event listeners for each button is to use the same event listener, so when processing an event, just get the source of the event and make a judgment.
    To determine whether the user enters the first number of the entire expression or the first number after the operator by pressing a key, I add a Boolean variable, firstDigit, which is used in the operation.I have divided the operations into two main categories: those that operate on only one number, such as: inversion,%, square, plus or minus (equivalent to a monotonic operator); the rest require two numbers to operate on (before and after the operator, i.e., a binary operator).
    In addition to the various processing methods, I have written a way to get numbers from a text box (converting strings to double s plus exception handling): getNumberFromText(), because it is used many times, just write a method call directly.

4. Operation

  • I've tried my best to imitate it, Hee-hee (I made it on the left and the win10 calculator on the computer on the right)

  • When the interface is scaled, all components are scaled synchronously, keeping the overall style of the interface unchanged:

  • Normal addition, subtraction, multiplication and division operations are relatively common. Here we will only show the cases where division and division are 0.

  • Square operation (keep the last 4 digits of the decimal point when the result is a decimal)

  • If it is illegal to prescribe a negative number:

  • Square operation

  • Count down:

  • It is illegal to calculate the last denominator to be 0:

  • Press Backspace:

  • Positive and negative:

  • Decimal operations:

Source code:

package Calculator;

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

/**
 * Created by Henry
 * Date: 2019/12/18
 * Time: 16:08
 */
public class Calculator implements ActionListener {
    /**
     * Calculator
     */
    private JFrame frame = new JFrame();

    //Name of each key on the calculator (top to bottom, left to right)
    private String[] keys = {"%","CE","C","Back","1⁄x","X²","√x","÷","7","8","9","X","4","5","6","-","1","2","3","+","+/-","0",".","="};
    private JButton buttons[] = new JButton[keys.length];  //Buttons for keys on the calculator
    private JTextField resultText = new JTextField("0");  //Show calculation results text box

    private boolean firstDigit = true;  // Indicates whether the user is pressing the first number of the entire expression or the first number after the operator
    private double resultNum = 0.0000;   // Intermediate result of calculation
    private String operator = "=";   // Operator for the current operation (revert to'='when pressing'C')
    private boolean operateValidFlag = true;   // Determine if the operation is legal

    /**
     * Constructor
     */
    public Calculator() {
        init();  // Initialize Calculator
        frame.setTitle("Calculator -- @author Cheng Haoqing");
        frame.setSize(366, 439);
        frame.setLocation(500, 300);
        frame.setResizable(true);  // Allows you to modify the size of the calculator window
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * Initialize Calculator
     */
    private void init() {

        Color color1 = new Color(181, 181, 181);  //Function Key and Operator Color
        Color color2 = new Color(126, 192, 238);  //Equals sign exclusive color
        Color color3 = new Color(232, 232, 232);  //background color
        // Create a palette text box
        JPanel textPanel = new JPanel();
        textPanel.setLayout(new BorderLayout());
        textPanel.add(resultText);
        resultText.setFont(new Font("Kai Typography",Font.BOLD,43));  //Set the font and size of text in the text box, bold
        resultText.setHorizontalAlignment(JTextField.RIGHT);  //Right-aligned text box contents
        resultText.setEditable(false);  //Cannot modify result text box
        resultText.setBorder(null);  //Remove border of text box
        // Set Text Box Background Color
        resultText.setBackground(color1);

        // Initialize the button on the calculator key and place the key on a drawing board
        JPanel keysPanel = new JPanel();
        // With a grid layout with 6 rows and 4 columns, the horizontal and vertical spacing between grids is 2 pixels
        keysPanel.setLayout(new GridLayout(6, 4, 2, 2));
        //Initialization function button
        for(int i = 0; i < 8; i++) {
            buttons[i] = new JButton(keys[i]);
            keysPanel.add(buttons[i]);
            buttons[i].setBackground(color3);
            buttons[i].setForeground(Color.black);
            buttons[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
            buttons[i].setBorderPainted(false);  //Remove the border of the button
        }
        //Initialization Operators and Numeric Key Buttons
        for(int i = 8; i < keys.length; i++) {
            buttons[i] = new JButton(keys[i]);
            keysPanel.add(buttons[i]);
            if((i+1)%4==0) buttons[i].setBackground(color3);
            else buttons[i].setBackground(Color.white);
            buttons[i].setForeground(Color.black);
            buttons[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
            buttons[i].setBorderPainted(false);  //Remove the border of the button
        }
        buttons[23].setBackground(color2);  // '='key with special color
        keysPanel.setBackground(color1);

        //Place the panel where the text box is located in the north and the keysPanel panel in the middle of the calculator
        frame.getContentPane().add("North", textPanel);
        frame.getContentPane().add("Center", keysPanel);
        //Set the borders of the two panels to restore the win10 calculator as much as possible
        textPanel.setBorder(BorderFactory.createMatteBorder(25,3,1,3,color1));
        keysPanel.setBorder(BorderFactory.createMatteBorder(6,3,3,3,color1));

        // Add event listeners for each button, using the same event listener.
        for (int i = 0; i < keys.length; i++) {
            buttons[i].addActionListener(this);
        }
    }

    /**
     * Handle Events
     */
    public void actionPerformed(ActionEvent ev) {

        String command = ev.getActionCommand();  // Get Event Source
        if (command.equals(keys[3])) {
            // The user pressed the Back key
            doBackspace();
        } else if (command.equals(keys[1])) {
            // The user pressed the CE key
            resultText.setText("0");
        } else if (command.equals(keys[2])) {
            // The user pressed the "C" key
            doC();
        } else if ("0123456789.".indexOf(command) >= 0) {
            // User pressed numeric or decimal key
            doNumber(command);
        } else if(command.equals(keys[0]) || command.equals(keys[4]) || command.equals(keys[5]) ||
                command.equals(keys[6]) || command.equals(keys[20])) {
            // The user pressed an operation key that only needed one number (countdown,%, square, plus or minus)
            doOperator1(command);
        } else {
            doOperator2(command);
        }
    }

    /**
     * Handles the event when the Back key is pressed
     */
    private void doBackspace() {
        String text = resultText.getText();
        int i = text.length();
        if (i > 0) {
            text = text.substring(0, i - 1);  // Backspace removes the last character of the text
            if (text.length() == 0) {
                // Initialize the various values of the calculator if the text is empty
                resultText.setText("0");
                firstDigit = true;
                operator = "=";
            } else {
                // Show new text
                resultText.setText(text);
            }
        }
    }

    /**
     * Handle events when the C key is pressed
     */
    private void doC() {
        // Initialize various values of the calculator
        resultText.setText("0");
        firstDigit = true;
        operator = "=";
    }

    /**
     * Handle events where numeric keys are pressed
     */
    private void doNumber(String key) {
        if (firstDigit) {
            // Input is the first number
            resultText.setText(key);
        } else if ((key.equals(".")) && (resultText.getText().indexOf(".") < 0)) {
            // If you enter a decimal point and there is no decimal point before, append the decimal point to the back of the result text box
            resultText.setText(resultText.getText() + ".");
        } else if (!key.equals(".")) {
            // If you do not enter a decimal point, append the number to the back of the result text box
            resultText.setText(resultText.getText() + key);
        }
        firstDigit = false;
    }

    /**
     * Handles events where operator keys are pressed
     */
    //An operation that requires only one number
    private void doOperator1(String key) {
        operator = key;  // Button pressed by operator for user
        if (operator.equals("1⁄x")) {
            // Reciprocal operation
            if (resultNum == 0) {
                operateValidFlag = false;  //Illegal operation
                resultText.setText("Zero has no reciprocal");
            } else {
                resultNum = 1 / getNumberFromText();
            }
        } else if (operator.equals("√x")) {
            // Square Root Operation
            if (resultNum < 0) {
                operateValidFlag = false;  //Illegal operation
                resultText.setText("Cannot be negative within the root sign");
            } else {
                resultNum = Math.sqrt(getNumberFromText());
            }
        } else if (operator.equals("X²")) {
            // Square operation
            resultNum = getNumberFromText()*getNumberFromText();
        } else if (operator.equals("%")) {
            // Percentage operation, divided by 100
            resultNum = getNumberFromText() / 100;
        } else if (operator.equals("+/-")) {
            // Positive and Negative Operations
            resultNum = getNumberFromText() * (-1);
            if (operateValidFlag) {
                // If the operation is valid, the result is that the last 4 digits of the decimal point are reserved for the decimal number, and the integer is output normally
                long t1;
                double t2;
                t1 = (long) resultNum;
                t2 = resultNum - t1;
                if (t2 == 0) {
                    resultText.setText(String.valueOf(t1));
                } else {
                    resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum)));
                }
            }
            firstDigit = true;
            operateValidFlag = true;
        }
    }

    //An operation that requires two numbers
    private void doOperator2(String key) {
        if (operator.equals("÷")) {
            // Division
            // If the value in the current result text box is equal to 0
            if (getNumberFromText() == 0.0) {
                operateValidFlag = false;  //Illegal operation
                resultText.setText("Divisor can not Be zero");
            } else {
                resultNum /= getNumberFromText();
            }
        } else if (operator.equals("+")) {
            // Addition operation
            resultNum += getNumberFromText();
        } else if (operator.equals("-")) {
            // Subtraction operation
            resultNum -= getNumberFromText();
        } else if (operator.equals("X")) {
            // Multiplication
            resultNum *= getNumberFromText();
        } else if (operator.equals("=")) {
            // Assignment operation
            resultNum = getNumberFromText();
        }
        if (operateValidFlag) {
            // If the operation is valid, the result is that the last 4 digits of the decimal point are reserved for the decimal number, and the integer is output normally
            long t1;
            double t2;
            t1 = (long) resultNum;
            t2 = resultNum - t1;
            if (t2 == 0) {
                resultText.setText(String.valueOf(t1));
            } else {
                resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum)));
            }
        }
        operator = key;  // Button pressed by operator for user
        firstDigit = true;
        operateValidFlag = true;
    }

    /**
     * Get a number from the result text box
     */
    private double getNumberFromText() {
        double result = 0;
        try {
            result = Double.valueOf(resultText.getText()).doubleValue();
        } catch (NumberFormatException e) {
        }
        return result;
    }

    public static void main(String[] args) {
        new Calculator();
    }

}


This experiment is a comprehensive experiment at the end of the school Java course, because the level of writing this program at that time was limited (although it has not been improved a lot now). If there are inappropriate writing, you are welcome to correct ~

Learn together and make progress together ~

Twelve original articles were published. 25 were praised. 4792 were visited
Private letter follow

Tags: calculator Java Programming Windows

Posted on Tue, 11 Feb 2020 19:36:46 -0800 by hedge