目 录
摘 要
课程设计《计算器模拟程序》通过采用面向对象的程序设计方法,Java Swing 设计计算器图形化界面,JAVA 为前台开发工具,SQL Server为后台数据库,开发了一个为人们生活带来便利的计算器,主要完成对数据的高效计算。
随着人们物质生活水平的日益提高,人民对高质量的计算提出了更高的要求,当今是云计算的生活和物联网发展和使用阶段,计算性能的高低和计算的效率直接影响到人们生活与各大高校人才的培养质量。基于此,有助于实现计算的信息化、规范化和科学化,使需要计算的人员能够及时、准确地计算所要计算的结果。该系统的主要功能是实现基本数学运算、函数等功能:加、减、乘、除、正切、余弦、平方根、自然对数、幂和倒数运算。各程序模块均不同程度低显示了其主要功能。
关键词:图形化界面;JAVA;数据库;计算器
1 前言
计算器是一种很常用的计算工具,它在计算方面、日常生活中给我们提供很大 的方便,在编辑此程序时,除了包括常用的加法运算算法、减法运算算法、乘法运 算算法、除法运算算法等四大模块之外。还特意添加了正负数的四则混合运算,给 本系统增加了一个亮点。其次本程序对其它算法也有很高的要求,对编程过程中所 用到的接口、抽象、对象、类等方法和过程提出较高的要求,同时对编程过程中所 编写的实验代码也不同程度的提出了很高的要求,所以在编程的过程中难免遇到了一些困难,所以在完成本次系统的过程中过程中充满了挑战与机遇。
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
SQL Server是由Microsoft开发和推广的关系数据库管理系统(DBMS),它最初是由Microsoft、Sybase和Ashton-Tate三家公司共同开发的,并于1988年推出了第一个OS/2版本。SQL语句可以用来执行各种各样的操作,例如更新数据库中的数据,从数据库中提取数据等。目前,绝大多数流行的关系型数据库管理系统,如Oracle,Sybase,Microsoft SQL Server,Access等都采用了SQL语言标准。虽然很多数据库都对SQL语句进行了再开发和扩展,但是包括Select,Insert,Update,Delete,Create,以及Drop在内的标准的SQL命令仍然可以被用来完成几乎所有的数据库操作。
2 选题的目的和意义
2.1 目的
1.巩固书本知识,对书上的知识能更透彻的了解,通过设计程序积累调试的经验以及培养编程能力。巩固所学的Java知识,消化课堂所讲解的内容。课本上的知识是机械的,表面的。通过把该算法的内容,算法执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验 原理有更深的理解。
2.通过课程设计能更好的掌握Java程序中的设计思路,为以后灵活运用奠定基础。通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了计算器程序从理论到现实在计算机中是怎样执行的,对Java理论在实践中的应用有深刻的理解。
3.通过对Java Swing和SQL Server数据库的应用,完成了设计方案。达到增强巩固Java知识的目的,使知识全面化、系统化。
4.能够独立的完成简单程序的设计以及完成一份较为满意的程序设计报告。
2.2 意义
Java的学习过程,是进行复杂程序设计的训练过程,是思维方法的训练过程,技能培养的过程不亚于知识传授。Java课程教学的重要内容和主要难点在于让我们理解、习惯构造性思维方法。培养我们的数据抽象能力、算法设计能力以及创造性思维和方法,才能够举一反三、触类旁通,从而达到应用知识解决复杂问题的目的。
Java作为专业基础课程,为后续专业基础课程提供基础,它承上启下、贯通始终,是计算机科学与技术人才素质框架中的脊梁,对能力的培养至关重要。通过对Java思维的学习,能够以问题求解方法、程序设计方法及一些典型的Java算法为对象,学会分析数据对象特征,掌握数理算法,初步掌握算法的时间、空间复杂分析基础,培养良好的程序设计风格以及进行复杂程序设计的技能。
3 设计方案
3.1需求分析
第一 该计算器模拟程序需要实现加、减、乘、除四个基本功能。
第二 在基础上添加正切、余弦、平方根、自然对数、幂和倒数运算。
第三 通过数据库的连接,在数据库表中写入以及读取数据。
3.2前端界面设计
本应用程序继承自框架类(JFrame),容器Containerc采用BorderLayout边缘布局,将单行文本框加入到“North ”区域,包含各种按钮的面板JPanel p加入到 “Center ”区域。包含各种按钮的面板JPanel p 采用3行9列的网格布局。
3.3后台数据设计
将数字按钮和运算符按钮以及控制按钮用一个增强for循环添加到面板中同时注册按钮事件监听器。如:
Button b=new Button();
b.addActionListener(事件监听器);
事件监听器中的事件处理方法void actionPerformed(ActionEvent e)完成主要的按钮事件的处理。事件处理分以下几种情况:数字按钮事件(‘0 ’,‘1’,‘2 ’…‘8’,‘9’)、运算符按钮事件(‘+ ’,‘- ’,‘* ’, ‘/ ’, ‘% ’)、正负号按钮事件(‘+/-’)、小数点按钮事件(‘. ’)、等号按钮事件(‘=’)、求倒按钮事件(‘求倒数’)、退格按钮事件(‘退格’)、清除按钮事件(‘C’) 、正切(tan)、余弦(cos),以及求平方根(sqrt)、指数(pow)、对e的指数(exp)、对数运算(log)。
在事件处理,触发按钮事件时,先判断是或是数字是或是“-/+”是或是“.”,是的话就将负号“-”、数字、小数点“.”分别写入文本框并存放在sum中,然后判断是或是“退格”、“求倒”等,是的话进行相应的处理,都不是的话则跳到 doOperation() 执行运算同时将运算符存放在 preOperater 中。触发按钮事件时,要进一步分析,是重新开始计算时触发的按钮事件还是计算中间触发的按钮事件。
这是一个简单的计算器,里面所涉及到的功能就是加、减、乘、除、等基本功能。在输入数据之后 Character.isDigit(Command.charAt(0)) 判断输入的数据是否符合要求。不符合要求给出提示,符合要求以后将判断点击的运算符,执行相应的操作。
对于单运算操作要进一步判断是否符合要求,如果是就进入下步计算,如果不是就弹出相应的提示:‘负数不能开根号’;‘除数不能为零’;用try… .catch捕获异常,如果有异常则中止活动。在进行开方(sqrt)运算时,如果输入数为负数,则弹出‘负数不能开根号’,中止运算。在进行自然对数运算时(log)如果输入数为负数,则弹出"负数不能进行自然对数运算”。在进行三角函数运算时(cos、tan)不必考虑输入的数字是否符合规范,对于任意输入的数函数本身有一个判断的过程,都能把输入的数转化为合适的范围,进而得到正确的结果。对于加减乘除等双运算操作,每个功能都由每一个模块来实现,当按下加按钮时,进行相应的加法操作,这一块对相应的操作数没有要求;当点击减号时,则进行减法操作,由 jTextField.getText() 得到数字按钮的值显示在相应的文本框中;乘法操作在点击一个操作数然后点击乘号再点击另一个时得出相应的结果显示在文本框中;在作除法运算时,当被除数点击为零时,调用catch进行异常处理,弹出“ Infinity ”。
在事件处理,触发按钮事件时,先判断是或是数字是或是“-/+”是或是“.”,是的话就将负号“-”、数字、小数点“.”分别写入文本框并存放在sum中,然后判断是或是“退格”、“求倒”等,是的话进行相应的处理,都不是的话则跳到 doOperation() 执行运算同时将运算符存放在 preOperater 中。触发按钮事件时,要进一步分析,是重新开始计算时触发的按钮事件还是计算中间触发的按钮事件。
4 概要设计
4.1系统总体结构
根据课程设计题目的功能要求,总体概要的组成框图如图4-1、4-2所示:
图4-1 数据存入流程图
图4-2 数据读取流程图
4.2程序模块说明
数据库连接模块:
存入数据:
void ShuJu(double sum){
double s1=sum; //将结果记录到数据库数据表
SimpleDateFormat data=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取当前系统时间信息,将其记录到数据表
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//注册数据库驱动
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection con = null;
try{ //连接本地数据库
con= DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;
database=KECHENGSHEJI", "shengyiguo", "1234567890");
} catch (SQLException e) {
e.printStackTrace();
}
try {
con.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("已将数据添加到表格");
PreparedStatement ps = null;
String sql="INSERT INTO shuju(日期,数据) VALUES (?,?)";
try{ //利用数据库语句向数据表中添加数据
ps=con.prepareStatement(sql);
ps.setString(1, data.format(new Date()));
ps.setString(2, String.valueOf(s1));
}catch (SQLException e) {
e.printStackTrace();
}
try {
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
try {//关闭资源
if (con != null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (ps != null)
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
读取数据:
void lishi(){
ResultSet resultSet=null;
Connection con = null;
Statement stat;
PreparedStatement ps= null;
String time;
Double shuju;
try {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
con = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;
database=KECHENGSHEJI","shengyiguo","1234567890");
con.setAutoCommit(true);
stat=con.createStatement();
String sql="SELECT 日期,数据 FROM shuju";
resultSet=stat.executeQuery(sql);
ps=con.prepareStatement(sql);
System.out.println(" "+"日期"+" "+"数据");
while(resultSet.next()){
time=resultSet.getString("日期");
shuju=resultSet.getDouble("数据");
ArrayList<String> arrayList1=new ArrayList<>();
ArrayList<String> arrayList2=new ArrayList<>();
arrayList1.add(time);
arrayList2.add(String.valueOf(shuju));
Object[][] table=new Object[arrayList1.size()][2];
for (int i = 0; i < arrayList1.size(); i++) {
table[i][0]=arrayList1.get(i);
table[i][1]=arrayList2.get(i);
}
System.out.println(Arrays.deepToString(table));
}
} catch (SQLException e) {
e.printStackTrace();
}
if (con!=null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try{
resultSet.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
- 主程序:
public static void main(String[] args) {
JFrame x=new ZhuJieMian("计算器"); //设置名称
x.setBounds(300,100,630,290); //窗口大小,初始位置
x.setVisible(true);
}
5 设计结果验证
5.1内容
运行主程序,分别测试加、减、乘、除、余弦、正切、平方根、自然对数、幂和倒数运算,如果成功,则在数据库数据表中则可以查看到数据。
5.2结果
程序运行成功:
运行前:
运行后:
通过验证,该程序实现了所需功能。
6结论与总结
实验达到了预期的目标。通过此次的编程,我学会了用 Java 语言编写简单的软件,增强了我对学习 Java的兴趣,使我更进一步加深了对 Java 语言程序设计基础的掌握。在做本次课程设计的过程中,我感触最深的当属查阅了很多次设计书和指导书。编程过程中,总体设计主要是窗口与组件的应用,具体执行则是利用Java语言设计算法,而难点也在算法的设计上。
作为一名计算机专业学生掌握一门或儿门计算机软件语言是必不可少的,虽然 本次课程设计没有要求尽可能多的用到教材中所学的全部知识,在整个设计过程中我都竭尽所能地都用到了它。编程过程中先后涉及Java 语言的使用,语言的开发环境,熟练掌握 JDK 的环境变量的设置,使用和查找。使用 JDK 来查找和使用各项接口、类、对象,继承类等的功能。创建对象、for循环、函数的抛出异常、继承、接口等各种函数。尽可能的使用了各种方法嵌入到函数之中。使用方法;使用继承、类、抽象等方法实现该程序。使用import java.awt. *; 创建用户界面和绘制图形图像的所有类;import java. awt. event.*;提供处理AWT组件所激发的各类事件的接口和类等方法。 最后使该程序显示GUI用户界面。
在程序的书写及执行过程中存在着一些问题,自身的原因是对 Java 各种函数及其方法使用不够熟练,影响了程序设计的总体的进度。虽然程序大体上符合要求,但由于第一次编写这么复杂的程序,程序仍然存在一些漏洞,如历史数据界面,只能在运行界面查看,无法单独弹出界面展示。我觉得在编程时应该注意排版对齐,这样不论是自己检查程序还是别人阅读程序都会更加方便。如果能添加备注的话以后阅读程序会更容易些。在以后的编程中我会吸取经验,养成认真、严谨的编程习惯。
参考文献
1.叶核亚.Java程序设计基础实用教程[M].北京:电子工业出版社,2018:74-88.
2.蔡翠平.Java程序设计[M].北京:北方交通大学出版社,2016:157-166.
3.印雯.Java面向对象程序设计教程[M].北京:高等教育出版社,2019:115-122.
4.吴逸贤.精彩Java程序设计[M].北京:科学出版社,2016:55-58.
5.肖雯.Java程序设计教程[M].北京:中国电力出版社,2017:223-235.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
public class LianJie2 {
public static class ZhuJieMian extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
//实现序列化,serialVersionUID 用来表明实现序列化类的不同版本间的兼容性
JTextField x; //文本框
String preOperater = ""; //上一次的运算符
double sum = 0; //运算结果
public ZhuJieMian(String title) {
super(title);
Container c = getContentPane(); //容器
c.setLayout(new BorderLayout()); //容器采用边缘布局
x = new JTextField(50);
c.add("North", x);
String[] buttoned = {"7","8", "9", "+/-", "C", "退格", "倒数",
"4", "5", "6", "+", "-", "*", "/",
"1", "2", "3","sqrt", "pow", "log10", "%",
".", "0","=","cos", "tan", "exp","历史"};
JPanel p = new JPanel(); //面板
p.setLayout(new GridLayout(4, 7, 10, 10)); //面板采用行列数3, 9的网格布局
for (String s : buttoned) { //用一个for循环将按钮添加进面板并注册监听器
JButton b = new JButton(s);
p.add(b);
b.addActionListener(this);
}
c.add("Center", p);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//响应用户事件,根据点击按钮实现相关操作
public void actionPerformed(ActionEvent e) {
String Command = e.getActionCommand();
try {
if (Character.isDigit(Command.charAt(0))) {//如果按钮事件为数字键
x.setText(x.getText() + Command); //添加数字
} else if (Command.equals(".")) { //如果按钮事件为”.”键
xiaoshu();
} else if (Command.equals("+/-")) { //如果按钮事件为”+/-”键"
fuhao();
} else if (Command.equals("退格")) { //如果按钮事件为”退格”键
backspace();
} else if (Command.equals("=")) { //如果按钮事件为"=”键
dengyu();
} else if (Command.equals("sqrt")) { //如果按钮事件为"sqrt"键
sqrt();
} else if (Command.equals("log")) { //如果按钮事件为"1og”键
log();
} else if (Command.equals("cos")) { //如果按钮事件为"cos”键
cos();
} else if (Command.equals("tan")) { //如果按钮事件为”tan”键
tan();
} else if (Command.equals("exp")) { //如果按钮事件为"exp”键
exp();
} else if (Command.equals("倒数")) { //如果按钮事件为”求倒”键"
qiudao();
} else if (Command.equals("C")) { //如果按钮事件为"C"键
clear();
} else if (Command.equals("历史")){ //如果按钮事件为"历史"键
lishi();
} else {
doOperation(); //记录运算符和输入的数字
x.setText("");
preOperater = Command;
}
} catch (Exception ex) {
sum = 0;
x.setText("");
}
}
void xiaoshu() { //添加小数点
String s = x.getText();
if (!s.contains(".")) x.setText(s + ".");
}
void fuhao() { //添加负号
String s = x.getText();
if (!s.contains("-"))
x.setText("-" + x.getText());
}
void backspace() { //退格
String s = x.getText();
if (s.length() > 0)
x.setText(s.substring(0, s.length() - 1));
} //删除最后-一个字符
void dengyu() { //等号,显示计算结果
doOperation();
x.setText("" + sum);
ShuJu(sum);
preOperater = "";
}
void sqrt() { //求该数的平方根
double m = Double.parseDouble(x.getText());
if (m < 0)
x.setText("负数不能开根号");
else
x.setText("" + Math.sqrt(m));
}
void log() { //求该数的自然对数
double m = Double.parseDouble(x.getText());
if (m < 0)
x.setText("负数不能进行自然对数运算");
else
x.setText("" + Math.log10(m));
}
void cos() { //求该数的余弦
double m = Double.parseDouble(x.getText());
x.setText("" + Math.cos(Math.toRadians(m)));
}
void tan() {//求该数的正切
double m = Double.parseDouble(x.getText());
x.setText("" + Math.tan(Math.toRadians(m)));
}
void exp() { //求e的幂
double m = Double.parseDouble(x.getText());
x.setText("" + Math.exp(m));
}
void qiudao() { //求倒数
if (Double.parseDouble(x.getText()) == 0)
x.setText("除数不能为零");
else {
x.setText(" " + 1 / (Double.parseDouble(x.getText())));
preOperater = "";
}
}
void clear() { //清零
sum = 0;
x.setText("");
preOperater = "";
}
//根据记录的运算符将前面记录的结果sum与文本框中的数据进行运算
void doOperation() {
double m = Double.parseDouble(x.getText());
if (preOperater.equals("")) sum = m; //将结果与文本框中的数据按照前一个运算符运算
if (preOperater.equals("+")) sum = sum + m; //加法运算
if (preOperater.equals("-")) sum = sum - m; //减法运算
if (preOperater.equals("*")) sum = sum * m; //乘法运算
if (preOperater.equals("/")) sum = sum / m; //除法运算
if (preOperater.equals("%")) sum = sum % m; //求余
if (preOperater.equals("pow")) sum = Math.pow(sum, m);
}
void ShuJu(double sum){
SimpleDateFormat data=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
double s1=sum;
Connection con = null;
PreparedStatement ps = null;
try {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
con = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;database=KECHENGSHEJI", "shengyiguo", "1234567890");
con.setAutoCommit(true);
System.out.println("已将数据添加到表格");
String sql = "INSERT INTO shuju(日期,数据) VALUES (?,?)";
ps = con.prepareStatement(sql);
ps.setString(1, data.format(new Date()));
ps.setString(2, String.valueOf(s1));
ps.executeUpdate();
}catch (SQLException e){
e.printStackTrace();
}
try {
if (con != null)
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if (ps != null)
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
void lishi(){
ResultSet resultSet=null;
Connection con = null;
Statement stat;
PreparedStatement ps= null;
String time;
Double shuju;
try {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
con = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1:1433;database=KECHENGSHEJI","shengyiguo","1234567890");
con.setAutoCommit(true);
stat=con.createStatement();
String sql="SELECT 日期,数据 FROM shuju";
resultSet=stat.executeQuery(sql);
ps=con.prepareStatement(sql);
System.out.println(" "+"日期"+" "+"数据");
while(resultSet.next()){
time=resultSet.getString("日期");
shuju=resultSet.getDouble("数据");
ArrayList<String> arrayList1=new ArrayList<>();
ArrayList<String> arrayList2=new ArrayList<>();
arrayList1.add(time);
arrayList2.add(String.valueOf(shuju));
Object[][] table=new Object[arrayList1.size()][2];
for (int i = 0; i < arrayList1.size(); i++) {
table[i][0]=arrayList1.get(i);
table[i][1]=arrayList2.get(i);
}
System.out.println(Arrays.deepToString(table));
}
} catch (SQLException e) {
e.printStackTrace();
}
if (con!=null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps!=null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet!=null){
try{
resultSet.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
JFrame x=new ZhuJieMian("计算器"); //名称
x.setBounds(300,100,630,290);
//x.setSize(630,290); //按键大小,若大小不合适则会出现文字显示不全的现象
x.setVisible(true);
}
}