Java带有存储文件功能的计算器(Swing)

MVC结构,上一年软件的课设,当时没写出四则运算很难受,现在能写了

废话不说,上代码

CalculatorView类
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;

public class CalculatorView extends JFrame {
    private JTextField display;
    private JTextArea history;
    private JPanel buttonPanel;
    private JScrollPane historyScrollPane;

    public CalculatorView() {
        initUI();
    }

    private void initUI() {
        setTitle("Calculator");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600, 400);
        setLocationRelativeTo(null); // Center the frame

        createDisplayArea();
        createHistoryArea();
        createButtonPanel();

        addComponentsToFrame();

        setVisible(true);
    }

    private void createDisplayArea() {
        display = new JTextField();
        display.setEditable(false);
        display.setFont(new Font("Arial", Font.PLAIN, 24));
        display.setPreferredSize(new Dimension(550, 50));
    }

    private void createHistoryArea() {
        history = new JTextArea(10, 20);
        history.setEditable(false);
        history.setFont(new Font("Arial", Font.PLAIN, 18));
        historyScrollPane = new JScrollPane(history);
        historyScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    }

    private void createButtonPanel() {
        buttonPanel = new JPanel(new GridLayout(6, 4, 10, 10));
        buttonPanel.setPreferredSize(new Dimension(550, 300));

        String[] buttonLabels = {
                "7", "8", "9", "/",
                "4", "5", "6", "*",
                "1", "2", "3", "-",
                "0", ".", "±", "+",
                "(", ")", "←", "=",
                "C", "√", "Save", "Copy"
        };

        for (String label : buttonLabels) {
            JButton button = new JButton(label);
            button.setFont(new Font("Arial", Font.PLAIN, 18));
            buttonPanel.add(button);
        }
    }

    private void addComponentsToFrame() {
        setLayout(new BorderLayout(20, 20));
        add(display, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.CENTER);
        add(historyScrollPane, BorderLayout.EAST);
    }

    public void setDisplayText(String text) {
        display.setText(text);
    }

    public String getDisplayText() {
        return display.getText();
    }

    public void addCalculatorListener(ActionListener listener) {
        for (Component component : buttonPanel.getComponents()) {
            if (component instanceof JButton) {
                ((JButton) component).addActionListener(listener);
            }
        }
    }

    public void updateHistory(String expression, double result) {
        history.append(expression + " = " + result + "\n");
    }
}
CalculatorModel类
private static final String FILE_PATH = " 你文件的地址";

请修改这一段代码,将文件地址复制进去,文件格式是txt

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Stack;
import java.util.StringTokenizer;

public class CalculatorModel {
    private double result;
    private static final String FILE_PATH = " 你文件的地址";

    public CalculatorModel() {}

    public double calculate(String expression) throws Exception {
        String postfixExpression = infixToPostfix(expression);
        result = evaluatePostfix(postfixExpression);
        saveResultToFile(expression, result);
        return result;
    }

    public void saveResultToFile(String expression, double result) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH, true))) {
            writer.write(expression + " = " + result + "\n");
        } catch (IOException e) {
            System.err.println("Error writing to file: " + e.getMessage());
        }
    }

    private String infixToPostfix(String infix) {
        StringBuilder postfix = new StringBuilder();
        Stack<String> stack = new Stack<>();
        StringTokenizer tokenizer = new StringTokenizer(infix, "+-*/()√", true);

        boolean lastWasOperator = true;  // To handle negative numbers

        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken().trim();
            if (token.isEmpty()) {
                continue;
            }

            handleToken(token, postfix, stack, lastWasOperator);
            lastWasOperator = isOperator(token) || token.equals("√");
        }

        while (!stack.isEmpty()) {
            postfix.append(stack.pop()).append(' ');
        }

        return postfix.toString();
    }

    private void handleToken(String token, StringBuilder postfix, Stack<String> stack, boolean lastWasOperator) {
        if (Character.isDigit(token.charAt(0)) || token.equals(".")) {
            postfix.append(token).append(' ');
            lastWasOperator = false;
        } else if (token.equals("(")) {
            stack.push(token);
            lastWasOperator = true;
        } else if (token.equals(")")) {
            while (!stack.isEmpty() && !stack.peek().equals("(")) {
                postfix.append(stack.pop()).append(' ');
            }
            stack.pop();
            lastWasOperator = false;
        } else if (isOperator(token) || token.equals("√")) {
            if (lastWasOperator && token.equals("-")) {
                postfix.append("0 ");
            }
            while (!stack.isEmpty() && precedence(token) <= precedence(stack.peek())) {
                postfix.append(stack.pop()).append(' ');
            }
            stack.push(token);
            lastWasOperator = true;
        }
    }

    private double evaluatePostfix(String postfix) {
        Stack<Double> stack = new Stack<>();
        StringTokenizer tokenizer = new StringTokenizer(postfix);

        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken().trim();
            if (token.isEmpty()) {
                continue;
            }

            handleToken(token, stack);
        }

        return stack.pop();
    }

    private void handleToken(String token, Stack<Double> stack) {
        if (isNumber(token)) {
            stack.push(Double.parseDouble(token));
        } else if (isOperator(token)) {
            double b = stack.pop();
            double a = stack.pop();
            switch (token) {
                case "+":
                    stack.push(a + b);
                    break;
                case "-":
                    stack.push(a - b);
                    break;
                case "*":
                    stack.push(a * b);
                    break;
                case "/":
                    stack.push(a / b);
                    break;
            }
        } else if (token.equals("√")) {
            double a = stack.pop();
            double b = stack.pop();
            stack.push(Math.sqrt(a) * b);
        }
    }

    private boolean isOperator(String token) {
        return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
    }

    private boolean isNumber(String token) {
        try {
            Double.parseDouble(token);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private int precedence(String token) {
        switch (token) {
            case "+":
            case "-":
                return 1;
            case "*":
            case "/":
                return 2;
            case "√":
                return 3;
        }
        return -1;
    }
}

CalculatorController类
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CalculatorController {
    private CalculatorModel model;
    private CalculatorView view;
    private StringBuilder currentInput;
    private String lastExpression;

    public CalculatorController(CalculatorModel model, CalculatorView view) {
        if (model == null || view == null) {
            throw new IllegalArgumentException("Model and View cannot be null.");
        }
        this.model = model;
        this.view = view;
        this.currentInput = new StringBuilder();
        this.lastExpression = "";
        this.view.addCalculatorListener(new CalculatorListener());
    }

    private class CalculatorListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();

            switch (command) {
                case "C":
                    resetInput();
                    break;
                case "±":
                    toggleSign();
                    break;
                case "←":
                    deleteLastChar();
                    break;
                case "=":
                    calculateExpression();
                    break;
                case "√":
                    addSquareRoot();
                    break;
                case "Save":
                    saveResultToHistory();
                    break;
                case "Copy":
                    copyToClipboard();
                    break;
                default:
                    appendInput(command);
                    break;
            }
        }
    }

    private void resetInput() {
        currentInput.setLength(0);
        view.setDisplayText("");
    }

    private void toggleSign() {
        if (currentInput.length() > 0) {
            if (currentInput.charAt(0) == '-') {
                currentInput.deleteCharAt(0);
            } else {
                currentInput.insert(0, '-');
            }
            view.setDisplayText(currentInput.toString());
        }
    }

    private void deleteLastChar() {
        if (currentInput.length() > 0) {
            currentInput.deleteCharAt(currentInput.length() - 1);
            view.setDisplayText(currentInput.toString());
        }
    }

    private void calculateExpression() {
        try {
            String expression = currentInput.toString();
            double result = model.calculate(expression);
            view.setDisplayText(String.valueOf(result));
            saveResultToHistory(expression, result);
            currentInput.setLength(0);
            currentInput.append(result);
        } catch (Exception ex) {
            view.setDisplayText("Error");
            currentInput.setLength(0);
        }
    }

    private void addSquareRoot() {
        currentInput.append("√");
        view.setDisplayText(currentInput.toString());
    }

    private void saveResultToHistory() {
        String expression = currentInput.toString();
        double saveResult = Double.parseDouble(view.getDisplayText());
        if (!expression.equals(String.valueOf(saveResult)) && !expression.equals(lastExpression)) {
            model.saveResultToFile(expression, saveResult);
            view.updateHistory(expression, saveResult);
            lastExpression = expression;
        }
    }

    private void copyToClipboard() {
        StringSelection selection = new StringSelection(view.getDisplayText());
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
    }

    private void appendInput(String command) {
        currentInput.append(command);
        view.setDisplayText(currentInput.toString());
    }

    private void saveResultToHistory(String expression, double result) {
        if (!expression.equals(lastExpression)) {
            model.saveResultToFile(expression, result);
            view.updateHistory(expression, result);
            lastExpression = expression;
        }
    }
}
CalculatorMain类
import javax.swing.SwingUtilities;

public class CalculatorMain {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            CalculatorModel model = new CalculatorModel();
            CalculatorView view = new CalculatorView();
            new CalculatorController(model, view);
            view.setVisible(true);
        });
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小艾yi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值