这个作业属于哪个课程 | https://bbs.csdn.net/forums/ssynkqtd-05 |
---|---|
这个作业要求在哪里 | https://bbs.csdn.net/topics/617294583 |
这个作业的目标 | 实现一个可视化的计算器,具有加减乘除和三角函数阶级的功能 |
0.页面展示
1.PSP
PSP | Personal Software Process Stages | Personal Software Process Stages | 实际耗时(分钟) |
---|---|---|---|
Planning | Planning | 10 | 10 |
Estimate | 估计这个任务需要多少时间 | 10 | 10 |
Development | Development | 60 | 120 |
Analysis | 需求分析 (包括学习新技术) | 120 | 150 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 0 | 0 |
Design | 具体设计 | 60 | 60 |
Coding | 具体编码 | 60 | 100 |
Code Review | 代码复审 | 100 | 100 |
Test | 测试(自我测试,修改代码,提交修改) | 180 | 180 |
Reporting | 报告 | 60 | 60 |
Test Repor | 测试报告 | 120 | 120 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
Size Measurement | 测试报告 | 30 | 30 |
合计 | 870 | 1060 |
2.解题的思路过程
本次作业的题目是制作一个简易的计算器
- 语言选择。语言方面我选择使用JAVA和JDK里面的JPanel来制作计算器。
- 页面与核心功能。通过JPanel来制作计算器的页面和布局。用JAVA来实现计算器运算的接受和运算。
- 制作难点。接受的其中一个难点是———对于符号的监听和接受,这个点我通过学习使用了正则表达来解决。
- exe打包。
3.代码展示
首先是可视化窗口工具的一些初始化
/*************窗口顶部的控件*************/
private JPanel jp_north = new JPanel();
private JTextField input_text = new JTextField();
private JButton c_Btn = new JButton("归零!");
/*************窗口中部的控件*************/
private JPanel jp_center = new JPanel();
窗口顶部按钮以及文本的显示
//对窗口顶部的界面添加
public void setNorth_Component() {
this.input_text.setPreferredSize(new Dimension(200, 45));
jp_north.add(input_text);
this.c_Btn.setForeground(Color.MAGENTA);
jp_north.add(c_Btn);
c_Btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
input_text.setText("");
}
});
this.add(jp_north, BorderLayout.NORTH);
}
对窗口中部按钮的设置
//对窗口中间控件添加
public void addCenter_Button() {
String btn_text = "789+sin456-cos123*tan0.=/^";
int count = 0;
this.jp_center.setLayout(new GridLayout(4, 5));
for (int i = 0; i < 26; i++) {
count++;
String temp = btn_text.substring(i, i + 1);
if(count == 5 && i != 25){
temp = btn_text.substring(i, i + 3);
count = 0;
i += 2;
}
String regex = "[\\+\\-*/.=]";
JButton Btn = new JButton();
Btn.setText(temp);
if (temp.matches(regex)) {
Btn.setFont(new Font("粗体", Font.BOLD, 16));
Btn.setForeground(Color.BLUE);
}
/* 优化使用正则表达式
// if (temp.equals("+") ||
// temp.equals("-") ||
// temp.equals("/") ||
// temp.equals("*") ||
// temp.equals(".") ||
// temp.equals("=") ){
// Btn.setFont(new Font("粗体",Font.BOLD,16));
// Btn.setForeground(Color.BLUE);
}
*/
Btn.addActionListener(this);
jp_center.add(Btn);
}
this.add(jp_center, BorderLayout.CENTER);
}
使用ActionListener接口来监听符号,是实现三角函数和基本运算的核心代码块
public void actionPerformed(ActionEvent e) {
String clickStr = e.getActionCommand();
String temp = null; //记住三角函数的字符串
//三角函数下预处理clickStr
if(clickStr.equals("sin")){
clickStr = "s";
temp = "sin";
}
if(clickStr.equals("cos")){
clickStr = "c";
temp = "cos";
}
if(clickStr.equals("tan")){
clickStr = "t";
temp = "tan";
}
//正常接受文本框数字
if (".0123456789".indexOf(clickStr) != -1) {
if(flag2 == false){
this.input_text.setText("");
flag2 = true;
}
this.input_text.setText(input_text.getText() + clickStr);
this.input_text.setHorizontalAlignment(JTextField.RIGHT);
// JOptionPane.showConfirmDialog(this,clickStr); 点击时弹窗,测试效果作用
} else if (clickStr.matches("[\\+\\-*/^]")) {
operator = clickStr;
firstInput = this.input_text.getText();
this.input_text.setText("");
}
// 三角函数的输入
else if(clickStr.matches("[stc]")){
this.input_text.setText("");
operator = clickStr;
this.input_text.setText(temp);
this.input_text.setHorizontalAlignment(JTextField.RIGHT);
flag1 = false;
flag2 = false;
}
// 得出结果
else if (clickStr.equals("=")) {
Double a = null;
//不是三角函数,flag = true ; 三角函数则跳过
if(flag1){
a = Double.valueOf(firstInput);
}
Double b = Double.valueOf(this.input_text.getText());
Double res = null;
switch (operator) {
case "+":
res = a + b;
break;
case "-":
res = a - b;
break;
case "*":
res = a * b;
break;
case "/":
if (b != 0) {
res = a * 1.0 / b;
}
break;
case "^":
res = 1.0;
for (int i = 0; i < b; i++) {
res = res * a;
}
break;
case "s":
res = Math.sin(Math.toRadians(b));
break;
case "c":
res = Math.cos(Math.toRadians(b));
break;
case "t":
res = Math.tan(Math.toRadians(b));
break;
default:
break;
}
this.input_text.setText(res.toString());
flag1 = true;
}
}
4.性能的改进与分析
- 我将诸多的固定不变的,如标题和窗口的长度尺寸,一同放在另外一个包再将其导入。降低了代码的冗长和繁杂。
public class Const {
public static final int FRAME_W = 320;
public static final int FRAME_H = 350;
public static final int SCREEN_W = Toolkit.getDefaultToolkit().getScreenSize().width;
public static final int SCREEN_H = Toolkit.getDefaultToolkit().getScreenSize().height;
//屏幕与窗体长宽 ;用 (屏幕长 - 窗体长)/ 2 得出屏幕中心位置
public static final int FRAME_X = (SCREEN_W - FRAME_W) / 2;
public static final int FRAME_Y = (SCREEN_H - FRAME_H) / 2;
public static final String Title = "计算器";
}
- 使用了正则表达发和switch()来缩减篇幅和可读性。
String regex = "[\\+\\-*/.=]";
JButton Btn = new JButton();
Btn.setText(temp);
if (temp.matches(regex)) {
Btn.setFont(new Font("粗体", Font.BOLD, 16));
Btn.setForeground(Color.BLUE);
}
/* 优化使用正则表达式
// if (temp.equals("+") ||
// temp.equals("-") ||
// temp.equals("/") ||
// temp.equals("*") ||
// temp.equals(".") ||
// temp.equals("=") ){
// Btn.setFont(new Font("粗体",Font.BOLD,16));
// Btn.setForeground(Color.BLUE);
}
*/
5.单元测试
public class Test {
Carculator carculator = new Carculator();
@org.junit.Test
public void add(){
Double res = carculator.jisuan1(12, "+", 2);
assertEquals(res, (Double)14.0);
}
@org.junit.Test
public void sub(){
Double res = carculator.jisuan1(12, "-", 2);
assertEquals((Double)10.0,res);
}
@org.junit.Test
public void mul(){
Double res = carculator.jisuan1(12, "*", 2);
assertEquals((Double)24.0,res);
}
@org.junit.Test
public void div(){
Double res = carculator.jisuan1(12, "/", 2);
assertEquals((Double)6.0,res);
}
@org.junit.Test
public void mi(){
Double res = carculator.jisuan1(12, "^", 2);
assertEquals((Double)144.0,res);
}
@org.junit.Test
public void sin(){
Double res = carculator.jisuan2("sin", 30);
BigDecimal two11 = new BigDecimal(res);
Double three11 = two11.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
assertEquals((Double)0.5,three11);
}
@org.junit.Test
public void cos(){
Double res = carculator.jisuan2("cos", 60);
BigDecimal two11 = new BigDecimal(res);
Double three11 = two11.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
assertEquals((Double)0.5,three11);
}
@org.junit.Test
public void tan(){
Double res = carculator.jisuan2( "tan", 45);
BigDecimal two11 = new BigDecimal(res);
Double three11 = two11.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
assertEquals((Double)1.0,three11);
}
}
测试结果:
6.异常处理
除法中的除数不能为零,通过IF语句限制。
7.心得体会
自己完成一个可视化的计算器还是充满挑战的,从学习可视化的使用到Junit的单元测试使用中,接触了很多新的东西,也习得了很多,不断地从中学习到很多。这其中有许多学习的烦躁和繁琐,坚持到成功后却也获得巨大的成就感和满足感。我更加清晰地接触到一个项目开发的整体过程和困难程度。这项作业带给我的惊喜和欢喜非常多的。