package Calculator;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
public class Calculator implements ActionListener {
    private JFrame frame = new JFrame();
    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];  
    private JTextField resultText = new JTextField("0");  
    private boolean firstDigit = true;  
    private double resultNum = 0.0000;   
    private String operator = "=";
    private boolean operateValidFlag = true;
    public Calculator() {
        init();  
        frame.setTitle("计算器 -- @author 姜远仁");
        frame.setSize(366, 439);
        frame.setLocation(500, 300);
        frame.setResizable(true);  
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void init() {
        Color color1 = new Color(181, 181, 181); 
        Color color2 = new Color(126, 192, 238);  
        Color color3 = new Color(232, 232, 232); 
        JPanel textPanel = new JPanel();
        textPanel.setLayout(new BorderLayout());
        textPanel.add(resultText);
        resultText.setFont(new Font("楷体",Font.BOLD,43)); 
        resultText.setHorizontalAlignment(JTextField.RIGHT);  
        resultText.setEditable(false); 
        resultText.setBorder(null);
        resultText.setBackground(color1);
        JPanel keysPanel = new JPanel();
        keysPanel.setLayout(new GridLayout(6, 4, 2, 2));
        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); 
        }
        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);
        }
        buttons[23].setBackground(color2); 
        keysPanel.setBackground(color1);
        frame.getContentPane().add("North", textPanel);
        frame.getContentPane().add("Center", keysPanel);
        textPanel.setBorder(BorderFactory.createMatteBorder(25,3,1,3,color1));
        keysPanel.setBorder(BorderFactory.createMatteBorder(6,3,3,3,color1));
        for (int i = 0; i < keys.length; i++) {
            buttons[i].addActionListener(this);
        }
    }
    public void actionPerformed(ActionEvent ev) {
        String command = ev.getActionCommand();  
        if (command.equals(keys[3])) {
            doBackspace();
        } else if (command.equals(keys[1])) {
            resultText.setText("0");
        } else if (command.equals(keys[2])) {
            doC();
        } else if ("0123456789.".indexOf(command) >= 0) {
            doNumber(command);
        } else if(command.equals(keys[0]) || command.equals(keys[4]) || command.equals(keys[5]) ||
                command.equals(keys[6]) || command.equals(keys[20])) {
            doOperator1(command);
        } else {
            doOperator2(command);
        }
    }
    private void doBackspace() {
        String text = resultText.getText();
        int i = text.length();
        if (i > 0) {
            text = text.substring(0, i - 1); 
            if (text.length() == 0) {
                resultText.setText("0");
                firstDigit = true;
                operator = "=";
            } else {
                resultText.setText(text);
            }
        }
    }
    private void doC() {
        resultText.setText("0");
        firstDigit = true;
        operator = "=";
    }
    private void doNumber(String key) {
        if (firstDigit) {
            resultText.setText(key);
        } else if ((key.equals(".")) && (resultText.getText().indexOf(".") < 0)) {
            resultText.setText(resultText.getText() + ".");
        } else if (!key.equals(".")) {
            resultText.setText(resultText.getText() + key);
        }
        firstDigit = false;
    }
    private void doOperator1(String key) {
        operator = key; 
        if (operator.equals("1⁄x")) {
            if (resultNum == 0) {
                operateValidFlag = false;  
                resultText.setText("零没有倒数");
            } else {
                resultNum = 1 / getNumberFromText();
            }
        } else if (operator.equals("√x")) {
            if (resultNum < 0) {
                operateValidFlag = false;  
                resultText.setText("根号内不能为负");
            } else {
                resultNum = Math.sqrt(getNumberFromText());
            }
        } else if (operator.equals("X²")) {
            resultNum = getNumberFromText()*getNumberFromText();
        } else if (operator.equals("%")) {
            resultNum = getNumberFromText() / 100;
        } else if (operator.equals("+/-")) {
            resultNum = getNumberFromText() * (-1);
            if (operateValidFlag) {
                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;
        }
    }
    private void doOperator2(String key) {
        if (operator.equals("÷")) {
            if (getNumberFromText() == 0.0) {
                operateValidFlag = false;  
                resultText.setText("除数不能为零");
            } else {
                resultNum /= getNumberFromText();
            }
        } else if (operator.equals("+")) {
            resultNum += getNumberFromText();
        } else if (operator.equals("-")) {
            resultNum -= getNumberFromText();
        } else if (operator.equals("X")) {
            resultNum *= getNumberFromText();
        } else if (operator.equals("=")) {
            resultNum = getNumberFromText();
        }
        if (operateValidFlag) {
            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; 
        firstDigit = true;
        operateValidFlag = true;
    }
    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();
    }
}