科学计算器的面向对象设计

一、项目介绍

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.采用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表中有两列数据historyid

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界面编程和数据库技术能用一行行代码来实现可视化编程确实是很神奇而数据的存储除了文件存储数据库确实是一个更好的选择实现数据共享完成数据集中控制、增加数据维护性、提高数据安全性

posted @ 2023-01-09 19:39  阿怂不怂  阅读(194)  评论(0)    收藏  举报