Building a Calculator Based On Java Swing

Building a Calculator Based On Java Swing

Introduction

In the digital age, graphical user interfaces (GUIs) are essential. Java Swing, a prominent framework, facilitates interactive and visually appealing applications. A fundamental and instructive example is the web-based calculator. Building it from scratch enhances GUI development and highlights software engineering principles. This article explores Java Swing, emphasizing its significance in creating a functional web-based calculator while briefly addressing software engineering practices for code maintainability and scalability. It offers insights for both novice and experienced developers, bridging Java Swing GUI development and software engineering.

Information Table

内容链接
课程班级链接https://bbs.csdn.net/forums/ssynkqtd-04
本次作业要求链接https://bbs.csdn.net/topics/617332156
本次作业目标可视化计算器
梅努斯(MU)学号 和 福州大学(FZU)学号21144257(MU)/832102128(FZU)

Link to Github: https://github.com/Saiph77/Software-Enginer

Project Process

PSP Form

Personal Software Process StagesEstimated Time (minutes)Actual Time (minutes)
Planning
• Estimate6060
Development
• Analysis3060
• Design Spec3030
• Design Review3030
• Coding Standard1515
• Design60120
• Coding90120
• Code Review3030
• Test3030
Reporting
• Test Report1515
• Size Measurement1515
• Postmortem & Process Improvement Plan6060
Sum465585

Description of Problem-Solving Ideas

Layout Issues

When developing user interface applications with Java Swing, you may encounter challenges in arranging and sizing Swing components, especially in complex layouts.

Solution: Utilize layout managers such as BorderLayout, FlowLayout, and GridLayout to automate component positioning. Choose an appropriate layout manager that suits your specific UI design requirements.

Thread Safety Concerns:

Swing components should be accessed and manipulated on the Event Dispatch Thread (EDT). Modifying UI components on non-EDT threads can lead to unpredictable issues.

Solution: Ensure that UI operations are executed on the EDT using methods like SwingUtilities.invokeLater() or SwingUtilities.invokeAndWait() to maintain thread safety.

Performance Problems:

Complex Swing interfaces can result in performance degradation, leading to slower responsiveness or increased memory usage.

Solution: Implement Swing’s lightweight components, reduce unnecessary rendering operations, and apply techniques like double buffering to enhance performance.

Cross-Platform Look and Feel:

Swing interfaces may look different on various platforms, causing UI inconsistencies across different operating systems.

Solution: Select and set a Swing Look and Feel (L&F) manager to maintain a consistent appearance across platforms. Options include Metal, Nimbus, and others.

Event Handling Challenges:

Managing user input and events can become complex, especially when dealing with multiple components and interactions.

Solution: Use appropriate design patterns such as the Observer pattern to manage and handle events effectively. Break down related code into smaller, reusable methods and classes to improve code readability and maintainability.

Focus Management Issues:

Managing the focus control within your application, especially in scenarios with multiple components, can be challenging.

Solution: Use methods like requestFocus() or employ FocusTraversalPolicy to define the focus traversal order for components, ensuring an organized focus management approach.

Custom Drawing Challenges:

If you need to perform custom drawing on Swing components, you may need to address drawing logic and performance optimization.

Solution: Extend Swing components and override the paintComponent() method for custom drawing. Implement double buffering and other performance-enhancing techniques to achieve smooth custom rendering.

Design and Implementation Process

Design

The design of the calculator focused on creating a clean and user-friendly interface.
Java Swing is well-suited for building basic calculator graphical user interfaces (GUIs) due to its cross-platform compatibility, user-friendliness, built-in layout managers, event handling capabilities, extensive documentation, and scalability for more advanced GUI applications.

flowchart for Java Swing code:
+-------------------+
|   Start Program  |
+-------------------+
         |
         v
+-------------------+
|   Create JFrame   |
+-------------------+
         |
         v
+-------------------+
|   Create Components |
+-------------------+
         |
         v
+-------------------+
|   Set Layout Manager |
+-------------------+
         |
         v
+-------------------+
|   Add Event Listeners |
+-------------------+
         |
         v
+-------------------+
|   Implement Logic  |
+-------------------+
         |
         v
+-------------------+
|   Display JFrame   |
+-------------------+
         |
         v
+-------------------+
|   End Program      |
+-------------------+
flowchart for calculator:

在这里插入图片描述

Code Description

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

class Calculator extends JFrame {
    private JTextField textfield;
    private boolean number = true;
    private String equalOp = "=";
    private CalculatorOp op = new CalculatorOp();


    private final Font BIGGER_FONT = new Font("monspaced", Font.PLAIN, 20);


    public Calculator() {
        // Create a textfield for displaying input and results
        textfield = new JTextField("", 12);
        textfield.setHorizontalAlignment(JTextField.RIGHT);
        textfield.setFont(BIGGER_FONT);

        // Create an ActionListener for handling number button clicks
        ActionListener numberListener = new NumberListener();

        // Define the order of buttons for numbers and a space
        String buttonOrder = "1234567890 ";

        // Create a JPanel for the number buttons
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(4, 4, 4, 4));

        // Loop through the buttonOrder string to create buttons
        for (int i = 0; i < buttonOrder.length(); i++) {
            String key = buttonOrder.substring(i, i + 1);
            if (key.equals(" ")) {
                buttonPanel.add(new JLabel(""));
            } else {
                JButton button = new JButton(key);
                button.addActionListener(numberListener);
                button.setFont(BIGGER_FONT);
                buttonPanel.add(button);
            }
        }

        // Create an ActionListener for handling operator button clicks
        ActionListener operatorListener = new OperatorListener();

        // Create a JPanel for the operator buttons
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(4, 4, 4, 4));

        // Define the order of operator buttons
        String[] opOrder = {"+", "-", "*", "/", "=", "C", "sin", "cos", "log"};

        // Loop through the opOrder array to create operator buttons
        for (int i = 0; i < opOrder.length; i++) {
            JButton button = new JButton(opOrder[i]);
            button.addActionListener(operatorListener);
            button.setFont(BIGGER_FONT);
            panel.add(button);
        }

        // Create a main JPanel to organize the components
        JPanel pan = new JPanel();
        pan.setLayout(new BorderLayout(4, 4));

        // Add the textfield to the top of the main panel
        pan.add(textfield, BorderLayout.NORTH);

        // Add the number buttons panel to the center of the main panel
        pan.add(buttonPanel, BorderLayout.CENTER);

        // Add the operator buttons panel to the right of the main panel
        pan.add(panel, BorderLayout.EAST);

        // Set the main panel as the content pane of the calculator frame
        this.setContentPane(pan);

        // Set frame properties
        this.pack();
        this.setTitle("Calculator");
        this.setResizable(false);
    }

    private void action() {
        // Set the "number" flag to true, indicating that a number input is expected.
        number = true;

        // Clear the textfield.
        textfield.setText("");

        // Set the "equalOp" variable to "=" to prepare for a new operation.
        equalOp = "=";

        // Reset the operator object's total value.
        op.setTotal("");
    }

    class OperatorListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            // Get the current text from the textfield.
            String displayText = textfield.getText();

            // Check if the clicked button is the "sin" operator.
            if (e.getActionCommand().equals("sin")) {
                // Calculate the sine of the input value and display it.
                textfield.setText("" + Math.sin(Double.valueOf(displayText).doubleValue()));
            } else if (e.getActionCommand().equals("cos")) {
                // Calculate the cosine of the input value and display it.
                textfield.setText("" + Math.cos(Double.valueOf(displayText).doubleValue()));
            } else if (e.getActionCommand().equals("log")) {
                // Calculate the natural logarithm of the input value and display it.
                textfield.setText("" + Math.log(Double.valueOf(displayText).doubleValue()));
            } else if (e.getActionCommand().equals("C")) {
                // Clear the textfield when the "C" (Clear) button is clicked.
                textfield.setText("");
            } else {
                if (number) {
                    // If a number is expected, perform necessary actions and clear the textfield.
                    action();
                    textfield.setText("");
                } else {
                    number = true;

                    // Handle different operators based on the previous operator ("equalOp").
                    if (equalOp.equals("=")) {
                        op.setTotal(displayText);
                    } else if (equalOp.equals("+")) {
                        op.add(displayText);
                    } else if (equalOp.equals("-")) {
                        op.subtract(displayText);
                    } else if (equalOp.equals("*")) {
                        op.multiply(displayText);
                    } else if (equalOp.equals("/")) {
                        op.divide(displayText);
                    }

                    // Display the result of the operation in the textfield.
                    textfield.setText("" + op.getTotalString());

                    // Update the "equalOp" variable with the current operator.
                    equalOp = e.getActionCommand();
                }
            }
        }
    }

    class NumberListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            // Get the digit (button label) that triggered the event.
            String digit = event.getActionCommand();

            // If a number is expected, set the textfield to the digit and mark that a number has been entered.
            if (number) {
                textfield.setText(digit);
                number = false;
            } else {
                // If there is already content in the textfield, append the digit to it.
                textfield.setText(textfield.getText() + digit);
            }
        }
    }

    public class CalculatorOp {
        private int total;

        // Set the total to the converted value of the provided string.
        public void setTotal(String n) {
            total = convertToNumber(n);
        }

        // Add the converted value of the provided string to the total.
        public void add(String n) {
            total += convertToNumber(n);
        }

        // Subtract the converted value of the provided string from the total.
        public void subtract(String n) {
            total -= convertToNumber(n);
        }

        // Multiply the total by the converted value of the provided string.
        public void multiply(String n) {
            total *= convertToNumber(n);
        }

        // Divide the total by the converted value of the provided string.
        public void divide(String n) {
            total /= convertToNumber(n);
        }

        // Convert a string to an integer.
        private int convertToNumber(String n) {
            return Integer.parseInt(n);
        }

        // Initialize the total to 0 when an instance of CalculatorOp is created.
        public CalculatorOp() {
            total = 0;
        }

        // Get the current total as a string.
        public String getTotalString() {
            return "" + total;
        }
    }
}

class SwingCalculator {
    public static void main(String[] args) {
        // Create a JFrame using the Calculator class, set it to be visible, and define the close operation.
        JFrame frame = new Calculator();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Displaying Result Functions

软工实践作业1

The video above shows the calculator’s user interface. Users can input mathematical expressions, trigonometric functions, and perform calculations. The display area shows both input and results.

Summary

In this assignment, we successfully designed and implemented a feature-rich calculator using Java Swing components. It supports basic arithmetic operations as well as advanced functions like trigonometry and degrees-to-radians conversion. We followed a structured development process, including planning, design, coding, and testing.

Building this calculator helped solidify key Java graphical user interface (GUI) development skills. It also emphasized problem-solving abilities and the importance of effective planning and documentation in software development.

This project serves as a valuable example of creating interactive Java applications, showcasing the powerful capabilities of Java in GUI programming.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值