Java_简易计算器
2020年11月7日下午12:30
2020年11月21日下午10:35
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控件的使用