摘 要
本课程设计是要做一个图形界面的计算器,具有良好的界面使用人员能快捷简单的进行操作,及时准确的获得需要的结果,充分降低了数字计算的难度和节约了时间。程序实现了计算器的基本功能:加、减、乘、除基本运算,也可以进行浮点和负数运算和sin、cos、tan等三角函数求值运算,同时能进行简单指数运算和阶乘运算,还有求倒数、退格和清零功能。
关键词:Java 科学计算器 简单运算
第一章 概述
1.1 引言
计算器一般指的是电子计算器。计算器是日常生活中十分便捷有效的工具,能够实现加减乘除等简单的运算功能。采用Java编程语言实现了计算器的功能。该计算器大大降低了数字计算的难度并且提高了计算准确精度和精确度。使用简单,适合广大工作人员和学生使用。
随着信息时代的步伐,越来越多的数字需要我们去处理,然而在我们日常生活中遇到的一些基本数字运算,以往简单的口算笔算,然而现在不同的是人们对计算机、手机的依赖越来越高,遇到计算的问题不愿意用脑去思考,而是交由计算机或者手机来完成。 为了使使用人员能快捷简单的进行操作,及时准确的获得需要的结果,使用Java语言实现了计算器的功能。
1.2用途及特点
Java使一种计算机程序设计语言。它既有高级语言的特点,又具有汇编语言的特点。它可以作为系统设计语言,编写工作系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。因此,它的应用范围很广泛。根据程序设计要求使用Java语言设计一个图形界面(GUI)的计算器应用程序,完成简单的算术应用,使用较为简单方便。该计算器应用程序使用过程中可以进行设计的计算器应用程序可以完成加法、减法、乘法和出发运算,且有小数点、正负号、简单三角函数计算、指数运算、阶乘运算、求倒数、退格和清零功能。
第二章 总体设计
2.1 整体框架
2.2 总体设计
2.2.1 设计思路
(1)本应用程序继承自框架类(JFrame),容器Container,采用BorderLayout边缘布局,文本框区域包含各种按钮面板JPanel。包含各种按钮的面板JPanel采用5行6列的网络布局,然后将数字按钮和运算符按钮以及清除按钮添加到面板中,统一设置按钮的使用方法,设置字体颜色以及增加监听事件。如:
统一设置按钮的使用方法:
private void addButton(JPanel panel, String name, ActionListener action, Color color) {
JButton bt = new JButton(name);
panel.add(bt);//在面板上添加按钮
bt.setForeground(color);//设置前景(字体)颜色
bt.addActionListener(action);//增加监听事件
}
设置字体颜色(对运算符号进行增添颜色):
addButton(panel2, "/", new Signs(), Color.red);
addButton(panel2, "*", new Signs(), Color.red);
addButton(panel2, "-", new Signs(), Color.red);
addButton(panel2, "+", new Signs(), Color.red);
(2)事件监听器中的事件处理方法void actionPerformed(ActionEvent Eve)完成主要的按钮事件处理。事件处理分以下几种情况:数字按钮事件(“0”,“1”,“2”…“8”,“9”)、运算符按钮事件(“+”,“-”,“*”,“/”,“%”)、正负号按钮事件(“+/-”)、小数点按钮事件(“.”)、等号按钮事件(“=”)、求倒按钮事件(“1/x”)、退格按钮事件(“Backspace”)、清除上一次输入的错误按钮事件(“CE”)、清除所有运算和输入(“C”)、记忆数据清除(“MC”)、记忆数据读取(“MR”)、开始记忆数据(“MS”)、计算结果并加上已经储存的数(“M+”)、正弦(“sin”)、余弦(“cos”)、正切(“tan”)等按钮.
在事件处理,触发按钮事件时,先判断是或不是数字、“+/-”、小数点“.”,是的话就将“+”、数字、小数点“.”分别写入文本框并进行相应的处理,都不是的话则跳到doOperation()执行运算同时将运算符存放在preOperater中。触发按钮事件时,要进一步分析,是重新开始计算时触发按钮事件还是计算中间触发的按钮事件。
计算器完成的是一个数学表达式,如:3+2,所以可以采用一个数组来存储数字或字符,如3,+,2分别存储在数组中,最后运算时,如图所示,可以一一取出来进行运算。
利用按钮设计计算器的各个运算符和操作符,通过按钮的事件处理实现按钮计算功能。
利用文本框显示操作数和运算结果。
2.2.2 详细设计
(1)功能实现:
- 加减乘除求余运算
if(oper == "+") {result += x;}//加法运算
else if(oper == "-") {result -= x;}//减法运算
else if(oper == "*") {result *= x;}//乘法运算
else if(oper == "/") {result /= x;}//除法运算
else if(oper == "=") {result = x;}//恒等运算
- 指数运算
else if(oper == "x^y") {result = Math.pow(result, x);}
- 平方根运算
String str = e.getActionCommand();
/* sqrt求平方根 */
if(str.equals("√")) {
double i = Double.parseDouble(tf.getText());
if(i>=0) {
/**
* String.valouOf()转换为字符串
* df.format()按要求保留四位小数
* Math.sqrt()求算术平方根
*/
tf.setText(String.valueOf(df.format(Math.sqrt(i))));
} else {
tf.setText("Data Error!!");
}
}
- 计算y√x
else if(oper == "y√x") {result = Math.pow(result, (double)1/x);}
tf.setText(df.format(result));
}
- 求正弦sin函数
else if(str.equals("sin")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.sin(i))));
}
- 求余弦cos函数
else if(str.equals("cos")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.cos(i))));
}
- 求正切tan函数
else if(str.equals("tan")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.tan(i))));
}
- 求反正弦asin函数
else if(str.equals("asin")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.asin(i))));
}
- 求反余弦acos函数
else if(str.equals("acos")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.acos(i))));
}
- 求反正切atan函数
else if(str.equals("atan")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.atan(i))));
}
- 求倒数(1/x)
else if(str.equals("1/x")) {
if(Double.parseDouble(tf.getText()) == 0) {
tf.setText("Data Error!!");
} else {
tf.setText(df.format(1/Double.parseDouble(tf.getText())));
}
}
- 求n的阶乘(n!)
else if(str.equals("n!")) {
double i = Double.parseDouble(tf.getText());
if((i%2 == 0) || (i%2 == 1))//判断为整数再进行阶乘操作
{
int j = (int)i;
int result = 1;
for(int k = 1; k<=j; k++)
result *= k;
tf.setText(String.valueOf(result));
}
else {
tf.setText("Data Error!!");
}
}
- 求x的平方
else if(str.equals("x^2")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(i*i)));
}
- 求x的立方
else if(str.equals("x^3")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(i*i*i)));
}
else {
if(flag) {
IfResult = false;
}
if(IfResult) {
oper = str;
} else {
getResult(Double.parseDouble(tf.getText()));
oper = str;
IfResult = true;
}
算法思路:
这是一个简单的计算器,里面所涉及到的功能就是加、减、乘、除、等基本功能。在输入数据之后Character. isDigit (Command. charAt (0))判断输入的数据是否符合要求。不符合要求给出提示,符合要求以后将判断点击的运算符,执行相应的操作。
对于单运算操作要进一步判断是否符合要求,如果是就进入下步计算,如果不是就弹出相应的提示:“ 负数不能开根号”:”除数不能为零”: 用ty-. catch捕获异常,如果有异常则中止活动。在进行开方(sqrt) 运算时,如果输入数为负数,则弹出”负数不能开根号”,中止运算。在进行自然对数运算时(log)如果输入数为负数,则弹出”负数不能进行自然对数运算"。在进行三角函数运算时(cos、 tan) 不必考虑输入的数字是否符合规范,对于任意输入的数函数本身有一个判断的过程,都能把输入的数转化为合适的范围,进而得到正确的结果。对于加减乘除等双运算操作,每个功能都由每一一个 模块来实现,当按下加按钮时,进行相应的加法操作,这一块对相应的操作数没有要求:当点击减号时,则进行减法操作,由jTextField. getText )得到数字按钮的值显示在相应的文本框中:乘法操作在点击一一个操作数然后点击乘号再点击另-一个时得出相应的结果显示在文本框中:在作除法运算时,当被除数点击为零时,调用catch进行异常处理,弹出"Infinity".
数据分析
在事件处理,触发按钮事件时,先判断是或是数字是或是“-/+"是或是“.”,是的话就将负号“-”、数字、小数点“.”分别写入文本框并存放在sum中,然后判断是或是“退格”、“求倒”等,是的话进行相应的处理,都不是的话则跳到doOperation()执行运算同时将运算符存放在preOperater 中。触发按钮事件时,要进一步分析,是重新开始计算时触发的按钮事件还是计算中间出发的按钮事件。
程序代码
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;//控制输出数字格式(七位)
import javax.swing.*;
public class Calculator extends JFrame{
private JTextField tf;//定义文本框
private JPanel panel1, panel2, panel3, panel4;//定义面板
private JMenuBar myBar;//创建菜单条
private JMenu menu1, menu2, menu3;//创建菜单
private JMenuItem editItem1, editItem2, help1, help2,help3;//创建菜单项
private JRadioButtonMenuItem seeItem1, seeItem2;//单选框
private JCheckBoxMenuItem seeItem3;//复选框
private ButtonGroup bgb;//创建按钮组
private String back;
private boolean IfResult = true, flag = false;
private String oper = " = ";
private double result = 0;
private Num numActionListener;//添加动作监听器
private DecimalFormat df;
public Calculator() {
super("我的科学计算器");//设置标题栏
df = new DecimalFormat("#.#######");//保留七位小数
this.setLayout(new BorderLayout(10,10));//为容器设置布局
panel1 = new JPanel(new GridLayout(1, 3, 10, 10));
panel2 = new JPanel(new GridLayout(5, 6, 5, 5));//五行六列
panel3 = new JPanel(new GridLayout(5, 1, 5, 5));
panel4 = new JPanel(new BorderLayout(5, 5));
/**
* 菜单栏
*/
myBar = new JMenuBar();
menu1 = new JMenu(" 编辑(E) ");
menu2 = new JMenu(" 查看(V) ");
menu3 = new JMenu(" 帮助(H) ");
menu1.setFont(new Font("宋体", Font.PLAIN, 12));
menu2.setFont(new Font("宋体", Font.PLAIN, 12));
menu3.setFont(new Font("宋体", Font.PLAIN, 12));
/**
* 编辑栏
*/
editItem1 = new JMenuItem("复制(C) Ctrl+C");
editItem2 = new JMenuItem("粘贴(V) Ctrl+V");
editItem1.setFont(new Font("宋体", Font.PLAIN, 12));
editItem2.setFont(new Font("宋体", Font.PLAIN, 12));
/**
* 查看栏
*/
seeItem1 = new JRadioButtonMenuItem("科学型(T)");
seeItem2 = new JRadioButtonMenuItem("标准型(S)");
seeItem3 = new JCheckBoxMenuItem("数字分组(I)");
seeItem1.setFont(new Font("宋体", Font.PLAIN, 12));
seeItem2.setFont(new Font("宋体", Font.PLAIN, 12));
seeItem3.setFont(new Font("宋体", Font.PLAIN, 12));
/**
* 帮助栏
*/
help1 = new JMenuItem("帮助主题(H)");
help2 = new JMenuItem("关于计算器(A)");
help1.setFont(new Font("宋体", Font.PLAIN, 12));
help2.setFont(new Font("宋体", Font.PLAIN, 12));
bgb = new ButtonGroup();//选项组
menu1.add(editItem1);
menu1.add(editItem2);
menu2.add(seeItem1);
menu2.add(seeItem2);
menu2.addSeparator();//添加一条分割线
menu2.add(seeItem3);
menu3.add(help1);
menu3.addSeparator();//添加一条分割线
menu3.add(help2);
myBar.add(menu1);
myBar.add(menu2);
myBar.add(menu3);
this.setJMenuBar(myBar);
numActionListener = new Num();//实现数字监听
/**
* 计算器屏幕显示区域
*/
tf = new JTextField();
tf.setEditable(false);//文本区域不可编辑
tf.setBackground(Color.white);//背景色
tf.setHorizontalAlignment(JTextField.RIGHT);//文字右对齐
tf.setText("0");
tf.setBorder(BorderFactory.createLoweredBevelBorder());
init();//对计算器进行初始化
}
/**
* 初始化操作
* 添加按钮
*/
private void init() {
addButton(panel1, "Backspace", new Clear(), Color.red);
addButton(panel1, "CE", new Clear(), Color.red);
addButton(panel1, "C", new Clear(), Color.red);
addButton(panel2, "1/x", new Signs(), Color.magenta);
addButton(panel2, "x^2", new Signs(), Color.magenta);
addButton(panel2, "7", numActionListener, Color.blue);
addButton(panel2, "8", numActionListener, Color.blue);
addButton(panel2, "9", numActionListener, Color.blue);
addButton(panel2, "/", new Signs(), Color.red);
addButton(panel2, "n!", new Signs(), Color.magenta);
addButton(panel2, "x^3", new Signs(), Color.magenta);
addButton(panel2, "4", numActionListener, Color.blue);
addButton(panel2, "5", numActionListener, Color.blue);
addButton(panel2, "6", numActionListener, Color.blue);
addButton(panel2, "*", new Signs(), Color.red);
addButton(panel2, "sin", new Signs(), Color.magenta);
addButton(panel2, "asin", new Signs(), Color.magenta);
addButton(panel2, "1", numActionListener, Color.blue);
addButton(panel2, "2", numActionListener, Color.blue);
addButton(panel2, "3", numActionListener, Color.blue);
addButton(panel2, "-", new Signs(), Color.red);
addButton(panel2, "cos", new Signs(), Color.magenta);
addButton(panel2, "acos", new Signs(), Color.magenta);
addButton(panel2, "π", numActionListener, Color.blue);
addButton(panel2, "0", numActionListener, Color.blue);
addButton(panel2, ".", new Dot(), Color.blue);
addButton(panel2, "+", new Signs(), Color.red);
addButton(panel2, "tan", new Signs(), Color.magenta);
addButton(panel2, "atan", new Signs(), Color.magenta);
addButton(panel2, "y√x", new Signs(), Color.magenta);
addButton(panel2, "x^y", new Signs(), Color.magenta);
addButton(panel2, "√", new Signs(), Color.red);
addButton(panel2, "=", new Signs(), Color.red);
JButton btns = new JButton("计算器");
btns.setBorder(BorderFactory.createLoweredBevelBorder());
btns.setEnabled(false);//按钮不可操作
btns.setPreferredSize(new Dimension(20, 20));
panel3.add(btns);//加入按钮
addButton(panel3, "MC", null, Color.red);
addButton(panel3, "MR", null, Color.red);
addButton(panel3, "MS", null, Color.red);
addButton(panel3, "M+", null, Color.red);
panel4.add(panel1, BorderLayout.NORTH);
panel4.add(panel2, BorderLayout.CENTER);
this.add(tf, BorderLayout.NORTH);
this.add(panel3, BorderLayout.WEST);
this.add(panel4);
pack();
this.setResizable(true);//窗口可改变大小
this.setLocation(300,300 );//窗口的坐标
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**
* 统一设置按钮的使用方式
* @param panel
* @param name
* @param action
* @param color
*/
private void addButton(JPanel panel, String name, ActionListener action, Color color) {
JButton bt = new JButton(name);
panel.add(bt);//在面板上添加按钮
bt.setForeground(color);//设置前景(字体)颜色
bt.addActionListener(action);//增加监听事件
}
/**
* 计算器的基础操作(+ - * /)
* @param x
*/
private void getResult(double x) {
if(oper == "+") {result += x;}
else if(oper == "-") {result -= x;}
else if(oper == "*") {result *= x;}
else if(oper == "/") {result /= x;}
else if(oper == "=") {result = x;}
/**
* 计算x^y
*/
else if(oper == "x^y") {result = Math.pow(result, x);}
/**
* 计算y√x
*/
else if(oper == "y√x") {result = Math.pow(result, (double)1/x);}
tf.setText(df.format(result));
}
/**
* 运算符号的事件监听
*/
class Signs implements ActionListener{
public void actionPerformed(ActionEvent e) {
/**
* 用ActionEvent对象的getActionCommand()方法
* 取得与引发事件对象相关的字符串
*/
String str = e.getActionCommand();
/* sqrt求平方根 */
if(str.equals("√")) {
double i = Double.parseDouble(tf.getText());
if(i>=0) {
/**
* String.valouOf()转换为字符串
* df.format()按要求保留四位小数
* Math.sqrt()求算术平方根
*/
tf.setText(String.valueOf(df.format(Math.sqrt(i))));
} else {
tf.setText("Data Error!!");
}
}
/* asin求反正弦函数 */
else if(str.equals("asin")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.asin(i))));
}
/* acos求反余弦函数 */
else if(str.equals("acos")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.acos(i))));
}
/* atan求反正切函数 */
else if(str.equals("atan")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.atan(i))));
}
/* 1//x求倒数 */
else if(str.equals("1/x")) {
if(Double.parseDouble(tf.getText()) == 0) {
tf.setText("Data Error!!");
} else {
tf.setText(df.format(1/Double.parseDouble(tf.getText())));
}
}
/* sin求正弦函数 */
else if(str.equals("sin")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.sin(i))));
}
/* cos求余弦函数 */
else if(str.equals("cos")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.cos(i))));
}
/* tan求正切函数 */
else if(str.equals("tan")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(Math.tan(i))));
}
/* n!求阶乘 */
else if(str.equals("n!")) {
double i = Double.parseDouble(tf.getText());
if((i%2 == 0) || (i%2 == 1))//判断为整数再进行阶乘操作
{
int j = (int)i;
int result = 1;
for(int k = 1; k<=j; k++)
result *= k;
tf.setText(String.valueOf(result));
}
else {
tf.setText("Data Error!!");
}
}
/* x^2求平方 */
else if(str.equals("x^2")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(i*i)));
}
/* x^3求立方 */
else if(str.equals("x^3")) {
double i = Double.parseDouble(tf.getText());
tf.setText(String.valueOf(df.format(i*i*i)));
}
else {
if(flag) {
IfResult = false;
}
if(IfResult) {
oper = str;
} else {
getResult(Double.parseDouble(tf.getText()));
oper = str;
IfResult = true;
}
}
}
}
/**
* 清除按钮的事件监听
*/
class Clear implements ActionListener {
public void actionPerformed(ActionEvent e) {
/**
* 用ActionEvent对象的getActionCommand()方法
* 取得与引发事件对象相关的字符串
*/
String str = e.getActionCommand();
if(str == "C") {
tf.setText("0");
IfResult = true;
result = 0;
} else if(str == "Backspace") {
if(Double.parseDouble(tf.getText()) > 0) {
if(tf.getText().length() > 1) {
tf.setText(tf.getText().substring(0, tf.getText().length() - 1));//使用退格键删除最后一位字符
} else {
tf.setText("0");
IfResult = true;
}
} else {
if(tf.getText().length() > 2) {
tf.setText(tf.getText().substring(0, tf.getText().length() - 1));
} else {
tf.setText("0");
IfResult = true;
}
}
} else if(str == "CE") {
tf.setText("0");
IfResult = true;
}
}
}
/**
* 数字输入的事件监听
*/
class Num implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
if(IfResult) {
tf.setText("");
IfResult = false;
}
if(str == "π") {
tf.setText(String.valueOf(Math.PI));
} else {
tf.setText(tf.getText().trim() + str);
if(tf.getText().equals("0")) {
tf.setText("0");
IfResult = true;
flag = true;
}
}
}
}
/**
* 小数点的事件监听
*/
class Dot implements ActionListener {
public void actionPerformed(ActionEvent e) {
IfResult = false;
if(tf.getText().trim().indexOf(".") == -1) {
tf.setText(tf.getText() + ".");
}
}
}
/**
* main方法
*/
public static void main(String[] args) {
new Calculator().setVisible(true);
}
}