美文网首页
学习实验楼课程:Java实现简单计算器(二)

学习实验楼课程:Java实现简单计算器(二)

作者: Kant_14 | 来源:发表于2017-02-20 20:51 被阅读219次

    现在得仔细考虑界面背后的计算逻辑了,我对原代码中的计算逻辑既看不懂,也没什么兴趣,感觉各种复杂麻烦。那就自己来看这个逻辑要怎么设计。

    1. 计算的一般操作是怎么样的?
    • 首先我按下一个数字,假如是1,计算器要存储这个1;(这边需要一个tmp变量,可能要全局使用的;
    • 如果我又按了一次1,计算器要存储的数字是11,这个逻辑有两种实现方式:
      • 一种是用String形式,最后的时候转换成数字,好像原代码就是这么办的,那就是说tmp是String,初始值为"",然后每次只要用+连接就可以了,什么时候结束呢?应该是按符号的时候;
      • 一种是用数字形式,每次输入的时候都转换为数字,计算的逻辑也很简单,输入两次的意思就是原来的值要进一位,也就是tmp = tmp * 10 + newInput;(1. 这边需要一个临时变量,用来接收输入的文本,转换为数字之后就是tmp;
    • 接下来我按一个符号+-*/,意思是上一个数字的输入结束了,计算器要存储我输入的符号;(这边也需要一个tmp_sign变量,可能要全局使用
    • 再次输入数字,逻辑应该和之前一样,那么就需要存储输入的第二个变量。问题来了,如果再输入下去,不是要无数个存储变量?解决的办法可能有两个:
      • 一个是每次输入新数字的时候就创建新变量,按某种规则进行命名,然后放到一个列表之类的容器中去,最后计算的时候一步到位;(看来不仅数字需要列表存储,连输入的符号也需要;
      • 一个是每次新输入之前,就完成之前的计算,把tmp空出来,就没有存储的问题了;但好像不能多步计算,万一有负数什么的怎么办?不过如果不考虑这些问题(反正界面上没有括号,输入多步计算也不太方便),这个方式看上去简单一些;(1. 看来至少需要一个存储计算答案的变量,应该也是全局需要;2. 输入一个符号就意味着要完成之前的计算;
    • 以上就是大体的计算过程了,界面上还有三个按钮没考虑到:
      • 一个是Clear,应该很简单,就是参数和存储值复位;
      • 一个是=,能不能当作符号处理?看上去差不多的样子,基本就是完成之前输入的计算,显示答案;
      • 一个是.,输入小数点之后,就比较麻烦了,首先是输入数字的获取,如果按第一种方式应该不受影响,按第二种方式,其逻辑就不成立了。不过既然第一种方式别人已经写了,我就没什么兴趣了,一定要按第二种方式的话,应该怎么处理呢?1. 看来首先需要一个表示状态的变量,判断是不是在小数点之后的输入,如果不是,就按原逻辑,如果是,就要用新的逻辑;2. 新的逻辑应该也很容易想到,如果是小数点后第一位,就是tmp = tmp + newInput * 0.1,如果是第二位,就是乘以0.01,那就是说还要有一个变量来处理小数点后的输入,初始值是0.1,在小数点之后的每次输入,这个变量都除以10;
        大概思路就是这样了,如果有什么问题,应该可以后面再来解决;
    1. 接下来就考虑具体实现的问题了,每次发生输入,就调用一个函数,在Java中,这个按钮响应应该是ActionListener之类的东西,稍微查了一下,是个很简单的接口,有一个预定函数,定义它所需要采取的相应动作;Java里面定义函数很麻烦,(至少和python比起来是这样)首先要创建一个类或接口,然后再根据这个类来创建一个实体;看上去,我们有几种输入,也就要创建几个类,然后分别创建实体,以供调用;
      代码不复杂,大体如下,当然,首先是定义好变量:
    /*基本参数定义并初始化*/
        float ans = 0;                  //用于存储答案,初始为0;
        String ans_dis = "0";           //用于存储显示字段,初始为“0”;
        float tmp = 0;                  //用于存储输入,初始为0;
        String act = "+";               //用于存储符号,默认为“+”;
        int arg_point = 0;              //判断是否在小数点之后,默认为0,即不在小数点后;
        static int arg_mtinput1 = 10;   //如果不在小数点后,多次输入处理时使用的常数,处理方式为 tmp = tmp * 10 + new_input,这个参数其实不需要,写出来方便解释,如果必要,可以用来调整进制;
        float arg_mtinput2 = 1;         //如果在小数点后,多次输入处理时使用的变量,arg = arg / 10,tem = tem + new_input * arg;
    /*处理计算逻辑*/
            
            //如果输入的是数字
            class LisnNum implements ActionListener {
                @Override
                public void actionPerformed(ActionEvent e) {
                    
                    //取得输入值文本;
                    String inputTmp = ((JButton) e.getSource()).getText();
                    
                    //如果之前没有小数点;
                    if(arg_point == 0) {
                        //将输入的文本转换为数字;
                        tmp = tmp * arg_mtinput1 + Integer.parseInt(inputTmp);
                        
                        //调整显示器的显示内容;
                        //因为一开始有设定一个0,就没法直接在后面接上输入的数字,多了一个判断;
                        if(ans_dis.equals("0"))
                            ans_dis = inputTmp;
                        else
                            ans_dis = ans_dis + inputTmp;
                        ansField.setText(ans_dis);
                    }
                    
                    //如果还在小数点后的输入状态;
                    else {
                        arg_mtinput2 = arg_mtinput2 / arg_mtinput1;
                        tmp = Integer.parseInt(inputTmp) * arg_mtinput2 + tmp;
                        ans_dis = Float.toString(tmp);
                        ansField.setText(ans_dis);
                    }
                }
            }
            
            //如果输入的是小数点
            class LisnPoint implements ActionListener {
                @Override
                public void actionPerformed(ActionEvent e) {
                    arg_point = 1;
                    ans_dis = ans_dis + ".";
                    ansField.setText(ans_dis);
                }
            }
            
            //如果输入的是符号
            class LisnSign implements ActionListener {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //计算上一步的答案;
                    if(act.equals("+"))
                        ans = ans + tmp;
                    if(act.equals("-"))
                        ans = ans - tmp;
                    if(act.equals("*"))
                        ans = ans * tmp;
                    if(act.equals("/"))
                        ans = ans / tmp;
                    
                    //输入暂存复位为0;
                    tmp = 0;
                    //小数点复位为0,即之后的输入没有小数点;
                    arg_point = 0;
                    arg_mtinput2 = 1;
                    //下一步计算的符号为当前输入的符号;
                    act = ((JButton) e.getSource()).getText();  
                    
                    ans_dis = Float.toString(ans) + act;
                    ansField.setText(ans_dis);
                    
                }
            }
            
            //如果输入的是等于号
            class LisnEql implements ActionListener {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(act.equals("+"))
                        ans = ans + tmp;
                    if(act.equals("-"))
                        ans = ans - tmp;
                    if(act.equals("*"))
                        ans = ans * tmp;
                    if(act.equals("/"))
                        ans = ans / tmp;
                    
                    ans_dis = Float.toString(ans);
                    ansField.setText(ans_dis);
                    
                    tmp = 0;
                    act = "+";
                    arg_point = 0;
                    arg_mtinput2 = 1;
                }
            }
            
            //如果输入的是clear
            class LisnClear implements ActionListener {
                @Override
                public void actionPerformed(ActionEvent e) {
                    //各参数复位;
                    ans = 0;
                    ans_dis = "0";
                    tmp = 0;
                    act = "+";
                    arg_point = 0;
                    arg_mtinput1 = 10;
                    arg_mtinput2 = 1;
                    ansField.setText(ans_dis);
                }
            }
    

    这是修改后的代码了,一开始的当然还有各种问题,可以看到,思路和原来的设想还是有些区别的,比如等于号要单独处理之类的;

    1. 最后一步比较简单,就是创建实体,并把每个按钮和处理逻辑联系起来:
     /*构建运算所需的实体,绑定按钮与运算逻辑*/
            LisnNum lisnNum = new LisnNum();
            LisnPoint lisnPoint = new LisnPoint();
            LisnSign lisnSign = new LisnSign();
            LisnEql lisnEql = new LisnEql();
            LisnClear lisnClear = new LisnClear();
            
            button_0.addActionListener(lisnNum);
            button_1.addActionListener(lisnNum);
            button_2.addActionListener(lisnNum);
            button_3.addActionListener(lisnNum);
            button_4.addActionListener(lisnNum);
            button_5.addActionListener(lisnNum);
            button_6.addActionListener(lisnNum);
            button_7.addActionListener(lisnNum);
            button_8.addActionListener(lisnNum);
            button_9.addActionListener(lisnNum);
            button_point.addActionListener(lisnPoint);
            button_div.addActionListener(lisnSign);
            button_mtp.addActionListener(lisnSign);
            button_add.addActionListener(lisnSign);
            button_sub.addActionListener(lisnSign);
            button_eql.addActionListener(lisnEql);
            button_clear.addActionListener(lisnClear);
    

    相关文章

      网友评论

          本文标题:学习实验楼课程:Java实现简单计算器(二)

          本文链接:https://www.haomeiwen.com/subject/jxiewttx.html