diff --git a/src/calculator/Calculator.java b/src/calculator/Calculator.java new file mode 100644 index 0000000000000000000000000000000000000000..678032418afc529a2576fc36f8eabc5ca486e54e --- /dev/null +++ b/src/calculator/Calculator.java @@ -0,0 +1,287 @@ +package calculator; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class Calculator extends JFrame implements ActionListener{ + + private JPanel jp_north = new JPanel(); + private JTextField input_text = new JTextField(); + private StringBuilder input_str = new StringBuilder(); + + + /** + * 记忆的数值 + */ + private BigDecimal lastValue; + + /** + * 选中的的操作符 + */ + private String memoryOperation; + + /** + * M操作中记忆的数值 + */ + private BigDecimal memoryValue = new BigDecimal(0); + + + + private JPanel jp_center = new JPanel(); + public Calculator() throws HeadlessException{ + this.init(); + this.addNorthComponent(); + this.addCenterButton(); + this.input_text.setHorizontalAlignment(JTextField.RIGHT); + flushPanel(); + } + + /** + * 刷新界面 + * 有操作符,可能会需要刷新界面 + */ + private void flushPanel() { + // 默认给个0 + input_text.setText("0"); + // 避免没有值的情况发生 + if (input_str.length() == 0) { + input_str.append("0"); + } + } + + /** + * 初始化加载 + */ + public void init() { + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setTitle("java计算器"); + this.setSize(300,550); + this.setLayout(new BorderLayout()); + this.setResizable(false); + input_text.setEditable(false); + + } + + + public void addNorthComponent() { + this.input_text.setPreferredSize(new Dimension(280,50)); + jp_north.add(input_text); + + this.add(jp_north,BorderLayout.NORTH); + + } + + public void addCenterButton() { + String btn_text[] = {"Backspace","CE","C","/", + "7","8","9","*", + "4","5","6","-", + "1","2","3","+", + "0","+/-",".","=", + "Sqrt","MC","MR","%", + "MS","M+"," ","1/x", + }; + + this.jp_center.setLayout(new GridLayout(7,4)); + for(int i=0;i<28;i++) { + JButton btn = new JButton(btn_text[i]); + btn.addActionListener(this); + jp_center.add(btn); + } + this.add(jp_center,BorderLayout.CENTER); + } + + public static void main (String[] args) { + Calculator calculator = new Calculator(); + calculator.setVisible(true); + + } + + + @Override + public void actionPerformed(ActionEvent e) { + // 点击事件 + String clickStr = e.getActionCommand(); + // 这些是数值,允许自由输入 + if(mightNumber(clickStr)) { + // 看看要不要删除开头的0,如果开头就是0,加了个小数点,其实这个0为了好看要保留下来 + if (input_str.length() == 1 && input_str.charAt(0) == '0') { + if (!".".equals(clickStr)) { + input_str.deleteCharAt(0); + } + } + this.input_str.append(clickStr); + } + // 退格 + else if ("Backspace".equals(clickStr)){ + backspace(); + return; + } + // 清屏 + else if ("C".equals(clickStr)){ + this.input_str = new StringBuilder(); + this.lastValue = new BigDecimal("0"); + this.memoryOperation = ""; + flushPanel(); + return; + } + // 清空这一步的输入 + else if ("CE".equals(clickStr)) { + this.input_str = new StringBuilder(); + flushPanel(); + return; + } + // 正负切换 + else if ("+/-".equals(clickStr)) { + // 正负切换 + input_str = new StringBuilder(new BigDecimal(input_str.toString()).negate().toString()); + } + // 平方根 + else if ("Sqrt".equals(clickStr)){ + double sqrt = Math.sqrt(Double.parseDouble(input_str.toString())); + // 保留四位小数 + input_str = new StringBuilder(new BigDecimal(sqrt).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString()); + } + // 当前数值百分比,用数值除以100 + else if ("%".equals(clickStr)) { + input_str = new StringBuilder( + new BigDecimal(input_str.toString()) + // 四舍五入保留四位小数,并去掉末尾的0 + .divide(new BigDecimal(100), 4, RoundingMode.HALF_UP) + .toPlainString() + ); + } + // 倒数,用1除以数值 + else if ("1/x".equals(clickStr)) { + input_str = new StringBuilder( + new BigDecimal(1) + // 四舍五入保留四位小数,并去掉末尾的0 + .divide(new BigDecimal(input_str.toString()), 4, RoundingMode.HALF_UP) + .toPlainString() + ); + } + // 将存储的值加上计算后的值,其实就是加上当前显示的值 + else if ("M+".equals(clickStr)) { + memoryValue = memoryValue.add(new BigDecimal(input_str.toString())); + return; + } + // M记忆值清空 + else if ("MC".equals(clickStr)) { + memoryValue = new BigDecimal(0); + } + // 将记忆的数值呈现出来 + else if ("MR".equals(clickStr)) { + input_str = new StringBuilder(memoryValue.toString()); + } + // 直接以当前数字取代记忆中的数字 + else if ("MS".equals(clickStr)) { + memoryValue = new BigDecimal(input_str.toString()); + return; + } + // 四则运算 + else if ("/".equals(clickStr) || "+".equals(clickStr) || "-".equals(clickStr) || "*".equals(clickStr)) { + // 要重新设置记忆的值 + flushMemoryValue(); + // 记忆操作符 + memoryOperation = clickStr; + input_str = new StringBuilder(); + // 清屏 + flushPanel(); + return; + } + // 计算结果了 + else if ("=".equals(clickStr)) { + String result = getResult(); + // 计算完结果之后直接返回 + this.input_str = new StringBuilder(result); + } + + this.input_text.setText(input_str.toString()); + } + + + /** + * 计算值 + * 通过记忆数和当前数,以及操作符的运算,可以得到结果 + * + * @return 得到的结果,字符串形式 + */ + private String getResult() { + BigDecimal nowValue = new BigDecimal(this.input_str.toString()); + switch (memoryOperation) { + case "+": + lastValue = lastValue.add(nowValue); + break; + case "-": + lastValue = lastValue.subtract(nowValue); + break; + case "*": + // 四舍五入保留四位小数,并去掉末尾的0 + lastValue = lastValue.multiply(nowValue).setScale(4 , RoundingMode.HALF_UP).stripTrailingZeros(); + break; + case "/": + // 四舍五入保留四位小数,并去掉末尾的0 + lastValue = lastValue.divide(nowValue,4 , RoundingMode.HALF_UP).stripTrailingZeros(); + break; + default: + break; + } + return lastValue.toString(); + } + + + /** + * 刷新记忆的值,直接使用现有的值即可 + */ + private void flushMemoryValue() { + lastValue = new BigDecimal(input_str.toString()); + } + + /** + * 退格 + */ + private void backspace() { + // 退完了,没法退了 + if (this.input_str.length() == 0) { + flushPanel(); + return; + } + // 退一个字符 + this.input_str.deleteCharAt(this.input_str.length() - 1); + // 删除了之后为空,也视为0 + if (this.input_str.length() == 0) { + input_str.append("0"); + flushPanel(); + } + // 重新设置展示值 + this.input_text.setText(input_str.toString()); + } + + /** + * 点击的按钮是数字吗,点击了·也算是数字 + * + * @param clickStr 点击的按钮 + * @return 选择的按钮值是数字吗(点也算数字) + */ + private boolean mightNumber(String clickStr) { + // 如果这一位和上一位都是点,那不行 + if (".".equals(clickStr)) { + // 如果已经有小数点了,那不能再添加了 + if (input_str.toString().contains(".")) { + return false; + } + return true; + } + // 必须每一位都不是数值,因为有个操作符是1/x + for (char item : clickStr.toCharArray()) { + // 不是数值 + if (!Character.isDigit(item)) { + return false; + } + } + return true; + } + +}