java GUI 简单计算器实现

一、计算器的界面:

1) 将这个JFrame窗口分为BorderLayout.NORTH BorderLayout.CENTER BorderLayout.SOUTH

2) 分别在三个部分(north center south)添加三个JPanel面板panel1 panel2 panel3

3) 将TextArea testArea添加到panel1中

4)将panel2设置布局为new GridLayout(4,4),再分别将14个JButton添加到panel2中

5)将panel3设置布局为new GridLayout(1,1)(目的为使添加的按钮填充panel3),再将JButton(也就是 “ = ” 按钮)添加到里面

得到以下布局:



二、程序代码

在我看来,实现这个程序的难点在于:

1.在ActionPerformed()方法中对获取的按钮事件的操作,也就是分类操作,其实这也就是这个程序的核心所在了,主要是这个算法,GUI做得再好看,这个算法不健壮的话程序还是很降档的。

解决:这个见仁见智,我的算法虽然基本可以实现,但对于一些挑剔的测试数据,比如 + + 9 - - . .等一些不正确的输入还是没能有相应的处理(就是今天比较懒,没处理这种异常,急着想发博文,过几天会有优化,会再发博文)

本程序ActionPerformed()算法基本分为:

a.对数字的处理

b.对计算符号的处理

c.对小数点的处理

d.对 = 符号的处理

e.对 c 符号的处理(清空符)

f.对 . 符号的处理

2.对小数点的操作,因为不能单单吧小数点的操作归处计算符号(+  - * /),所以需要用大段代码对小数点处理。

3.对double类型的精度计算,因为在计算double类型数的时候难免会出现精度混乱等问题,比如你计算的是3.1+3.00001,会出现 6.100010000000000001 的情况。

解决:使用BigDecimal类解决这个问题,可以很好的解决double类型数据的精度计算缺陷,具体实现:


    public static double mul(double a,double b){
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.multiply(b2).doubleValue();
    }
    public static double add(double a,double b){
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.add(b2).doubleValue();
    }
    public static double sub(double a,double b){
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.subtract(b2).doubleValue();
    }
    public static double div(double a,double b) throws  Exception{<span>	</span>//抛出了出现除数为0的异常
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.divide(b2,10,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
等到需要两个数计算时候就调用这四个方法就好了,不会出现精度混乱都问题。


实现ActionListener接口的ActionPerformed方法的算法很粗糙,但是确实正确,要是想要看懂的话估计有困难,我解释起来的也挺费劲的,所以就直接附上源代码,有兴趣的朋友可以拿去跑跑!

源代码:

package package2;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;

/**
 * Created by sakura on 16/5/23.
 */

public class Calculator extends JFrame implements ActionListener{
    JButton bNumber[];
    JButton bSign[];
    String[] signSting;
    static JTextArea testArea;
    JPanel panel1,panel2,panel3;
    static public int numberCount;
    static public Double a;
    static public Double b;
    public double numberString[];
    static String sign;
    static int pointExist;
    static int judgeException;  //判断有 "除数为0" 异常时候testArea不输出内容
    String timeSign;

    Calculator(){
        judgeException = 0;
        timeSign = new String() ;
        timeSign = null;
        pointExist = 0;
        sign = new String();
        a = null;
        b = null;
        numberCount = 0;
        numberString = new double[100];
        bNumber = new JButton[20];
        bSign = new JButton[20];
        signSting = new String[]{"+","-","*","/",".","=","c"};

        this.setVisible(true);
        this.setBounds(300,100,600,600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /*  初始化组件 */

        for(int i = 0;i < 10;i++){
            bNumber[i] = new JButton(String.valueOf(i));
            bNumber[i].addActionListener(this);
        }
        for(int i = 0;i < 7;i++){
            bSign[i] = new JButton(signSting[i]);
            bSign[i].addActionListener(this);
        }
        panel1 = new JPanel();
        panel2 = new JPanel();
        panel3 = new JPanel();
        testArea = new JTextArea();

        /*  将 textArea 添加到 BorderLayout.north*/

        panel1.add(testArea);

        /*  将panel2 设置为 gridlayout , 再添加到 BorderLayout.center*/

        panel2.setLayout(new GridLayout(4,4));
        panel2.add(bNumber[0]);
        panel2.add(bSign[4]);
        panel2.add(bSign[6]);
        panel2.add(bSign[0]);
        panel2.add(bNumber[1]);
        panel2.add(bNumber[2]);
        panel2.add(bNumber[3]);
        panel2.add(bSign[1]);
        panel2.add(bNumber[4]);
        panel2.add(bNumber[5]);
        panel2.add(bNumber[6]);
        panel2.add(bSign[2]);
        panel2.add(bNumber[7]);
        panel2.add(bNumber[8]);
        panel2.add(bNumber[9]);
        panel2.add(bSign[3]);

        /*  将 按钮 "=" 填充到 BorderLayout.south*/

        panel3.setLayout(new GridLayout(1,1));
        panel3.add(bSign[5]);

        /* 将三个JPanel 添加到 JFrame*/

        this.add(panel1,BorderLayout.NORTH);
        this.add(panel2,BorderLayout.CENTER);
        this.add(panel3,BorderLayout.SOUTH);
    }
    public static void main(String[] args) {
        new Calculator();
    }

    public void actionPerformed(ActionEvent e){
        timeSign = e.getActionCommand();
        if (timeSign.equals("0") || timeSign.equals("1") || timeSign.equals("2") || timeSign.equals("3") || timeSign.equals("4") || timeSign.equals("5") || timeSign.equals("6") || timeSign.equals("7") || timeSign.equals("8") || timeSign.equals("9")) {
            numberString[numberCount++] = Integer.valueOf(timeSign);
            testArea.append(e.getActionCommand());
        }else if (timeSign.equals("+") || timeSign.equals("-") || timeSign.equals("*") || timeSign.equals("/")) {
            if(pointExist == 1 && b == null){
                a = add(a,CalculatePoint(numberString,numberCount));
                numberCount = 0;
            }else if(pointExist == 1){
                b = add (b,CalculatePoint(numberString,numberCount));
                numberCount = 0;
            }
            if (a == null) {
                sign = timeSign;
                a = CalculateTotal(numberString, numberCount);
                numberCount = 0;
            } else {
                if(pointExist == 0)
                    b = CalculateTotal(numberString, numberCount);
                if(b != null)
                    a = CalculateTotalThree(a, b, sign);
                sign = timeSign;
                pointExist = 0;
            }
            numberCount = 0;
            testArea.append(e.getActionCommand());
        } else if (e.getActionCommand().equals("=")) {
            if(pointExist == 1 && b == null){
                a = add(a,CalculatePoint(numberString,numberCount));
                numberCount = 0;
            }else if(pointExist == 1){
                b = add(b,CalculatePoint(numberString,numberCount));
                numberCount = 0;
            }
            if (a == null) {                                                //直接输入 = 的情况
                testArea.append("=" + String.valueOf(a));
            } else {
                if(pointExist == 0)
                    b = CalculateTotal(numberString, numberCount);
                if(b != null)
                    a = CalculateTotalThree(a, b, sign);
                if(judgeException == 0)
                    testArea.append("=" + String.valueOf(a));
                pointExist = 0;
                judgeException = 0;
            }
        }else if(timeSign.equals(".")){
            if(a == null ){
                a = CalculateTotal(numberString,numberCount);
                numberCount = 0;
                pointExist = 1;
                testArea.append(".");
            }else {
                b = CalculateTotal(numberString, numberCount);
                numberCount = 0;
                pointExist = 1;
                testArea.append(".");
            }
        }else if(timeSign.equals("c")){
            numberCount = 0;
            pointExist = 0;
            a = null;
            b = null;
            testArea.setText("");
            judgeException = 0;
        }
    }

    /*  自定义计算方法*/

    public static double CalculateTotal(double number[],int i){         //计算从计算器读取到的数字的综总和
        int total = 0;
        int timeI = i;
        i--;
        for(int j = 0;j < timeI;j++){
            total += number[j]*Math.pow(10,i--);
        }
        return total;
    }
    public static Double CalculateTotalThree(Double a ,Double b,String string){         //计算两个数在某一个符号下的值
        if(string.equals("+"))
            return add(a,b);
        else if(string.equals("-"))
            return sub(a,b);
        else if(string.equals("*"))
            return mul(a,b);
        else if(string.equals("/"))
            try{
                return div(a, b);
            }catch (Exception e){
                testArea.setText(" 除数不能为0 ");
                Calculator.a = null;
                Calculator.b = null;
                pointExist = 0;
                numberCount = 0;
                judgeException = 1;
            }
        return 0.0;
    }
    public static double CalculatePoint(double number[],int j){             //遇到小数点时候的情况
        double total = 0;
        int count = j;
        for(int i = 0;i < j;i++){
            total = add(total ,mul(number[i],Math.pow(Math.pow(10,i+1),-1)));
        }
        return total;
    }

    /*  BigDecimal类方法,使计算更精确,优化double,解决出现结果不精确情况 */

    public static double mul(double a,double b){
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.multiply(b2).doubleValue();
    }
    public static double add(double a,double b){
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.add(b2).doubleValue();
    }
    public static double sub(double a,double b){
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.subtract(b2).doubleValue();
    }
    public static double div(double a,double b) throws  Exception{
        BigDecimal b1 = new BigDecimal(Double.toString(a));
        BigDecimal b2 = new BigDecimal(Double.toString(b));
        return b1.divide(b2,10,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

感谢朋友的赏脸观看,有什么技术上的错我或者需要改进的地方请多多指教

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值