科学计算器的面向对象设计
一、项目介绍
1.功能要求:
本课程设计是做了一个图形界面的科学计算器,其界面主要是由swing组件中的控件构成。程序实现了计算器的基本功能有:加、减、乘、除基本算术运算(可以进行浮点和负数运算),同时能进行指数运算和自然对数运算,还有退格、清零,查看历史记录功能 。
2.功能架构图

二、个人任务简述
1. 完成的任务与功能:
|
序号 |
完成功能与任务 |
描述 |
|
1 |
全局搜索功能 |
采用swing编写客户端服务器可视化界面 |
|
2 |
面向对象设计 |
基本完成面向对象技术设计系统 |
|
3 |
数据库读写编码部分 |
使用JDBC连接数据库,DAO模式读写数据,直接底层操作,提供了简单,便捷的访问数据库的方法,跨平台性较强,灵活比较强,可以执行很复杂的SQL语句。 |
|
4 |
数据库设计 |
采用MySQL数据库。表设计符合第三范式。 |
2.项目Git地址
https://gitee.com/li-rong-a-song/test.git
3.Git提交记录截图

三、本人负责功能详解
1. *面向对象设计
类设计说明:


2. *全局搜索功能:
2.1 采用swing编写客户端服务器可视化界面

2.2 关键代码
public class MainJFrame extends JFrame { private boolean flag = false; Button btn[] = new Button[] { new Button("x²"), new Button("√"), new Button("mod"), new Button("log"), new Button("("), new Button(")"), new Button("CE"), new Button("Del"), new Button("7"), new Button("8"), new Button("9"), new Button("+"), new Button("4"), new Button("5"), new Button("6"), new Button("-"), new Button("1"), new Button("2"), new Button("3"), new Button("*"), new Button("0"), new Button("."), new Button("="), new Button("/"), };// 设置按键部分 //设置面板组件 private JPanel content1 = new JPanel(); private JPanel content = new JPanel(); private JPanel jbt = new JPanel();//按钮 private JPanel jpb = new JPanel(); private JPanel jpa = new JPanel(); public JTextField jtf = new JTextField();//创建单行文本输入框 public JTextArea jta = new JTextArea("历史记录");//创建一个显示指定文字的多行文本输入框 public MainJFrame() { content.setLayout(new BorderLayout());//设置为边框布局管理器 content1.setLayout(new BorderLayout());//设置为边框布局管理器 jta.setEditable(false);//调用次函数的控件不能被编辑 jta.setBackground(Color.white);//设置背景为白色 jta.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 20));//设置字体为宋体,字号20 jpa.setLayout(new BorderLayout());//设置为边框布局管理器 Border border = BorderFactory.createLineBorder(Color.BLACK);//创建黑色边框 jta.setBorder(BorderFactory.createCompoundBorder(border, BorderFactory.createEmptyBorder(10, 10, 10, 10))); //为文本框jta设置矩形边框 jta.setLineWrap(true);//文本区行的长度大于所分配的宽度时,将换行 JScrollPane scrollPane = new JScrollPane(jta, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);//设置带滚动条的面板 add(scrollPane);//加入到组件jta content1.add(jpa,BorderLayout.EAST);//向界面容器conten1东区域加入边框组件jpa JMenuBar menuBar = new JMenuBar();//创建菜单栏对象 JMenu menu1 = new JMenu("清空历史");//子菜单栏 JMenuItem copyMenuItem = new JMenuItem("确定");//设置菜单项,当用户选择“按钮”时,将执行与菜单项相关联的操作 copyMenuItem.addActionListener(new Menulistent());//监听菜单项按钮 menu1.add(copyMenuItem);//菜单项按钮加入菜单栏中 menu1.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);//设置子菜单对齐菜单栏右侧 menuBar.add(menu1);//子菜单加入菜单栏 setJMenuBar(menuBar);//设置为窗体的菜单栏 jtf.setPreferredSize(new Dimension(300, 100));//设置组件大小 jtf.setEditable(false);//调用次函数的控件不能被编辑 jtf.setBackground(Color.white);//设置背景为白色 jtf.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 50));//设置字体为宋体,字号50 jtf.setHorizontalAlignment(JTextField.RIGHT);//设置文本向右对齐 jpb.setLayout(new BorderLayout());//设置为边框布局管理器 jpb.add(jtf);//jtf文本框组件加入jpb面板组件中 content.add(jpb, BorderLayout.NORTH);//向界面容器conten北区域加入边框组件jpb jbt.setLayout(new GridLayout(6, 4));//设置⽹格布局管理器 for (int i = 0; i < btn.length; i++) { jbt.add(btn[i]);//按钮加入jbt组件中 if (i != 22 && i != 7 && i != 6 && i != 0) btn[i].addActionListener(new Listen());//显示数字 else btn[i].addActionListener(new Result());//计算结果 } content.add(jbt, BorderLayout.CENTER);//向界面容器conten中间区域加入边框组件jbt this.add(content, BorderLayout.WEST);//向窗体西区域加入界面容器content setTitle("计算器");//设置窗体标题 setSize(500, 400);//设置窗体大小 setResizable(false);//窗体不允许用户调整大小 setLocationRelativeTo(null);//设置窗体居中显示 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗口关闭方式 setVisible(true);//显示窗口 }
3. *数据库读写编码部分
3.1 使用JDBC连接数据库,并用DAO模式读写数据
3.2 关键代码
public class CounterDaoImpl implements CounterDao { @Override public void insert(String cal) {//插入记录 Connection conn = null; PreparedStatement ps = null; String sql = "insert into mycal(history) value(?)"; try { conn = JDBCUtil.getConnection(); ps = conn.prepareStatement(sql); ps.setString(1, cal); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); System.out.println("添加数据失败"); } } @Override public void delete() {//删除记录 Statement stmt = null; PreparedStatement ps = null; Connection con = null; try { String sqldelect = "DELETE FROM mycal"; con = JDBCUtil.getConnection(); stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); ps = con.prepareStatement(sqldelect); ps.executeUpdate(); System.out.println("删除成功"); } catch (SQLException e1) { System.out.println("查询数据库出错"); e1.printStackTrace(); } finally { try { stmt.close(); con.close(); } catch (SQLException e1) { System.out.println("关闭资源出错"); e1.printStackTrace(); stmt = null; con = null; } } } @Override public List<String> diplayAllCal() {//查询记录 String sql = "select * from mycal";// 表中有id和history这列 try (Connection conn = JDBCUtil.getConnection(); PreparedStatement pstat = conn.prepareStatement(sql);) { ResultSet rs = pstat.executeQuery(sql); List str= new ArrayList(); while (rs.next()) { int id = rs.getInt("id"); String history = rs.getString("history"); str.add(history); } return str; } catch (SQLException e1) { System.out.println("查询数据库出错"); e1.printStackTrace(); return null; } } }
3.3 难点及解决方法
数据库内容不知道如何显示在前端界面上,一直搞不定用DAO模式进行前端和后端的交互,致使前端和后段代码杂糅重叠。没有用到DAO。之后询问了学长得知需要在DAO方法中返回至前端。
4. 数据库设计
4.1 简述数据库设计
根据系统需要,设计了一个mycal表,表中有两列数据history和id
history:代表运算式,id:表示表中序号
4.2 数据库表设计

4.3 难点及解决方法
时常出现Mysql启动失败的提示,查询了许多在mac中配置并启动Mysql的教程;在命令行中创建数据库表无法明显感受到数据是否读写,使用Sequel Ace连接Mysql后实现数据库的可视化。
5.运算功能设计
public double help(String s, int i) { double num = 0.0, prev = 0.0, sum = 0; int choose = 0;//数字位和小数点位选择 int chooseop=0;//符号选择 String target1="";//ln String target2="";//log,mod String target="";//√ int flag=0;//记录是否target char prevOp = '+';//基本四则运算 double indexcount=1.0; while (i < s.length()) { //target处理log mod ln //根号√占一个字符 target=s.substring(i,i+1); //ln两个字符 if(i+1<s.length()) target1=s.substring(i,i+2); //mod log三个字符 if(i+2<s.length()) target2=s.substring(i,i+3); if((target.equals("√")||target1.equals("ln")||target2.equals("log")||target2.equals("mod"))&&flag==0) { if(target.equals("√")) {chooseop=1;i+=1;System.out.println("i"+i);} else if(target2.equals("log")) {chooseop=2;i+=3;} else if(target2.equals("mod")) {chooseop=3;i+=2;} else if(target1.equals("ln")) {chooseop=4;i+=2;} flag=1; } //处理数字 if (Character.isDigit(s.charAt(i))||s.charAt(i) == '.') { if (s.charAt(i) == '.') { choose = 1;// 0表示没有小数点,1表示有小数点 i++; indexcount=1; } if (choose == 0) {//整数*10再相加 num = num * 10 + (s.charAt(i++)- '0'); } else { indexcount*=0.1; num = num + (double)(s.charAt(i++)- '0')* indexcount; } } else if (s.charAt(i) == '(') { num = help(s, ++i); i = end; } else{ switch(chooseop) { case 1: num=Math.sqrt(num); break; case 2: num=Math.log(num)/Math.log(10); break; // case 3: // prev %= num; // break; case 4: num=Math.log(num); break; case 0: break; } switch (prevOp) { case '+': sum += prev; prev = num; break; case '-': sum += prev; prev = -num; break; case '*': prev *= num; break; case '/': prev /= num; break; case 'd': prev=prev%num; break; } if (s.charAt(i) == ')') { i++; break; } prevOp = s.charAt(i);// 操作符 //重置 num = 0; choose = 0; chooseop=0; target1=""; target2=""; target=""; flag=0; i++; } } end = i; return (sum + prev); }
四、课程设计感想
课程设计是一个考验综合能力的大型考核任务,不是一朝一夕的学习理论知识就能够完善所有功能任务的,同时如此庞大的体系也需要一些合作共享、相互帮助、集思广益效果才会更好,此次设计由我个人完成,不能及时地发现问题、解决问题,甚是感受到了团队合作的重要性,也充分认识到了编写一些可视化前端面板能使系统程序更加人性化,用户使用起来更加简单明了方便快捷。在本次课程设计中,由于想实现查看历史记录功能但是并不完全熟悉数据库这部分内容,导致绕了很多弯路,遇到了很多错误,最后在csdn和哔哩哔哩视频教程的帮助下较为顺利地解决了,但也仍有很多问题。本是抱着面向对象设计的思想,想实现用DAO模式读写数据库,但由于不熟悉前后端交互,我想不到如何将数据库内容展现在GUI界面中达到可视的目的,导致前端和后端交叉重叠了部分,多亏了学长的指点帮助让我顺利解决问题。
五、尚待改进或者新的想法
1. 自己所完成功能的不足之处及以后想要采取的改进方法。
1) 运算功能有限,尚未完成三角函数类运算。以后可以增加一些三角函数的运算方法,并完善计算器的界面,使其更精致美观。
2) 尚未支持键盘快捷键,未完善复制粘贴功能。目前还没有对此的改进思路。
3) 没有实现多线程,不能提供网络计算服务。以后完善实现多线程技术,进一步完善计算功能。
2. 课设后想要进一步做的事情:
通过此次课程设计,我了解到自身的不足还有很多。此次设计过程我也学到了很多,对很多技术有了更进一步的认识,也有了更多兴趣。我想进一步学习GUI界面编程和数据库技术,能用一行行代码来实现可视化编程确实是很神奇;而数据的存储除了文件存储,数据库确实是一个更好的选择,能实现数据共享,完成数据集中控制、增加数据维护性、提高数据安全性。

浙公网安备 33010602011771号