接上贴,一个Java的问题

这个计算器已经有比较完善了,但是有一个问题一直无法解决。

就是这个计算器在开始运行的时候,没有任何数字的时候无法加入“加减乘除”,所以也就无法计算负数,请问如何修改才能是实现,计算负数

代码贴这里了,感谢大佬有空看看

package MYM;

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

public class MYM {
    private JFrame frame;
    private JTextField textField;
    private String currentInput = "";
    private boolean lastWasOperator = false;

    public MYM() {
        frame = new JFrame("Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 500);
        frame.setLayout(new BorderLayout());

        textField = new JTextField();
        textField.setFont(new Font("Arial", Font.PLAIN, 24));
        textField.setEditable(false);
        textField.setHorizontalAlignment(JTextField.RIGHT);
        frame.add(textField, BorderLayout.NORTH);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(5, 4, 5, 5));  // Added gaps between buttons

        String[] buttons = {
            "7", "8", "9", "/",
            "4", "5", "6", "*",
            "1", "2", "3", "-",
            "0", ".", "=", "+",
            "C", "←"
        };

        for (String label : buttons) {
            JButton button = new JButton(label);
            button.setFont(new Font("Arial", Font.PLAIN, 24));
            button.addActionListener(new ButtonClickListener());
            
            // Style the buttons
            if (label.matches("[0-9.]")) {
                button.setBackground(new Color(240, 240, 240));
            } else if (label.equals("=")) {
                button.setBackground(new Color(100, 149, 237));
                button.setForeground(Color.WHITE);
            } else if (label.equals("C") || label.equals("←")) {
                button.setBackground(new Color(255, 160, 122));
            } else {
                button.setBackground(new Color(220, 220, 220));
            }
            
            button.setFocusPainted(false);
            panel.add(button);
        }

        // Add empty buttons to fill the last row
        for (int i = 0; i < 2; i++) {
            JButton emptyButton = new JButton();
            emptyButton.setEnabled(false);
            emptyButton.setBackground(panel.getBackground());
            panel.add(emptyButton);
        }

        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        frame.add(panel, BorderLayout.CENTER);
        frame.setVisible(true);
    }

    private class ButtonClickListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();
            
            if (command.equals("=")) {
                // Before evaluating, ensure that the number is properly formatted
                if (!currentInput.isEmpty() && !lastWasOperator) {
                    try {
                        currentInput = evaluateExpression(currentInput);
                        textField.setText(currentInput);
                    } catch (Exception ex) {
                        textField.setText("Error");
                        currentInput = "";
                    }
                }
            } else if (command.equals("C")) {
                currentInput = "";
                textField.setText(currentInput);
                lastWasOperator = false;
            } else if (command.equals("←")) {
                if (!currentInput.isEmpty()) {
                    currentInput = currentInput.substring(0, currentInput.length() - 1);
                    if (!currentInput.isEmpty()) {
                        lastWasOperator = isOperator(currentInput.charAt(currentInput.length() - 1));
                    } else {
                        lastWasOperator = false;
                    }
                    textField.setText(currentInput);
                }
            } else if (isOperator(command.charAt(0))) {
                // If the current input ends with a decimal point, we add '0'
                if (currentInput.endsWith(".")) {
                    currentInput += "0";
                }
                // Check if the previous character is an operator or the input is empty
                if (!currentInput.isEmpty() && !lastWasOperator) {
                    currentInput += command;
                    textField.setText(currentInput);
                    lastWasOperator = true;
                }
            } else {
                if (command.equals(".")) {
                    // 如果输入小数点且当前输入中没有小数点,并且当前数字部分没有小数点,则允许添加
                    int lastOperatorPos = findLastOperator(currentInput);
                    String lastNumber = currentInput.substring(lastOperatorPos + 1);

                    // 如果数字部分没有小数点
                    if (!lastNumber.contains(".")) {
                        // 如果小数点前没有数字(例如操作符前、或者输入空白),补充0
                        if (lastNumber.isEmpty()) {
                            currentInput += "0";
                        }
                        currentInput += command;
                    }
                } else {
                    // Special handling for negative sign (-)
                    if (command.equals("-")) {
                        // If the input is empty, or the last character is an operator, treat "-" as negative sign
                        if (currentInput.isEmpty() || isOperator(currentInput.charAt(currentInput.length() - 1))) {
                            currentInput += command;
                        } else {
                            currentInput += command;
                        }
                    } else {
                        currentInput += command;
                    }
                }
                textField.setText(currentInput);
                lastWasOperator = false;
            }
        }
    }

    private boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    // 找到最后一个操作符的位置
    private int findLastOperator(String expression) {
        int lastOperatorPos = -1;
        for (int i = expression.length() - 1; i >= 0; i--) {
            if (isOperator(expression.charAt(i))) {
                lastOperatorPos = i;
                break;
            }
        }
        return lastOperatorPos;
    }

    private String evaluateExpression(String expression) {
        try {
            double result = evaluate(expression);
            // Format the result to remove unnecessary decimal places
            if (result == (long) result) {
                return String.format("%d", (long) result);
            } else {
                return String.format("%.8f", result).replaceAll("0*$", "").replaceAll("\\.$", "");
            }
        } catch (Exception e) {
            return "Error";
        }
    }

    private double evaluate(String expression) {
        Stack<Double> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();
        
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            
            if (Character.isDigit(c) || c == '.') {
                StringBuilder num = new StringBuilder();
                while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                    num.append(expression.charAt(i));
                    i++;
                }
                i--;
                numbers.push(Double.parseDouble(num.toString()));
            } else if (isOperator(c)) {
                while (!operators.empty() && hasPrecedence(c, operators.peek())) {
                    numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
                }
                operators.push(c);
            }
        }
        
        while (!operators.empty()) {
            numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
        }
        
        return numbers.pop();
    }

    private boolean hasPrecedence(char op1, char op2) {
        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return false;
        return true;
    }

    private double applyOperation(char operator, double b, double a) {
        switch (operator) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/': 
                if (b == 0) throw new ArithmeticException("Division by zero");
                return a / b;
        }
        return 0;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MYM());
    }
}

            if (!currentInput.isEmpty() && !lastWasOperator) {
                currentInput += command;
                textField.setText(currentInput);
                lastWasOperator = true;
            }

if中的第一个条件导致第一个字符无法输入操作符

感谢,我去试试

如果刚开始学觉得比较复杂 可以直接丢给AI让他帮你看

试着丢了,但是一直运行不了,原因是上面那个限制了,但是AI不明白 :sob:

我去……Swing,这是国外大学 Java 作业吧(

课外作业。

楼主解决这个问题了吗?

我的解决方法是:打开计算器时默认缺省值是0,这样用户的输入第一个字符有且仅有三种情况:
1. 操作符:+、-、*、/时,是0+、-、*、/,这样,例如0-5= -5,于是就得到-5了;
2. 小数点:. 时,是0.这样,例如0.5,于是得到就是小数;
3. 数字:[0-9]时,这时需要将[0-9]覆盖那个0。

第一个字符后,剩余的逻辑就和楼主的原程序一致了。

当输入了一段expression时,按C和⬅,当expression被清空时,需保证缺省值为0。

代码如下,如果有错或者有改进的地方,请多多指正:
```package MYM;

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

public class MYM {
    private JFrame frame;
    private JTextField textField;
    private String currentInput = "0";
    private boolean lastWasOperator = false;

    public MYM() {
        frame = new JFrame("Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 500);
        frame.setLayout(new BorderLayout());

        textField = new JTextField();
        textField.setFont(new Font("Arial", Font.PLAIN, 24));
        textField.setEditable(false);
        textField.setHorizontalAlignment(JTextField.RIGHT);
        frame.add(textField, BorderLayout.NORTH);
        textField.setText(currentInput);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(5, 4, 5, 5));  // Added gaps between buttons

        String[] buttons = {
                "7", "8", "9", "/",
                "4", "5", "6", "*",
                "1", "2", "3", "-",
                "0", ".", "=", "+",
                "C", "←"
        };

        for (String label : buttons) {
            JButton button = new JButton(label);
            button.setFont(new Font("Arial", Font.PLAIN, 24));
            button.addActionListener(new ButtonClickListener());

            // Style the buttons
            if (label.matches("[0-9.]")) {
                button.setBackground(new Color(240, 240, 240));
            } else if (label.equals("=")) {
                button.setBackground(new Color(100, 149, 237));
                button.setForeground(Color.WHITE);
            } else if (label.equals("C") || label.equals("←")) {
                button.setBackground(new Color(255, 160, 122));
            } else {
                button.setBackground(new Color(220, 220, 220));
            }

            button.setFocusPainted(false);
            panel.add(button);
        }

        // Add empty buttons to fill the last row
        for (int i = 0; i < 2; i++) {
            JButton emptyButton = new JButton();
            emptyButton.setEnabled(false);
            emptyButton.setBackground(panel.getBackground());
            panel.add(emptyButton);
        }

        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        frame.add(panel, BorderLayout.CENTER);
        frame.setVisible(true);
    }

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

            if (command.equals("=")) {
                // Before evaluating, ensure that the number is properly formatted
                if (!currentInput.isEmpty() && !lastWasOperator) {
                    try {
                        currentInput = evaluateExpression(currentInput);
                        textField.setText(currentInput);
                    } catch (Exception ex) {
                        textField.setText("Error");
                        currentInput = "";
                    }
                }
            } else if (command.equals("C")) {
                currentInput = "0";
                textField.setText(currentInput);
                lastWasOperator = false;
            } else if (command.equals("←")) {
                if (!currentInput.isEmpty()) {
                    currentInput = currentInput.substring(0, currentInput.length() - 1);
                    if (!currentInput.isEmpty()) {
                        lastWasOperator = isOperator(currentInput.charAt(currentInput.length() - 1));
                    } else {
                        currentInput = "0";
                        textField.setText(currentInput);
                        lastWasOperator = false;
                    }
                    textField.setText(currentInput);
                }
            } else if (isOperator(command.charAt(0))) {
                // If the current input ends with a decimal point, we add '0'
                if (currentInput.endsWith(".")) {
                    currentInput += "0";
                }
                // Check if the previous character is an operator or the input is empty
                if (!currentInput.isEmpty() && !lastWasOperator) {
                    currentInput += command;
                    textField.setText(currentInput);
                    lastWasOperator = true;
                }
            } else {
                if (command.equals(".")) {
                    // 如果输入小数点且当前输入中没有小数点,并且当前数字部分没有小数点,则允许添加
                    int lastOperatorPos = findLastOperator(currentInput);
                    String lastNumber = currentInput.substring(lastOperatorPos + 1);

                    // 如果数字部分没有小数点
                    if (!lastNumber.contains(".")) {
                        // 如果小数点前没有数字(例如操作符前、或者输入空白),补充0
                        if (lastNumber.isEmpty()) {
                            currentInput += "0";
                        }
                        currentInput += command;
                    }
                } else {
//                    // Special handling for negative sign (-)
//                    if (command.equals("-")) {
//                        // If the input is empty, or the last character is an operator, treat "-" as negative sign
//                        if (currentInput.isEmpty() || isOperator(currentInput.charAt(currentInput.length() - 1))) {
//                            currentInput += command;
//                        } else {
//                            currentInput += command;
//                        }
//                    } else {
//                        currentInput += command;
//                    }
                    if (currentInput == "0") {
                        if (command.matches("[0-9]")) {
                            currentInput = command;
                        }
                    } else {
                        currentInput += command;
                    }
                }
                textField.setText(currentInput);
                lastWasOperator = false;
            }
        }
    }

    private boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    // 找到最后一个操作符的位置
    private int findLastOperator(String expression) {
        int lastOperatorPos = -1;
        for (int i = expression.length() - 1; i >= 0; i--) {
            if (isOperator(expression.charAt(i))) {
                lastOperatorPos = i;
                break;
            }
        }
        return lastOperatorPos;
    }

    private String evaluateExpression(String expression) {
        try {
            double result = evaluate(expression);
            // Format the result to remove unnecessary decimal places
            if (result == (long) result) {
                return String.format("%d", (long) result);
            } else {
                return String.format("%.8f", result).replaceAll("0*$", "").replaceAll("\\.$", "");
            }
        } catch (Exception e) {
            return "Error";
        }
    }

    private double evaluate(String expression) {
        Stack<Double> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);

            if (Character.isDigit(c) || c == '.') {
                StringBuilder num = new StringBuilder();
                while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                    num.append(expression.charAt(i));
                    i++;
                }
                i--;
                numbers.push(Double.parseDouble(num.toString()));
            } else if (isOperator(c)) {
                while (!operators.empty() && hasPrecedence(c, operators.peek())) {
                    numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
                }
                operators.push(c);
            }
        }

        while (!operators.empty()) {
            numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
        }

        return numbers.pop();
    }

    private boolean hasPrecedence(char op1, char op2) {
        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return false;
        return true;
    }

    private double applyOperation(char operator, double b, double a) {
        switch (operator) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            case '/':
                if (b == 0) throw new ArithmeticException("Division by zero");
                return a / b;
        }
        return 0;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MYM());
    }
}

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。