这个作业属于哪个课程 | <班级的链接> |
---|---|
这个作业要求在哪里 | https://bbs.csdn.net/forums/ssynkqtd-05?spm=1001.2014.3001.6685 |
这个作业的目标 | 完成一个具有可视化界面的计算器 |
其他参考文献 | Java GUI——Java图形用户界面_java图形界面-CSDN博客 |
作业要求
https://bbs.csdn.net/topics/617294583
项目源码
https://gitcode.net/qq_63824566/calculatorex
目录
1.界面展示
2.PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 15 |
Development | 开发 | 150 | 200 |
• Analysis | • 需求分析 (包括学习新技术) | 30 | 25 |
• Design Spec | • 生成设计文档 | 20 | 20 |
• Design Review | • 设计复审 | 10 | 10 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 15 | 10 |
• Design | • 具体设计 | 30 | 30 |
• Coding | • 具体编码 | 100 | 120 |
• Code Review | • 代码复审 | 10 | 10 |
• Test | • 测试(自我测试,修改代码,提交修改) | 10 | 10 |
Reporting | 报告 | 70 | 80 |
• Test Repor | • 测试报告 | 10 | 10 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 535 |
3.解题思路描述
本题要求完成图形化简易计算器,拿到题目之后初步选择使用Java语言完成,查阅资料后发现要实现图形化界面则需要使用到Swing,GUI相关内容,在图形界面中添加按键并定义相关事件和逻辑处理即可。在完成加减乘除简易计算器的基础上,又为其添加回退键,三角函数运算和次方平方根运算,并加入负数的处理,最后使用exe4j进行打包处理。
4.核心代码
用户输入待运算数据时的处理代码,只有在检测到用户输入的是数据而非运算符号时,数字才会被添加到显示框中
String clickStr = event.getActionCommand();
/* JOptionPane.showMessageDialog(this,clickStr);*/
if (".0123456789".indexOf(clickStr)!=-1){
this.input_text.setText(input_text.getText()+clickStr);
/*JOptionPane.showMessageDialog(this,clickStr);*/
}
用户在进行加减乘除简易运算和进行等于时的处理代码
else if (clickStr.matches("[\\+\\-*/]{1}")){
firstInput = this.input_text.getText();
operator = clickStr;
this.input_text.setText("");
}
else if (clickStr.equals("=")) {
Double a = Double.valueOf(firstInput);
Double b = Double.valueOf(this.input_text.getText());
Double res = null;
switch (operator){
case "+":
res = a+b;
this.input_text.setText(res.toString());
break;
case "-":
res = a-b;
this.input_text.setText(res.toString());
break;
case "*":
res = a*b;
this.input_text.setText(res.toString());
break;
case "/":
if (b !=0){
res = a/b;
this.input_text.setText(res.toString());
break;
}
else {
this.input_text.setText("ERROR");
break;
}
}
进行三角函数等运算时的处理代码
else if (clickStr.equals("sin")) {
Double a = Double.valueOf(this.input_text.getText());
Double res = Math.sin(Math.toRadians(a));
this.input_text.setText(res.toString());
}
else if (clickStr.equals("cos")) {
Double a = Double.valueOf(this.input_text.getText());
Double res = Math.cos(Math.toRadians(a));
this.input_text.setText(res.toString());
}
else if (clickStr.equals("tan")) {
Double a = Double.valueOf(this.input_text.getText());
Double res = Math.tan(Math.toRadians(a));
this.input_text.setText(res.toString());
}
else if (clickStr.equals("del")) {
String res = this.input_text.getText();
if (res.equals("")){
this.input_text.setText("");
}
else {
res = res.substring(0,res.length()-1);
this.input_text.setText(res.toString());
}
}
else if (clickStr.equals("1/x")) {
Double res = Double.valueOf(this.input_text.getText());
res = 1/res;
this.input_text.setText(res.toString());
}
else if (clickStr.equals("x²")) {
Double res = Double.valueOf(this.input_text.getText());
res = res*res;
this.input_text.setText(res.toString());
}
else if (clickStr.equals("√x")) {
Double res = Double.valueOf(this.input_text.getText());
res = Math.sqrt(res);
this.input_text.setText(res.toString());
}
else if (clickStr.equals("+/-")) {
Double res = Double.valueOf(this.input_text.getText());
res = 0-res;
this.input_text.setText(res.toString());
}
5.设计和实现过程
导入所需要的库
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
创建图形化界面,将其封装为了init函数
public static final int FW = 300;
public JPanel jp_north = new JPanel();
public JTextField input_text = new JTextField();
public JButton c_btn = new JButton("C");
public JPanel jp_center = new JPanel();
public Calculator() throws HeadlessException{
this.init();
this.addNorthComponent();
this.addCenterComponent();
}
public void init(){
this.setTitle("Calucator");
this.setSize(FW,FH);
this.setLayout(new BorderLayout());
this.setResizable(false);
this.setLocation(FX,FY);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
首先为其添加顶部的文本框和Clear键,同时将其封装为addNorthComponent函数,为Clear键添加功能
public JPanel jp_north = new JPanel();
public JTextField input_text = new JTextField();
public JButton c_btn = new JButton("C");
public void addNorthComponent(){
this.input_text.setPreferredSize(new Dimension(230,30));
jp_north.add(input_text);
jp_north.add(c_btn);
c_btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
input_text.setText("");
}
});
this.add(jp_north,BorderLayout.NORTH);
为其添加中心输入区的按钮,同时为每个按键添加事件监听
public void addCenterComponent(){
String[] btn_text = new String[]{"sin","cos","tan","del","1/x","x²","√x","/","7","8","9","*","4","5","6","-","1","2","3","+","+/-","0",".","="};
this.jp_center.setLayout(new GridLayout(6,4));
for (int i =0;i<24;i++){
String temp = btn_text[i];
JButton btn = new JButton();
btn.setText(temp);
btn.addActionListener(this);
jp_center.add(btn);
}
this.add(jp_center,BorderLayout.CENTER);
}
捕获每一次的点击,以便之后运算
public void actionPerformed(ActionEvent event) {
String clickStr = event.getActionCommand();
核心运算代码如上文所示
6.程序性能改进
程序默认将图形化界面显示在屏幕左上角,为了美观起见将图形设置在屏幕中央显示,同时设置输入框文本靠右排列,使其更符合现实计算器
public static final int FW = 300;
public static final int FH = 300;
public static final int SW = Toolkit.getDefaultToolkit().getScreenSize().width;
public static final int SH = Toolkit.getDefaultToolkit().getScreenSize().height;
public int FX = (SW - FW)/2;
public int FY = (SH - FH)/2;
this.setSize(FW,FH);
this.setLocation(FX,FY);
this.input_text.setHorizontalAlignment(JTextField.RIGHT);
在加减乘除计算模块中,原先使用equal函数进行符号判定,书写和阅读较为繁琐,后改为matches判定,更为简洁
else if (clickStr.matches("[\\+\\-*/]{1}")){
firstInput = this.input_text.getText();
operator = clickStr;
this.input_text.setText("");
}
7.单元测试
单元测试代码如下
import org.junit.Before;
import org.junit.Test;
import java.awt.event.ActionEvent;
import static org.junit.Assert.*;
public class CalculatorTest {
private Calculator calculator;
@Before
public void setUp() {
calculator = new Calculator();
}
@Test
public void testAddition() {
calculator.input_text.setText("2");
calculator.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "+"));
calculator.input_text.setText("3");
calculator.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "="));
assertEquals("5.0", calculator.input_text.getText());
}
@Test
public void testDivision() {
calculator.input_text.setText("10");
calculator.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "/"));
calculator.input_text.setText("5");
calculator.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "="));
assertEquals("2.0", calculator.input_text.getText());
}
}
单元测试结果如下
8.异常处理
当用户点击del键时,会删除最后一位输入的数字,但如果此时输入框为空,点击del键后系统便会报错。遂加入代码设定当输入框为空时点击del输入框继续为空
else if (clickStr.equals("del")) {
String res = this.input_text.getText();
if (res.equals("")){
this.input_text.setText("");
}
else {
res = res.substring(0,res.length()-1);
this.input_text.setText(res.toString());
}
}
当被除数为0时,违反运算法则,此时输出Error提醒用户
case "/":
if (b !=0){
res = a/b;
this.input_text.setText(res.toString());
break;
}
else {
this.input_text.setText("ERROR");
break;
}
9.心得体会
通过此次作业,我初步了解了图形化界面的编写,提升了java编程能力,深入了解了java事件监听相关内容。同时我也认清了自身在对程序可维护性和简洁性实现上的不足,日后我将加倍努力,不断提升自身素养。