《解析Java程序设计》课程实验-多功能计算器-毕业论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《解析Java程序设计》课程实验-多功能计算器-毕业论文
《解析Java程序设计》课程实验
上机实验报告
题目:多功能计算器
专业:计算机与智能科学类
班级:
姓名:
学号:
指导老师:
完成日期: 2013.5.28
目录
一、需求分析和系统设计 (2)
1.1需求分析 (2)
1.1.1功能 (2)
1.1.2算法分析 (2)
1.2方案选择 (2)
1.3模块划分 (3)
1.3.1系统流程图 (3)
1.3.2模块详细流程图 (4)
二、源程序清单 (6)
2.1源程序主体: (6)
2.2源程序测试 (6)
三、单元测试和综合测试 (20)
3.1单元测试 (20)
3.2综合测试 (23)
四、问题及其解决方案 (26)
4.1问题集锦 (26)
4.2解决方案 (26)
五、收获及心得 (27)
一、需求分析和系统设计
1.1需求分析
计算机的发展突飞猛进,人们使用计算机的目的各不相同,但是我们很容易发现,关于计算的问题生活中随处可见,于是计算器也是计算机中必备的软件。
我们可以使用计算器进行复杂的算术运算,也可以用来不同数值之间的转化。
况且数学中我们也经常用到弧度、梯度、角度等的运算,于是计算器应运而生。
计算器是日常生活中十分便捷有效的工具,能实现加、减、乘、除、开方、求倒数等简单运算的工具。
要实现计算功能,可以编写程序来解决此问题。
计算器使用非常简单和方便,对广大中小学生的学习有着促进作用,也对在职人员的工作有点帮助作用。
1.1.1功能
可以实现基本的四则运算,三角函数部分运算,倒数,平方,立方,阶乘,欧拉数 e 的double 次幂的值,10的x次方,log10,开方,ln,百分制转换。
1.1.2算法分析
本课程设计要求学生能够较全面的掌握面向对象程序设计的有关概念和开发方法,以便能较全面地理解、掌握和综合运用所学的知识,提高自身的编程能力。
首先开始设计一个计算器的界面,定义4个Panel放入框架中,其后定义计算器所需要的按钮并赋给其按钮名称,使得使用计算器时简单明了,清晰可见,操作轻松。
给各个按钮进行算法,利用鼠标点击事件,当鼠标点击某个按钮时就开始执行那个按钮所定义的算法,生成数据并显示。
按钮所定义的算法,主要分为三类:第一类是四则运算,第二类是调用Java库函数完成,第三类是自定义算法解决。
1.2方案选择
方案选择这要有以下3个方面的考虑:
1.界面设计的友好和可观性;
2.就目前只是而言,算法实现的难易程度;
3.基于上述两点,程序的运行效率暂不考虑。
最终,程序的方案就是现在的程序,下文将具体介绍。
1.3模块划分
细致一点讲,本程序模块较多。
所以,选择以图示方式展现,且看:
1.3.1系统流程图
开始
按钮区
显示屏
顶行操作键
P
1
P
3
P
4 P
2
输入
输入
输入
否
数字和功能按
重庆邮电大学
1.3.2模块详细流程图P1模块:
结束
输出结
是否继续
?
是
否
开始
Tf2输入
运算
Tf1显示
P3模块:
P4模块:
开始
输入操
参与运
结束
开始
输入数字
进行运
结束
是否继续
?
否
是
二、源程序清单
2.1源程序主体
package myCalculator2;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import ng.Math;
public class myCalculator extends WindowAdapter implements ActionListener { /**
* 题目:简单计算器作者:张良时间:2013.5
*/
String foreNum = null;// 输入的第一个数
String currOpr = null;// 当前操作运算符
String currNum = null;// 输入的第二个数
String copyStr;// 复制字符串
static String save = null;// 保存tf2的信息,在tf1显示
boolean keyIsClicked = true;// 记录键盘按钮是否可用
JFrame f;
JTextField tf1, tf2;
JMenuBar bar;
JMenu menuEdit, menuView, menuHelp;
JMenuItem menuEditCopy, menuEditPaste, menuScan, menuHelpAbout;
JPanel p1, p2, p3, p4;// , p4, p5, p6,p7,p8,p9,p10;
JButton bt0, bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8, bt9;
JButton btBack, btCe, btC, btExit;
JButton btSqrt, btPercent, btReciprocal, btSin, btCos, btTan, btExp, bt10ofx, btX2, btX3, btN, btLog, btLn;
JButton btMinus, btPoint, btEqual, btAdd, btNegative, btMult, btDiv; public myCalculator() {
frame();// 框架
menu();// 菜单
UI();// UI设计
}
public void frame() {
f = new JFrame("DIY计算器");
f.setSize(370, 350);
f.setLocation(300, 300);
f.getContentPane().setBackground(Color.LIGHT_GRAY);
f.setResizable(true);// 能改变窗体大小
f.setLayout(new BorderLayout());
f.setVisible(true);
}
public void menu() {
bar = new JMenuBar();
menuEdit = new JMenu("编辑(E)");
menuView = new JMenu("查看(V)");
menuHelp = new JMenu("帮助(H)");
menuEditCopy = new JMenuItem("复制(C)");
menuEditPaste = new JMenuItem("粘贴(V)");
menuScan = new JMenuItem("看看(s)");
menuHelpAbout = new JMenuItem("关于计算器(A)");
f.setJMenuBar(bar);
bar.add(menuEdit);
bar.add(menuView);
bar.add(menuHelp);
menuEdit.add(menuEditCopy);
menuEdit.add(menuEditPaste);
menuView.add(menuScan);
menuHelp.add(menuHelpAbout);
menuEditCopy.addActionListener(this);
menuEditPaste.addActionListener(this);
menuScan.addActionListener(this);
menuHelpAbout.addActionListener(this);
}
/**
* @param args
*/
public void UI() {
tf1 = new JTextField(15);
tf1.setText(" =");
tf1.setEditable(false);// 不可编辑
tf1.setHorizontalAlignment(JTextField.RIGHT);// 从右侧输入数据tf2 = new JTextField(15);
tf2.setText("0.0");
tf2.setEditable(false);// 不可编辑
tf2.setHorizontalAlignment(JTextField.RIGHT);// 从右侧输入数据p1 = new JPanel(new GridLayout(2, 1));
p2 = new JPanel(new BorderLayout());
p3 = new JPanel();
p4 = new JPanel(new GridLayout(6, 5));
btBack = new JButton("<—");
btCe = new JButton("Ce");
btC = new JButton("C");
btExit = new JButton("off");
btSin = new JButton("sin");
btCos = new JButton("cos");
btTan = new JButton("tan");
btExp = new JButton("exp");
bt10ofx = new JButton("10^x");
btX2 = new JButton("x^2");
btX3 = new JButton("x^3");
btN = new JButton(" n! ");
btLog = new JButton("log");
btLn = new JButton(" ln ");
bt7 = new JButton("7");
bt8 = new JButton("8");
bt9 = new JButton("9");
btDiv = new JButton("/");
btSqrt = new JButton("sqrt");
bt4 = new JButton("4");
bt5 = new JButton("5");
bt6 = new JButton("6");
btMult = new JButton("*");
btPercent = new JButton(" % ");
bt1 = new JButton("1");
bt2 = new JButton("2");
bt3 = new JButton("3");
btMinus = new JButton("-");
btReciprocal = new JButton(" 1/x");
bt0 = new JButton("0");
btPoint = new JButton(".");
btEqual = new JButton("=");
btAdd = new JButton("+");
btNegative = new JButton(" +/-");
p3.add(btBack);// 逐个删除
p3.add(btCe);// 清除当前输入的数据或符号
p3.add(btC);// 清除(clear)键
p3.add(btExit);// 退出键
p4.add(btSin);// sin
p4.add(btCos);// cos
p4.add(btTan);// tan
p4.add(btExp);// 返回欧拉数e 的double 次幂的值p4.add(bt10ofx);// 返回10的x次方
p4.add(btX2);// x的平方
p4.add(btX3);// x的立方
p4.add(btN);// n的阶乘
p4.add(btLog);// log函数
p4.add(btLn);// ln函数
p4.add(bt7);
p4.add(bt8);
p4.add(bt9);
p4.add(btDiv);// 除号
p4.add(btSqrt);// 根号
p4.add(bt4);
p4.add(bt5);
p4.add(bt6);
p4.add(btMult);// 乘号
p4.add(btPercent);// 百分号
p4.add(bt1);
p4.add(bt2);
p4.add(bt3);
p4.add(btMinus);// 减号
p4.add(btReciprocal);// 倒数
p4.add(bt0);
p4.add(btPoint);
p4.add(btEqual);// 等号
p4.add(btAdd);
p4.add(btNegative);// 正负符号
p1.add(tf1);
p1.add(tf2);
f.add(p1, BorderLayout.NORTH);
f.add(p2, BorderLayout.CENTER);
p2.add(p3, BorderLayout.NORTH);
p2.add(p4, BorderLayout.CENTER);
// 设置按键的前景色
btBack.setForeground(new Color(255, 100, 100)); btCe.setForeground(new Color(255, 100, 100)); btC.setForeground(new Color(255, 100, 100)); btEqual.setForeground(new Color(255, 0, 0)); btExit.setForeground(new Color(255, 100, 100)); bt0.setForeground(new Color(255, 0, 0));
bt1.setForeground(new Color(255, 0, 0));
bt3.setForeground(new Color(255, 0, 0));
bt4.setForeground(new Color(255, 0, 0));
bt6.setForeground(new Color(255, 0, 0));
bt7.setForeground(new Color(255, 0, 0));
bt9.setForeground(new Color(255, 0, 0));
bt8.setForeground(new Color(255, 0, 0));
bt5.setForeground(new Color(255, 0, 0));
bt2.setForeground(new Color(255, 0, 0)); btPoint.setForeground(new Color(255, 0, 0)); btSqrt.setForeground(new Color(0, 0, 255)); btPercent.setForeground(new Color(0, 0, 255)); btReciprocal.setForeground(new Color(0, 0, 255)); btNegative.setForeground(new Color(0, 0, 255)); btSin.setForeground(new Color(0, 0, 255));
btCos.setForeground(new Color(0, 0, 255)); btTan.setForeground(new Color(0, 0, 255)); btExp.setForeground(new Color(0, 0, 255)); bt10ofx.setForeground(new Color(0, 0, 255)); btX2.setForeground(new Color(0, 0, 255)); btX3.setForeground(new Color(0, 0, 255)); btN.setForeground(new Color(0, 0, 255)); btLog.setForeground(new Color(0, 0, 255)); btLn.setForeground(new Color(0, 0, 255)); btAdd.setForeground(new Color(0, 0, 255)); btMult.setForeground(new Color(0, 0, 255)); btDiv.setForeground(new Color(0, 0, 255)); btMinus.setForeground(new Color(0, 0, 255)); // 注册监听
bt1.addActionListener(this);
bt2.addActionListener(this);
bt3.addActionListener(this);
bt4.addActionListener(this);
bt5.addActionListener(this);
bt6.addActionListener(this);
bt7.addActionListener(this);
bt8.addActionListener(this);
bt9.addActionListener(this);
bt0.addActionListener(this);
btAdd.addActionListener(this);
btMinus.addActionListener(this);
btMult.addActionListener(this);
btDiv.addActionListener(this);
btEqual.addActionListener(this);
btPoint.addActionListener(this);
btSqrt.addActionListener(this); btPercent.addActionListener(this); btReciprocal.addActionListener(this); btNegative.addActionListener(this); btBack.addActionListener(this);
btCe.addActionListener(this);
btC.addActionListener(this);
btExit.addActionListener(this);
btSin.addActionListener(this);
btCos.addActionListener(this);
btTan.addActionListener(this);
btExp.addActionListener(this);
bt10ofx.addActionListener(this);
btX2.addActionListener(this);
btX3.addActionListener(this);
btN.addActionListener(this);
btLog.addActionListener(this);
btLn.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// TODO 自动生成方法存根
Object obj = e.getSource();
// 输入数字
if (obj == bt1 || obj == bt2 || obj == bt3 || obj == bt4 || obj == bt5 || obj == bt6 || obj == bt7 || obj == bt8 || obj == bt9
|| obj == bt0) {
if (keyIsClicked == true) {
tf2.setText(e.getActionCommand());
save = tf2.getText();
tf1.setText(save);
} else {
tf2.setText(tf2.getText() + e.getActionCommand());
save = tf2.getText();
tf1.setText(save);
}
keyIsClicked = false;
}
// 小数点
else if (obj == btPoint) {
if (keyIsClicked == false) {
tf2.setText(tf2.getText() + '.');
}
}
// 实现开根号
else if (obj == btSqrt) {
save = tf2.getText();
if (tf2.getText().charAt(0) == '-') {// 返回字符串第一个字符tf2.setText("错误!输入无效");
} else
tf2.setText(Double.toString(Math.sqrt(Double.parseDouble(save))));
tf1.setText("x= " + save + " √" + " =");
keyIsClicked = true;
}
// 实现倒数
else if (obj == btReciprocal) {
save = tf2.getText();
for (int i = 0; i < save.length(); i++)
if (save.charAt(i) == '0')
tf2.setText("错误!零不能求倒数");
else {
String s = Double.toString(1 / Double.parseDouble(save));
foreNum = tf2.getText();
tf2.setText(s);
tf1.setText("x= " + save + " 1/x" + " =");
keyIsClicked = true;
}
}
// 实现sin
else if (obj == btSin) {
save = tf2.getText();
tf2.setText(Double.toString(Math.sin(Double.parseDouble(save))));
tf1.setText("x= " + save + " sinx" + " =");
keyIsClicked = true;
}
// 实现cos
else if (obj == btCos) {
save = tf2.getText();
tf2.setText(Double.toString(Math.cos(Double.parseDouble(save))));
tf1.setText("x= " + save + " cosx" + " =");
keyIsClicked = true;
}
// 实现tan
else if (obj == btTan) {
save = tf2.getText();
tf2.setText(Double.toString(Math.tan(Double.parseDouble(tf2 .getText()))));
tf1.setText("x= " + save + " tanx" + " =");
keyIsClicked = true;
}
// 实现exp
else if (obj == btExp) {
save = tf2.getText();
tf2.setText(Double.toString(Math.tan(Double.parseDouble(tf2 .getText()))));
tf1.setText("x= " + save + " exp(x)" + " =");
keyIsClicked = true;
}
// 实现10的x次方
else if (obj == bt10ofx) {
double a, s = 1;
save = tf2.getText();
a = Double.parseDouble(save);
for (int i = 1; i <= a; i++)
s *= 10;
tf2.setText(Double.toString(s));
tf1.setText("x= " + save + " 10^x" + " =");
keyIsClicked = true;
}
// 实现x的平方
else if (obj == btX2) {
double x;
save = tf2.getText();
x = Double.parseDouble(save);
tf2.setText(Double.toString(x * x));
tf1.setText("x= " + save + " x^2" + " =");
keyIsClicked = true;
}
// 实现x的立方
else if (obj == btX3) {
double x;
save = tf2.getText();
x = Double.parseDouble(save);
tf2.setText(Double.toString(x * x * x));
tf1.setText("x= " + save + " x^3" + " =");
keyIsClicked = true;
}
// 实现n的阶乘
else if (obj == btN) {
double a, s = 1;
save = tf2.getText();
a = Double.parseDouble(save);
for (int i = 1; i <= a; i++)
s *= i;
tf2.setText(Double.toString(s));
tf1.setText("n= " + save + " n!" + " =");
keyIsClicked = true;
}
// 实现log
else if (obj == btLog) {
save = tf2.getText();
tf2.setText(Double.toString(Math.log10(Double.parseDouble(tf2
.getText()))));
tf1.setText("x= " + save + " logx" + " =");
keyIsClicked = true;
}
// 实现ln
else if (obj == btLn) {
save = tf2.getText();
tf2.setText(Double.toString(Math.log(Double.parseDouble(tf2
.getText()))));
tf1.setText("x= " + save + " lnx" + " =");
keyIsClicked = true;
}
// 实现+/-符号
else if (obj == btNegative) {
boolean isNumber = true;
String s = tf2.getText();
for (int m = 0; m < s.length(); m++)
if (!(s.charAt(m) >= '0' && s.charAt(m) <= '9'
|| s.charAt(m) == '.' || s.charAt(m) == '-')) {
break;
}
if (isNumber == true) {
// 如果当前字符串首字母有-号,代表现在是个负数,再按下时,则将首符号去掉
if (s.charAt(0) == '-') {
tf2.setText("");
for (int m = 1; m < s.length(); m++) {
char a = s.charAt(m);
tf2.setText(tf2.getText() + a);
save = save + tf2.getText();
tf1.setText(save);
}
}
// 如果当前字符串第一个字符不是负号,则添加一个符号在首字母处
else {
tf2.setText('-' + s);
tf1.setText(tf2.getText());
}
}
}
// 实现%功能
else if (obj == btPercent) {
boolean isNumber = true;
if (isNumber == true)
tf2.setText(String.valueOf(Double.parseDouble(tf2.getText()) / 100));
else
tf2.setText("错误");
}
// 实现四则运算
else if (obj == btAdd || obj == btMinus || obj == btDiv
|| obj == btMult) {
if (keyIsClicked == false) {
currNum = tf2.getText();
try {
if (currOpr == "+") {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
+ Double.parseDouble(currNum)));// valueOf()要把参数中给的值,转化为String类型
} else if (currOpr == "-") {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
- Double.parseDouble(currNum)));
} else if (currOpr == "*") {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
* Double.parseDouble(currNum)));
} else if (currOpr == "/") {
if (Double.parseDouble(tf2.getText()) == 0)
tf2.setText("除数不能为零");
else {
tf2.setText(String.valueOf(Double
.parseDouble(foreNum)
/ Double.parseDouble(currNum)));
}
}
} catch (NumberFormatException exc) {
System.out.println("请先输入计算的数字!");
exc.toString();
}
}
foreNum = tf2.getText();
tf2.setText("");
currOpr = e.getActionCommand();
keyIsClicked = false;
}
// 实现等号
else if (obj == btEqual) {
currNum = tf2.getText();
if (currOpr == "+") {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
+ Double.parseDouble(currNum)));
tf1.setText(foreNum + "+" + currNum + " =");
} else if (currOpr == "-") {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
- Double.parseDouble(currNum)));
tf1.setText(foreNum + "-" + currNum + " =");
} else if (currOpr == "*") {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
* Double.parseDouble(currNum)));
tf1.setText(foreNum + "*" + currNum + " =");
} else if (currOpr == "/") {
if (Double.parseDouble(tf2.getText()) == 0)
tf2.setText("除数不能为零");
else {
tf2.setText(String.valueOf(Double.parseDouble(foreNum)
/ Double.parseDouble(currNum)));
tf1.setText(foreNum + "/" + currNum + " =");
}
}
currOpr = e.getActionCommand();
keyIsClicked = true;
}
// 实现Backspace功能
else if (obj == btBack) {
String s = tf2.getText();
tf2.setText("");
for (int m = 0; m < s.length() - 1; m++) {
char a = s.charAt(m);
tf2.setText(tf2.getText() + a);
keyIsClicked = true;
}
}
// 实现Ce功能
else if (obj == btCe) {
tf2.setText("");
}
// 实现C功能
else if (obj == btC) {
foreNum = currNum = save = null;
keyIsClicked = true;
tf2.setText("0.0");
tf1.setText(" =");
}
// 实现退出功能
else if (obj == btExit) {
System.exit(0);
}
// 实现复制
else if (obj == menuEditCopy) {
copyStr = tf2.getText();
}
// 实现粘贴
else if (obj == menuEditPaste) {
tf2.setText(copyStr);
}
// 实现查看主题
else if (obj == menuScan) {
ImageIcon icon = new ImageIcon("计算器.jpg");
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(f, label, "查看主题", JOptionPane.PLAIN_MESSAGE);
}
// 实现帮助主题
else if (obj == menuHelpAbout) {
ImageIcon icon = new ImageIcon("介绍.jpg");
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(f, label, "帮助主题",
JOptionPane.PLAIN_MESSAGE);// JOptionPane
// 有助于方便地弹出要求用户提供值或向其发出通知的标准对话框
} // showMessageDialog 告知用户某事已发生。
} // PLAIN_MESSAGE未使用图标
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
}2.2源程序测试
package myCalculator2;
import javax.swing.UIManager;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName() );// UIManager统一管理当前外观
} catch (Exception e) {// getSystemLookAndFeelClassName()如果有实现本机系统外观的
// LookAndFeel 类的名称,则返回该名称;否则返回默认的跨平台
// LookAndFeel 类的名称。
e.printStackTrace();
}
new myCalculator();
}
三、单元测试和综合测试
3.1单元测试
P1模块:
测试结果良好,达到预期效果。
P3模块:
测试结果良好,达到预期效果。
P4模块:
测试结果良好,达到预期效果。
3.2综合测试
鉴于篇幅,此处未完全将测试结果展示出来。
此处仅举数例即可。
四、问题及其解决方案
4.1问题集锦
1.界面如何布局
2.文本域的使用
3.按钮怎样实现
4.菜单如何编辑
5.一行输入,如何两行显示
4.2解决方案
1.综合使用BorderLayout,FlowLayout,GridLayout布局即可解决,做之前先画草图;
2.引入import javax.swing.JTextField;
3.实现监听事件,实现ActionListener接口;
4.引入import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem;
5.将两个文本域放在一个panel里,即tf1和tf2,综合使用tf1和tf2的setText()和getText()方法,实现组件间的信息传递。
五、收获及心得
. 通过这次实验,使我更深刻认识到了面向对象的编程的基本思想,了解了Java编程的流程,通过查资料更是明白了许多函数的用法,解决了学习中的很多谜团。
在课堂上学习中不明白的,没掌握的,认识不深刻的,通过自己动手实践,都有了解答。
就比如说吧,怎样实现一行输入,两行显示的功能,刚开始头乱乱的,后来看了JTextField类的方法,于是就慢慢生出一个想法,可以使用setText()和getText()方法实现组件间的信息传递,通过设置合理的中间变量,我做到了,这就是收获。
同时让我对JFrame类、JPanel类、5种布局管理器、文本框、标签及按钮的使用方法,有了进一步的了解。
同时在实验过程中也发现了自己的许多不足,但通过查询对其有有了更深刻大大大的了解。
学习过程中,感谢老师的精心地教导和理解学生,对我的遇到的问题耐心细致地解答。
俗话说老师引进门修行靠各人,今后也一定继续保持这股对Java 的热情,提升自己的编程能力,把课堂所学的东西多用用,多做做有价值的东西。