目录
计算器功能
一个简单的计算器,应该具有图形化界面,各种Button,一个结果显示屏,支持加减乘除,N次方,N次方根,求sin,cos,tan以及对应的反sin,cos,tan,log。
各种难点
难点1:图形化界面
这里我选用的是JAVA.Swing。
1,先用JPane和JFramel构建我们的窗口,JPanel是一个通用的轻量级容器,先定义一个JPanel panel,然后在main方法里面用panel = new JPanel;创造窗口。用setBackground设置颜色。
JPanel panel;
panel = new JPanel;
panel.setBackground(Color.BLUE);
2,用JTextField输出计算结果,JTextField
是一个轻量级组件,允许编辑单行文本。
-
JTextField
的水平对齐可以设置为左对齐,前导对齐,居中,右对齐或尾对齐。 如果字段文本的所需大小小于分配给它的大小,则右/尾对齐很有用。 这由setHorizontalAlignment
和getHorizontalAlignment
方法确定。 默认值是前导对齐。 - JTextField
-
public JTextField():构造一个新的TextField 。 创建默认模型,初始字符串为null ,列数设置为0。
- public JTextField(String text):构造一个使用指定文本初始化的新
TextField
。 将创建默认模型,列数为0。 - public JTextField(int columns):构造具有指定列数的新空
TextField
。 将创建默认模型,并将初始字符串设置为null
。 - public JTextField(String text, int columns):构造一个使用指定文本和列初始化的新
TextField
。 创建默认模型。 - public JTextField(Document doc, String text, int columns):构造一个新的
JTextField
,它使用给定的文本存储模型和给定的列数。 这是其他构造函数通过其提供的构造函数。 如果文档是null
,则创建默认模型。
-
- setHorizontalAlignment
-
设置文本的水平对齐方式。 有效密钥是:
JTextField.LEFT
JTextField.CENTER
JTextField.RIGHT
JTextField.LEADING
JTextField.TRAILING
invalidate
和repaint
,并PropertyChange
事件(“horizontalAlignment”)。
-
- setFont
-
public void setFont(Font f):设置当前字体。 这将删除缓存的行高和列宽,以便反映新字体。 设置字体后调用revalidate。
-
JTextField display;
display = new JTextField(20);
display.setEditable(false);
display.setText(displayText);
3,用JButton创建计算器的各种按键
然后添加事情监听器,这样用户按下按键就能给我们一个值用于判断。用panel.add(JButton);添加按钮到容器中。
难点2:各种计算公式
result = Math.pow(operand2, 2);
result = Math.pow(operand2, 3);
result = Math.sqrt(operand2);
result = Math.sin(operand2*Math.PI/180);
result = Math.cos(operand2*Math.PI/180);
result = Math.tan(operand2*Math.PI/180);
result = Math.log10(operand2);
result = Math.log(operand2);
result = Math.asin(operand2);
result = Math.acos(operand2);
result = Math.atan(operand2);
result = operand2-2*operand2;
result = Math.cbrt(operand2);
sin,cos,tan这里不光要用Math公式,还要把输入的数值从弧度制转化为角度制再带入计算。
难点3:连续运算
要实现连续运算,就需要记录下前2次运算的结果,然后依次运算,每次运算都保留运算结果用于下次运算。先定义2个变量operand1,operand2用于保存用户输入的数值,再定义一个operator用于保存用户输入的运算符。然后增加判断条件,如果用户按下数字,再屏幕上显示数字,如果用户按下运算符+-*/,则记录屏幕上已经有的数字为operand1,然后准备记录下一个数字operand2,所以要清空屏幕。用户输入第二个数字按下=,记录屏幕上的数字为operand2,然后运算,输出结果。operator一开始定义好了之后是null,只有用户按过运算符才会改变,所以判断operator是不是null就可以判断是否是连续运算。
// 判断是否连续运算
else if (operator != null){
displayText = Double.toString(computeResult());
display.setText(displayText);
operand1 = Double.parseDouble(displayText);
shouldAppendDigitToNumber = false;
operator=String.valueOf(c);
return;
这里其实我还增加了一个判断shouldAppendDigitToNumber,如果为true,则下一次输入的数字直接+到屏幕上(字符串),如果为false,则先清空屏幕,再添加数字。
// 用来表示应该重新输入一个数字还是往屏幕后面添加数字
boolean shouldAppendDigitToNumber;
难点4:对用户的点击进行监控及准确反应
这里用到的是awt包,使用addActionListener,然后对用户的按下的键的第一个字母进行判断,用if,else if,else来对用户的不同按键进行不同反应。charAt是JAVA.Lang包String类的内容。command.charAt(0)返回的是用户按下的键的字符串的第一个char字符,结果保存在c中,通过判断c == “?”即可判断用户按下的是哪一个按钮。
String (Java 2 Platform SE 5.0) (cuit.edu.cn)
JAVA lang包介绍 - 新时代农民工01 - 博客园 (cnblogs.com)
btnEqual.addActionListener(this);
public void actionPerformed(ActionEvent e) {
var command = e.getActionCommand();
char c = command.charAt(0);
if (isOperand(c)) {
...
}
(1条消息) 学习java.awt_一腔诗意醉了酒的博客-CSDN博客_awt
(1条消息) java.awt包_java.awt包 简介_面子是给狗吃的的博客-CSDN博客
源码
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Calculator implements ActionListener {
// 整个面板
JPanel panel;
// 计算器的显示屏
JTextField display;
// 显示屏里的内容
String displayText;
// 保存用户输入的第一个数
Double operand1;
// 保存用户输入的运算符号:+-×÷
String operator;
// 用来表示应该重新输入一个数字还是往屏幕后面添加数字
boolean shouldAppendDigitToNumber;
// 计算器上的按键
JButton btnFushu,btnDian,btnLog,btnLn,btnAdd,btnSubtract,btnChen,btnChu,btnAc,btnEqual;
JButton btnSin,btnAsin,btnAcos,btnAtan,btnCos,btnTan;
JButton b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b00;
JButton btnPingFan3,btnPingFan2,btnPingFanGen,btnPingFanGen3;
// 生成整个计算器模板
Calculator(){
panel = new JPanel();
// 设置背景颜色
panel.setBackground(Color.BLUE);
// 初始化operator,为后面判断连续运算提供条件
operator = null;
displayText = "0";
display = new JTextField(20);
display.setEditable(false);
display.setText(displayText);
shouldAppendDigitToNumber = false;
createButtons();
attachListeners();
addComponentsToPanel();
}
/**
* 将屏幕和按键依次添加到计算器上
*/
void addComponentsToPanel() {
panel.add(btnEqual);
panel.add(display);
panel.add(btnAc);
panel.add(b0);
panel.add(b1);
panel.add(b2);
panel.add(b3);
panel.add(b4);
panel.add(b5);
panel.add(b6);
panel.add(b7);
panel.add(b8);
panel.add(b9);
panel.add(btnDian);
panel.add(b00);
panel.add(btnFushu);
panel.add(btnAdd);
panel.add(btnSubtract);
panel.add(btnChen);
panel.add(btnChu);
panel.add(btnPingFan2);
panel.add(btnPingFan3);
panel.add(btnPingFanGen);
panel.add(btnPingFanGen3);
panel.add(btnSin);
panel.add(btnCos);
panel.add(btnTan);
panel.add(btnAsin);
panel.add(btnAcos);
panel.add(btnAtan);
panel.add(btnLog);
panel.add(btnLn);
}
/**
* 设置用户点击按键时计算器的反应
*/
void attachListeners() {
btnAdd.addActionListener(this);
b1.addActionListener(this);
b0.addActionListener(this);
b00.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
b5.addActionListener(this);
b6.addActionListener(this);
b7.addActionListener(this);
b8.addActionListener(this);
b9.addActionListener(this);
btnEqual.addActionListener(this);
btnSubtract.addActionListener(this);
btnChen.addActionListener(this);
btnChu.addActionListener(this);
btnAc.addActionListener(this);
btnPingFan2.addActionListener(this);
btnPingFan3.addActionListener(this);
btnPingFanGen.addActionListener(this);
btnPingFanGen3.addActionListener(this);
btnSin.addActionListener(this);
btnCos.addActionListener(this);
btnTan.addActionListener(this);
btnLog.addActionListener(this);
btnLn.addActionListener(this);
btnDian.addActionListener(this);
btnAsin.addActionListener(this);
btnAcos.addActionListener(this);
btnAtan.addActionListener(this);
btnFushu.addActionListener(this);
}
/**
* 创建好按键(但还没有"贴"到屏幕上)
*/
void createButtons() {
b0 = new JButton("0");
b00 = new JButton("00");
b1 = new JButton("1");
b2 = new JButton("2");
b3 = new JButton("3");
b4 = new JButton("4");
b5 = new JButton("5");
b6 = new JButton("6");
b7 = new JButton("7");
b8 = new JButton("8");
b9 = new JButton("9");
btnDian = new JButton(".");
btnAdd = new JButton("+");
btnEqual = new JButton("=");
btnSubtract = new JButton("-");
btnChen = new JButton("×");
btnChu = new JButton("÷");
btnAc = new JButton("AC");
btnPingFan2 = new JButton("二次方");
btnPingFan3 = new JButton("三次方");
btnPingFanGen = new JButton("平方根");
btnPingFanGen3 = new JButton("立方根");
btnSin = new JButton("Sin");
btnAsin = new JButton("算ASin");
btnAcos= new JButton("求Acos");
btnAtan = new JButton("得Atan");
btnCos = new JButton("Cos");
btnTan = new JButton("Tan");
btnLog = new JButton("常用log");
btnLn = new JButton("Ln");
btnFushu = new JButton("负数");
Font f = new Font("仿宋", Font.BOLD, 20);// 根据指定字体名称、样式和磅值大小,创建一个新 Font
b0.setFont(f);
b00.setFont(f);
b1.setFont(f);
b2.setFont(f);
b3.setFont(f);
b4.setFont(f);
b5.setFont(f);
b6.setFont(f);
b7.setFont(f);
b8.setFont(f);
b9.setFont(f);
btnDian.setFont(f);
btnAdd.setFont(f);
btnEqual.setFont(f);
btnSubtract.setFont(f);
btnChen.setFont(f);
btnChu.setFont(f);
btnAc.setFont(f);
btnPingFanGen.setFont(f);
btnPingFan2.setFont(f);
btnPingFan3.setFont(f);
btnPingFanGen3.setFont(f);
btnSin.setFont(f);
btnAsin.setFont(f);
btnAcos.setFont(f);
btnAtan.setFont(f);
btnCos.setFont(f);
btnTan.setFont(f);
btnLog.setFont(f);
btnLn.setFont(f);
btnFushu.setFont(f);
}
// main function
public static void main(String[] args) {
Calculator calculator = new Calculator();
JFrame frame = new JFrame("Caculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(calculator.panel);
frame.setSize(330, 600);
frame.setLocation(700,300);
frame.setVisible(true);
}
// 主要判断方法
public void actionPerformed(ActionEvent e) {
var command = e.getActionCommand();
char c = command.charAt(0);
if (isOperand(c)) {
if (shouldAppendDigitToNumber) {
displayText += command;
} else {
displayText = command;
shouldAppendDigitToNumber = true;
}
} else if (c == '=') {
Double result = computeResult();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
} else if (c == 'A'){
displayText = "0";
operator=null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '.'){
displayText += command;
shouldAppendDigitToNumber = true;
}
else if (c == '负'){
Double result = computeResult12();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '二'){
Double result = computeResult1();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '三'){
Double result = computeResult8();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == 'S'){
Double result = computeResult3();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '算'){
Double result = computeResult9();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '求'){
Double result = computeResult10();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '得'){
Double result = computeResult11();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == 'C'){
Double result = computeResult4();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == 'T'){
Double result = computeResult5();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '常'){
Double result = computeResult6();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == 'L'){
Double result = computeResult7();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '平'){
Double result = computeResult2();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
else if (c == '立'){
Double result = computeResult13();
displayText = Double.toString(result);
operator = null;
operand1 = null;
shouldAppendDigitToNumber = false;
}
// 判断是否连续运算
else if (operator != null){
displayText = Double.toString(computeResult());
display.setText(displayText);
operand1 = Double.parseDouble(displayText);
shouldAppendDigitToNumber = false;
operator=String.valueOf(c);
return;
}
else {
operand1 = Double.parseDouble(displayText);
shouldAppendDigitToNumber = false;
operator = command;
}
display.setText(displayText);
}
/**
* 计算结果
*/
Double computeResult() {
Double operand2 = Double.parseDouble(displayText);
Double result=0.0;
switch (operator) {
case "+":
result = addNumbers(operand1, operand2);
break;
case "-":
result = SubtractNumbers(operand1, operand2);
break;
case "×":
result = chenNumbers(operand1, operand2);
break;
case "÷":
result = chuNumbers(operand1, operand2);
break;
}
return result;
}
Double computeResult1() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.pow(operand2, 2);
return result;
}
Double computeResult8() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.pow(operand2, 3);
return result;
}
Double computeResult2() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.sqrt(operand2);
return result;
}
Double computeResult3() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.sin(operand2*Math.PI/180);
return result;
}
Double computeResult4() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.cos(operand2*Math.PI/180);
return result;
}
Double computeResult5() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.tan(operand2*Math.PI/180);
return result;
}
Double computeResult6() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.log10(operand2);
return result;
}
Double computeResult7() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.log(operand2);
return result;
}
Double computeResult9() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.asin(operand2);
return result;
}
Double computeResult10() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.acos(operand2);
return result;
}
Double computeResult11() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.atan(operand2);
return result;
}
Double computeResult12() {
double operand2 = Double.parseDouble(displayText);
double result;
result = operand2-2*operand2;
return result;
}
Double computeResult13() {
double operand2 = Double.parseDouble(displayText);
double result;
result = Math.cbrt(operand2);
return result;
}
Double addNumbers(Double a, Double b) {
return a + b;
}
Double SubtractNumbers(Double a, Double b) {
return a - b;
}
Double chenNumbers(Double a, Double b) {
return a * b;
}
Double chuNumbers(Double a, Double b) {
return a / b;
}
/**
* 判断按的是数(0123之类)还是运算符(+-=之类)
*/
boolean isOperand(char c) {
return Character.isDigit(c);
}
}