团队名称 |
团队成员介绍 |
任务分配 |
团队成员博客 |
---|---|---|---|
XQ Warriors |
徐维辉 |
负责计算器数据的算法操作,如平方数、加减乘除,显示历史计算记录 |
无 |
邱良厦(组长) |
负责计算器的图形设计,把输入和结果显示在最上面的文本框 |
无 |
1)图形界面设计参考:Java Swing界面设计UI(全)_swing ui-CSDN博客
Java Swing界面设计UI(全)_swing ui-CSDN博客
2)使用的查询工具:Chatgpt和文心一言,询问相关操作的实现,查询方法具体使用等
3)文心一言链接:文心一言 (baidu.com)
Chatgpt镜像:AIchatOS
Issues · 则戈/Simple-Calculator - Gitee.com
1)邱良厦:
1.图片资源和代码资源分成两个部分
2.添加UI界面设计文件,完善图形界面设计,查看图形界面操作是否有误
3.添加UI程序的图片
2)徐维辉:
1.完成Calculator类,实现了常见的数学算法,完成了一元操作符和二元操作符的相关操作
2.完成历史计算记录记录算法
想看看是否能通过按钮实现数学表达式的运算,实现图形化界面,制作一个简单计算器。
看bilibili视频:java计算器程序_哔哩哔哩_bilibili
项目功能架构图
主要功能流程图
1.包图:UI包、sumpleculator包、
2.类图:Calulator类、Main类、UI类、HistoryDialog类
1)运行程序,打开简单计算器的界面
2)操作视频
简单计算机的运算操作
1. class UI:创建了窗口、各个面板、文本框,字体对象,添加了各个按钮。
public class UI implements ActionListener {
private JFrame frame;
private JPanel panel;
private JPanel panelSub1;//子面板
private JPanel panelSub2;
...
private JTextArea text;//文本框
// JButton 数组,存储数字按钮
private JButton button[], butAdd, butMinus, butMultiply, butDivide,
butEqual, butCancel, butSquareRoot, butSquare, butOneDividedBy,
butCos, butSin, butTan, butXPowerOfY, butLog, butRate, butabs, butBinary, butln;
private Font font;
private Font textFont;
...
}
2. init():设计窗口的的布局,为各个按钮添加字体,给各个子面板流水体布局,把按钮添加到各个子面板,最后把子面板添加到面板,窗口最后在采用面板来实现界面
public void init() {
frame.setSize(450, 450);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for (int i = 0; i < 10; i++) {
button[i].setFont(font);
}
butAdd.setFont(font);
butMinus.setFont(font);
butMultiply.setFont(font);
...
panelSub2.add(button[1]);
panelSub2.add(button[2]);
panelSub2.add(button[3]);
//在数字和运算符之间空出一点距离
panelSub2.add(Box.createHorizontalStrut(15));
panelSub2.add(butAdd);
panelSub2.add(butMinus);
...
for (int i = 0; i < 10; i++) {//添加监听器
button[i].addActionListener(this);
}
butAdd.addActionListener(this);
butMinus.addActionListener(this);
butMultiply.addActionListener(this);
butDivide.addActionListener(this);
...
panel.add(panelSub2);
frame.add(panel);//添加面板
frame.setVisible(true);
}
3. actionPerformed():点击按钮进行操作时,根据不同的事件源(e.getSource())执行不同的功能,如果是数字按钮,将对应的值添加到文本框中,并返回,如果是符合按钮,就会进行对应符号的运算
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
Double checkNum = null;
for (int i = 0; i < 10; i++) {//数字按钮
if (source == button[i]) {
text.replaceSelection(buttonValue[i]);
return;
}
}
if (source == butAdd) {
//把数字读出来进行相加
write(calc.binCalculate(Calculator.binaryOperatorModes.add, reader()));
text.replaceSelection(butAdd.getText());
}
// 处理减法操作
if (source == butMinus) {
write(calc.binCalculate(Calculator.binaryOperatorModes.minus, reader()));
text.replaceSelection(butMinus.getText());
}
...
}
4.Calculator类的基本属性和构造函数:主要包含Calculator类的基本属性和构造函数,包括操作数num1、num2,记录运算结果的result,记录当前运算符号的mode,以及记录一元运算和二元运算会用到的list
public enum binaryOperatorModes {
normal, add, minus, multiply, divide , xPowerOfY
}
//一元运算
public enum unaryOperatorModes {
square, squareRoot, oneDivided, cos, sin, tan, log, rate, abs, ln,
}
private Double num1, num2;
private Double result;
//默认状态normal
private binaryOperatorModes mode = binaryOperatorModes.normal;
private List unaryHistory = new ArrayList<>();
private List binaryHistory = new ArrayList<>();
5 二元运算模块:包含了二元运算相关的方法。binCalculateImpl方法用于执行实际的二元运算,binCalculate方法是对外的接口,处理用户输入的二元运算。calculateEqual方法用于处理等号操作。将运算结果返回到num1,用于下次运算。保存到result,用于记录的显示
//二元运算的具体实现
private Double binCalculateImpl() {
if (mode == binaryOperatorModes.normal) {
return num2;
}
if (mode == binaryOperatorModes.add) {
if (num2 != 0) {
result = num1 + num2;
return num1 + num2;
}
return num1;
}
if (mode == binaryOperatorModes.minus) {
result = num1 - num2;
return num1 - num2;
}
if (mode == binaryOperatorModes.multiply) {
result = num1 * num2;
return num1 * num2;
}
if (mode == binaryOperatorModes.divide) {
result = num1 / num2;
return num1 / num2;
}
if (mode == binaryOperatorModes.xPowerOfY) {
result = Math.pow(num1, num2);
return Math.pow(num1, num2);
}
throw new Error("没有该运算");
}
// 二元运算的对外接口
public Double binCalculate(binaryOperatorModes newMode, Double num) {
if (mode == binaryOperatorModes.normal) {
num2 = 0.0;
num1 = num;
mode = newMode;
return NaN;
} else {
Double temp = num1;
num2 = num;
num1 = binCalculateImpl();
mode = newMode;
String opr = null;
binaryHistory.add("操作数: " + temp + " " + getOperatorSymbol(mode) + " " + num2 + " 结果 " + result);
return num1;
}
}
6.一元运算模块、重置运算器模块:重置计算器,将num1、num2置零,状态mode置为normal
实现简单的一元运算,并且将运算记录保存
// 重置计算器状态的方法
public Double reset() {
num2 = 0.0;
num1 = 0.0;
mode = binaryOperatorModes.normal;
//无效字符
return NaN;
}
// 执行单元操作的方法
public Double unaryCalculate(unaryOperatorModes newMode, Double num) {
if (newMode == unaryOperatorModes.square) {
result = num * num;
}
if (newMode == unaryOperatorModes.squareRoot) {
result = Math.sqrt(num);
}
if (newMode == unaryOperatorModes.oneDivided) {
result = 1 / num;
}
if (newMode == unaryOperatorModes.cos) {
result = Math.cos(Math.toRadians(num));
}
if (newMode == unaryOperatorModes.sin) {
result = Math.sin(Math.toRadians(num));
}
if (newMode == unaryOperatorModes.tan) {
if (num == 0 || num % 180 == 0) {
result = 0.0;
}
if (num % 90 == 0 && num % 180 != 0) {
result = NaN;
}
result = Math.tan(Math.toRadians(num));
}
if (newMode == unaryOperatorModes.log) {
result = Math.log10(num);
}
if (newMode == unaryOperatorModes.ln) {
result = Math.log(num);
}
if (newMode == unaryOperatorModes.rate) {
result = num / 100;
}
if (newMode == unaryOperatorModes.abs){
result = Math.abs(num);
}
unaryHistory.add("表达式: " + getOperatorSymbol(newMode) + "(" + num + ") = " + result);
return result;
}
7.获取操作符符号模块:将当前的mode转化为其对应的符号字符串,用于写入计算的历史记录中
public static String getOperatorSymbol(binaryOperatorModes mode) {
return switch (mode) {
case add -> "+";
case minus -> "-";
case multiply -> "*";
case divide -> "/";
case xPowerOfY -> "^";
default -> "";
};
}
public static String getOperatorSymbol(unaryOperatorModes mode) {
return switch (mode) {
case square -> "^";
case squareRoot -> "sqrt()";
case oneDivided -> "1/x";
case cos -> "cos";
case sin -> "sin";
case tan -> "tan";
case log -> "log()";
case rate -> "rate()";
case abs -> "abs()";
case ln -> "ln()";
default -> "";
};
}
1.变量命名错误:
将butXPowerOfY改为butXpowerOfY
2.包名命名错误
改为Ui
1. 不足:
界面布局使用了多个 JPanel 进行组合,没有使用更灵活的布局管理器,如BorderLayout或 GridBagLayout,部分代码重复,没有优化界面布局和颜色。计算器中没有实现小数点功能,不能直接添加小数,操作历史记录没有完全实现,有时候不能记录符号。
2. 展望:
增加支持复数计算、矩阵计算和小数点运算等,可以继续优化界面,使用更灵活的布局管理器,如BorderLayout,优化颜色布局等