Java_简易计算器

Java编程练习,设计一个功能基础的计算器

要求

模仿windows自带的计算器功能,设计一个简单计算器

(1)至少要求实现整数和小数的加、减、乘、除、清零功能。

(2)其他计算功能,请参考windows自带的计算器,尽可能多的实现

参考

说明

这个程序设计的思路非常简单,把所有的按钮排好,给每个按钮添加事件,所以事件集中到一个函数进行进一步精准处理,触发每个按钮的处理函数。在这些按钮的处理函数里面添加各种规则(能不能按,这个按钮操作需不需要处理。比如肯定不能在一个数里面出现两个小数点是吧,不能连续出现操作符+-*/是吧,除数不能为0等等等等等)

代码

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.math.BigDecimal;
/*
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.math.BigDecimal;
/*

+-----------------------------------+
|                                   |
|                                   |
+-----------------------------------+
|                                   |
|                                   |
+-----------------------------------+
| +-------------------------------+ |
| |       |       |       |       | |
| |       |       |       |       | |
| +-------------------------------+ |
| |       |       |       |       | |
| |       |       |       |       | |
| +-------------------------------+ |
| |       |       |       |       | |
| |       |       |       |       | |
| +-------------------------------+ |
| |       |       |       |       | |
| |       |       |       |       | |
| +-------------------------------+ |
| |       |       |       |       | |
| |       |       |       |       | |
| +-------------------------------+ |

*/

public class test3_2 extends JFrame implements ActionListener {
  // 设计计算器表盘
  private static final long serialVersionUID = 1L;
  private JPanel topPanel, centerPanel;
  GridLayout topLayout;
  GridLayout centerLayout;
  JTextArea topArea;
  JTextField resultArea;
  private boolean firstPress;
  private double result, ans;
  int btnNum = 20;
  JButton btn[] = new JButton[btnNum];

  private void initTop() {
    // 初始化输入区域和答案区域
    // 初始化头部区域,用GridLayout布局2行1列
    topPanel = new JPanel();
    topLayout = new GridLayout(2, 1);
    // 设定输入区域
    topArea = new JTextArea();
    topArea.setEditable(false);
    topArea.setText("0");
    topArea.setLineWrap(true);// 自动换行
    // 设定答案区域
    resultArea = new JTextField();
    resultArea.setEditable(false);// 答案背景灰白
    resultArea.setBackground(Color.LIGHT_GRAY);
    // resultArea.setBorder(null);//可添加答案区域的边框
    resultArea.setHorizontalAlignment(JTextField.RIGHT);// 答案右对齐
    resultArea.setText("");
    // 完成头部区域布局
    topPanel.setLayout(topLayout);
    topPanel.add(topArea);
    topPanel.add(resultArea);
    getContentPane().add(topPanel, "North");// 把这个JPannel放到上面
  }

  private void initCenter() {
    // 设计按钮盘
    centerPanel = new JPanel();
    centerLayout = new GridLayout(5, 4);
    centerPanel.setLayout(centerLayout);
    String btnText[] = new String[] { "C", "/", "*", "CE", "7", "8", "9", "-", "4", "5", "6", "+", "1", "2", "3", "%",
        "ANS", "0", ".", "=" };
    for (int i = 0; i < btnNum; ++i) {
      btn[i] = new JButton(btnText[i]);
      btn[i].addActionListener(this);// 添加本类监控,因为全是按钮,所以统一处理
      btn[i].setActionCommand(btnText[i]);
      centerPanel.add(btn[i]);
    }
    getContentPane().add(centerPanel, "Center");
  }

  private void initValue() {
    firstPress = true;
    result = 0.0;
    ans = 0.0;
  }

  test3_2(String title) {
    // 构造函数
    super(title);
    initTop();
    initCenter();
    initValue();
    setLocation(800, 450);
    pack();// 自动适应窗口大小
    setResizable(false);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  private void handleCE() {
    // 按键CE的响应
    topArea.setText("0");
    resultArea.setText("");
    initValue();
  }

  private void handleC() {
    // 按键C的响应
    String text = topArea.getText();
    if (firstPress) {
      return;
    } else {
      if (text.length() == 1) {
        handleCE();
      } else {// 回字符
        text = text.substring(0, text.length() - 1);
        topArea.setText(text);
      }
    }
  }

  private void handleOperator(String operator) {
    // +-*/键的响应
    String text = topArea.getText();
    int len = text.length();
    if (firstPress) {
      if (operator == "-") {// 第一个键是‘-’号
        topArea.setText("-");
        firstPress = false;
      }
      return;
    } else if ("0123456789".indexOf(text.charAt(len - 1)) >= 0) {
      topArea.append(operator);// 防止连续出现两操作数
    }
  }

  private void handleDigit(String number) {
    // 数字键的响应
    if (firstPress) {// 第一个数字键
      if (number == "0") {// 第一个数字键是0则直接返回
        topArea.setText("0");
        return;
      }
      topArea.setText("");
      firstPress = false;
    }
    topArea.append(number);
  }

  private void handleDot() {
    // 小数点的响应
    String text = topArea.getText();
    int len = text.length();
    for (int i = 1; i <= len; ++i) {// 是否可以添加小数点的第一个条件:这个完整的数之前没有小数点
      if ("0123456789".indexOf(text.charAt(len - i)) >= 0) {
        continue;
      } else if ("+-*/%".indexOf(text.charAt(len - i)) >= 0) {
        break;
      } else if ('.' == text.charAt(len - i)) {
        return;
      }
    }
    if ("0123456789".indexOf(text.charAt(len - 1)) >= 0) {// 是否可以添加小数点的第二个条件:前一个数不是操作数
      if (firstPress) {// 可以以0开头,0.xxx
        topArea.setText("0");
        firstPress = false;
      }
      topArea.append(".");
    }
  }

  private void handleEqual() {
    // 等于号的响应
    calValue();
    // if(resultArea.getText()=="?"){
    // ans=0;
    // firstPress=true;
    // }
    resultArea.setText("");
    if (result == (int) result) {// 整数形式答案
      resultArea.setText("" + (int) result);
    } else {
      result = (double) Math.round(result * 10e6) / 10e6;// 计算结果仅保留6位小数
      resultArea.setText("" + result);
    }
    ans = result;
    firstPress = true;
  }

  private void handleANS() {
    // ANS键的响应
    String text = topArea.getText();
    int len = text.length();
    String output = "";
    // 处理ans的数据成字符串
    if (ans == (int) ans) {// 整数
      if ((int) ans == 0)// 上一次的计算结果为0,则什么都不做
        return;
      output = String.valueOf((int) ans);//
    } else {// 小数
      BigDecimal bd = new BigDecimal(String.valueOf(ans));
      output = bd.stripTrailingZeros().toPlainString();// 处理掉后面多余的0
    }
    // 插入ans
    if (firstPress) {
      topArea.setText(output);
      firstPress = false;
    } else if ("+-*/%".indexOf(text.charAt(len - 1)) >= 0) {
      topArea.append(output);
    }
  }

  private void calValue() {
    // 计算完整答案
    result = 0;
    int k = 0;
    String text = topArea.getText();
    String tem = text;
    double cal[] = new double[text.length()];

    for (int i = 0; i <= text.length(); i++) {
      // 在tmp里面取出第一个数字(可以取出负数)
      if (i < text.length() && "0123456789.".indexOf(text.charAt(i)) >= 0 || ((i == 0) && '-' == text.charAt(i))) {
        continue;
      } else {
        cal[0] = Double.parseDouble(tem.substring(0, i));
        tem = tem.substring(i);
        break;
      }
    }
    // 先取出第一个数字,看是否还剩下运算操作。方便计算顺序和等号处理
    while (tem.length() > 1) {
      char ch = tem.charAt(0);// 取得操作+-*/%
      tem = tem.substring(1);// tmp去掉上一个取得的运算操作符号
      double mid = 0;// 存放下一个数字
      for (int i = 0; i <= tem.length(); i++) {
        if (i < tem.length() && "0123456789.".indexOf(tem.charAt(i)) >= 0) {
          continue;
        } else {
          mid = Double.parseDouble(tem.substring(0, i));
          tem = tem.substring(i);
          break;
        }
      }
      // 计算,利用k来控制优先级,如果是*/,立即给出结果,如果是-,则把下一个数当负数保存
      switch (ch) {
        case '+':
          ++k;
          cal[k] = mid;
          break;
        case '-':
          ++k;
          cal[k] = -mid;
          break;
        case '*':
          cal[k] = cal[k] * mid;
          break;
        case '/':
          if (mid == 0.0) {
            System.out.println("被除数不能为0");
            return;
          }
          cal[k] = cal[k] / mid;
          break;
        case '%':
          cal[k] = cal[k] % mid;
          break;
      }
    }
    // 最后把所有保存的数相加(*/因为是立即计算,所以不影响后续相加)
    for (int j = 0; j <= k; j++)
      result += cal[j];
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    // 处理按钮事件
    String command = e.getActionCommand();
    if (command == "CE") {
      handleCE();
    } else if (command == "C") {
      handleC();
    } else if ("+-*/%".indexOf(command) >= 0) {
      handleOperator(command);
    } else if ("0123456789".indexOf(command) >= 0) {
      handleDigit(command);
    } else if (command == ".") {
      handleDot();
    } else if (command == "=") {
      handleEqual();
    } else if (command == "ANS") {
      handleANS();
    }
  }

  public static void main(String[] args) {
    new test3_2("Cale");
  }
}

此题考察swing和awt控件的使用

Leave a Comment

您的电子邮箱地址不会被公开。 必填项已用 * 标注