这是我在java课程设计上的一个作品。老师要求很简单,我尽量做得完善,在要求之外,做了不少。
在小数点,一些windows计算器怪异的地方(3+=+9++4=),参考网上的算法完成。
算法简介:
[=]的功能: 
1.如果前次为一次有效的右数输入则将当前数赋给右数变量。
2.检查符变量是否存在运算符,若存在则计算表达式左数 运算符 右数,并将结果赋给左数变量,同时显示。若不存在,则不作操作。
3.清空串变量。
[四则运算符]的功能:
1.若前次为一次运算数输入,则执行[=]。
2.将当前数赋给左右数变量,将运算符赋给符变量。
3.清空串变量。
算法具体链接:http://blog.csdn.net/haochen_net/archive/2008/10/25/3143290.aspx
Cal类的实现:
import java.awt.BorderLayout;
import java.awt.CheckboxMenuItem;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
public class Cal extends JFrame implements ActionListener {
    // 菜单
    MenuBar myMenuBar = new MenuBar();
    // JPanel
    JPanel pdisplay = new JPanel();
    JPanel pm = new JPanel(new GridLayout(5, 1, 0, 5));
    JPanel pc = new JPanel(new GridLayout(1, 3, 5, 0));
    JPanel pb = new JPanel(new GridLayout(4, 5, 5, 5));
    JPanel pbc = new JPanel(new BorderLayout(5, 5));
    JPanel pbcm = new JPanel();
    static// 显示
    JTextField tftext = new JTextField(25);
    JTextField tfm = new JTextField(5);
    // 按钮字符定义及按钮
    String strB[] = { "MC", "MR", "MS", "M+", "Backspace", "CE", "C", "7", "8",
            "9", "/", "sqrt", "4", "5", "6", "*", "%", "1", "2", "3", "-",
            "1/x", "0", "+/-", ".", "+", "=" };
    JButton[] jb = new JButton[27];
    public Cal() {
        super("计算机-荞叶制作");
        addMenu();
        initDisplay();
        initPbcm();
        Container pane = this.getContentPane();
        pane.setLayout(new BorderLayout(10, 5));
        pane.add(pdisplay, BorderLayout.NORTH);
        pane.add(pbcm, BorderLayout.CENTER);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(300, 200, 400, 260);
        this.setResizable(false);
        this.setVisible(true);
    }
    // 一些类变量
    static StringBuilder text = new StringBuilder("0");// 显示符
    StringBuilder number = new StringBuilder("0");// 当前数.
    double rightOper;// 右数
    double leftOper;// 左数
    double result;// 结果
    int operator;// 操作符,默认为0,没有操作符
    int isFloat = 0;// 0不是浮点型,1输入了一个.2真正的浮点
    boolean isZero = true;// 0显示清空状态,不能输入0.输入1-9进入1状态.可以输入0-9进入2;
    boolean isNeg;// 默认为正数
    boolean isExcp;// 默认没有异常.
    StringBuilder m = new StringBuilder("0");// 存储数串变量
    int isRightInput = 0;// 一次有效右输入,输入运算符后=1;再输入数字后=2;
    // //////////////////////////////////////////////////////////////////////////////////////
    /**
     * number是用于给leftOper和rightOper赋值的.纯纯的能够转化为Double类型的StringBuilder.
     * 当然text,number,m考虑到大量的String连接和转换,StringBuilder效率更高.
     * */
    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        if (cmd == "0" || cmd == "1" || cmd == "2" || cmd == "3" || cmd == "4"
                || cmd == "5" || cmd == "6" || cmd == "7" || cmd == "8"
                || cmd == "9") {
            if (isExcp)// 如果是三种错误之一,就不响应了.只有CE和C能够响应
                return;
            if (isRightInput == 1)// 如果是待一次有效右输入.也就是前一次输入的是运算符.
                isRightInput = 2;// 进阶真正的右输入
            if (isZero) {// 处于清空状态
                number = new StringBuilder(cmd);// number直接为一个数字串
                isZero = false;// 有一位数字后,不在处于清空.后面就可以输入运算符,单目,.,+/-
            } else {
                if (isFloat == 1) {// 待浮点状态,前一次输入的是.
                    number.append('.');// number这时加入.
                    isFloat = 2;// 真正的浮点.
                }
                number.append(cmd);// 数字后连接数字.
                if (number.charAt(0) == '0' && isFloat != 2)// 如果不是浮点,
                    number.deleteCharAt(0);// 但以0开头就删去.这种方法不优雅,但想不出更好的.
            }
            text = number;// 只要输入数字,无条件地显示.
        } else if (cmd == ".") {
            if (isExcp)
                return;
            if (isFloat == 0)// 如果不是浮点型
                isFloat = 1;// 待浮点型.
        } else if (cmd == "+/-") {
            if (isZero || isExcp)// 清空状态或异常.
                return;
            if (isNeg) {// 如果是负数就变为正数,如果是正数就变为负数.
                isNeg = false;
                number.deleteCharAt(0);// delete和insert操作可以推迟到完成数字输入状态后,根据isNeg来判断更好.
            } else {
                isNeg = true;
                number.insert(0, '-');
            }
            text = number;
        }
        // 双目运算功能
        else if (cmd == "+" || cmd == "-" || cmd == "*" || cmd == "/") {
            if (isExcp)
                return;
            if (isRightInput == 0)
                isRightInput = 1;// 变为待一次有效右输入状态.
            if (isRightInput == 2) {// 如果已经是一次有效右输入了.就相当于'='.比如1+2+的时候.
                rightOper = Double.parseDouble(number.toString());// 当前的number给右数.
                try {
                    result = Util.calculate(leftOper, rightOper, operator);// 根据三个变量计算。如果/时右数为0,就抛异常.
                } catch (ArithmeticException ae) {
                    isExcp = true;
                    if (leftOper == 0)// 左数,右数同时为0时.
                        text = new StringBuilder("函数结果未定义。");
                    else
                        text = new StringBuilder("除数不能为零。");
                }
                rightOper = leftOper = result;// 把得到的结果给左数,同时也给右数.
                text = new StringBuilder(String.valueOf(result));
                isZero = true;
                isRightInput = 1;// 直接就是1状态.不经过0
            }
            if (operator == 0)// 如果运算符没有.如:1+
                rightOper = leftOper = Double.parseDouble(number.toString());// 左数和右数均赋值.
            // 据cmd初始化operator.此步一定进行,不管是运算符功能还是=功能.
            if (cmd == "+")// 很无奈的是不能用switch.enum太繁.
                operator = 1;
            else if (cmd == "-")
                operator = 2;
            else if (cmd == "*")
                operator = 3;
            else
                operator = 4;
            isZero = true;
        }
        // 单目运算
        else if (cmd == "sqrt") {
            if (isExcp)
                return;
            double dnum = Double.parseDouble(number.toString());
            if (dnum < 0) {// 如果当前数为负,就错误.
                isExcp = true;
                text = new StringBuilder("函数输入无效。");
            } else {
                result = Math.sqrt(dnum);
                number = text = new StringBuilder(String.valueOf(result));
                if (operator == 0)// 有运算符必赋值给右数.
                    leftOper = result;
                else {
                    rightOper = result;
                }
                isZero = true;
            }
        } else if (cmd == "%") {
            if (isExcp)
                return;
            double dnum = Double.parseDouble(number.toString());
            result = leftOper * dnum / 100;// 这种规则让人很难适应,有点小变态.
            number = text = new StringBuilder(String.valueOf(result));
            if (operator == 0)
                leftOper = result;
            else {
                rightOper = result;
            }
            isZero = true;
        } else if (cmd == "1/x") {
            if (isExcp)
                return;
            double dnum = Double.parseDouble(number.toString());
            if (dnum == 0) {
                isExcp = true;
                text = new StringBuilder("除数不能为零。");
            } else {
                result = 1 / Double.parseDouble(number.toString());
                number = text = new StringBuilder(String.valueOf(result));
                if (operator == 0)
                    leftOper = result;
                else {
                    rightOper = result;
                }
                isZero = true;
            }
        } else if (e.getActionCommand() == "=") {
            if (isExcp)
                return;
            double dnum = Double.parseDouble(number.toString());
            if (isRightInput == 2) {// 一次有效的右输入.如1+2=-2.如1+2=3=.就不响应3.
                rightOper = dnum;// 当前数赋给右数.
                isRightInput = 0;// =号破坏一次右输入,必须得以+-*/开头,后接数字
            }
            if (operator != 0) {// 1+2=
                try {
                    result = Util.calculate(leftOper, rightOper, operator);
                } catch (ArithmeticException ae) {
                    isExcp = true;
                    if (leftOper == 0)// 左数,右数同时为0时.
                        text = new StringBuilder("函数结果未定义。");
                    else
                        text = new StringBuilder("除数不能为零。");
                }
                leftOper = result;
            } else
                // 1=
                result = dnum;
            text = new StringBuilder(String.valueOf(result));
            isZero = true;
        } else if (e.getActionCommand() == "关于计算器") {
            String temp = "java模拟windows高模仿实用计算器.\n荞叶制作.qq:494053175 \n blog:sina wangflood";
            JOptionPane.showMessageDialog(null, temp, "关于计算器",
                    JOptionPane.INFORMATION_MESSAGE);
        }
        // BackSpace功能
        else if (cmd == "Backspace") {
            if (isExcp)
                return;
            if ((!isNeg && number.length() < 2)// 正数剩一位时,负数剩二位时.直接跳到0
                    || (isNeg && number.length() < 3)) {
                isZero = true;
                number = new StringBuilder("0");
            } else
                number = number.deleteCharAt(number.length() - 1);// 每次删除最后一位.
            text = number;
        } else if (cmd == "CE") {
            isZero = true;
            isExcp = false;// 清异常.
            text = number;
        } else if (cmd == "C") {
            operator = 0;// 清运算符.
            isZero = true;
            leftOper = 0;// 清左数
            rightOper = 0;// 清右数.
            result = 0;// 清结果.
            number = text = new StringBuilder("0");// 清当前数
            isExcp = false;// 清异常
            isRightInput = 0;// 清一次有效右输入.
        } else if (cmd == "MC") {
            if (isExcp)// 同样也响应不了.异常的时候.
                return;
            m = new StringBuilder("0");
        } else if (cmd == "MR") {// 显示存储数到display.
            if (isExcp)
                return;
            isRightInput = 2;
            number = text = m;
        } else if (cmd == "MS") {
            if (isExcp)
                return;
            m = number;// 将当前数赋给m.
        } else if (cmd == "M+") {// 当前数与m相加赋给m
            if (isExcp)
                return;
            m = new StringBuilder(String.valueOf((Double.parseDouble(m
                    .toString()) + Double.parseDouble(number.toString()))));
        } else {// 一般不给出现这种情况.我们都会上天堂的.
            System.out.println("欢迎来到地狱!");
        }
        // 按任何键都会触发的.
        tftext.setText(text.toString());
        if (m.length() != 0)// m不空的话就显示M
            tfm.setText("M");
        else
            tfm.setText("");
        if (isZero) {// 为清空状态.浮点状态和负数状态回到默认.
            isFloat = 0;
            isNeg = false;
        }
    }
    private void initDisplay() {
        tftext.setHorizontalAlignment(JTextField.RIGHT);
        pdisplay.add(tftext);
        tftext.setText("0.");
        tfm.setHorizontalAlignment(JTextField.CENTER);
        tfm.setEditable(false);
        pm.add(tfm);
    }
    private void initPbcm() {
        // 生成按钮
        for (int i = 0; i < 27; i++) {
            jb[i] = new JButton(strB[i]);
        }
        for (int i = 0; i < 4; i++) {
            jb[i].addActionListener(this);
            pm.add(jb[i]);
        }
        for (int i = 4; i < 7; i++) {
            jb[i].addActionListener(this);
            pc.add(jb[i]);
        }
        for (int i = 7; i < 27; i++) {
            jb[i].addActionListener(this);
            pb.add(jb[i]);
        }
        pbc.add(pc, BorderLayout.NORTH);
        pbc.add(pb, BorderLayout.CENTER);
        pbcm.add(pm);
        pbcm.add(pbc);
    }
    private void addMenu() {
        this.setMenuBar(myMenuBar);
        // 以下是编辑菜单项
        Menu editMenu = new Menu("编辑");
        myMenuBar.add(editMenu);
        MenuItem menuitemcopy = new MenuItem("复制");
        MenuItem menuitemplaste = new MenuItem("粘贴");
        MenuItem menuitemload = new MenuItem("用户登录");
        editMenu.add(menuitemload);
        editMenu.add(menuitemcopy);
        editMenu.add(menuitemplaste);
        menuitemload.addActionListener(this);
        menuitemcopy.addActionListener(this);
        menuitemplaste.addActionListener(this);
        // 以下是编辑菜单项
        Menu watchMenu = new Menu("查看");
        myMenuBar.add(watchMenu);
        MenuItem menuitemstandard = new MenuItem("标准型");
        MenuItem menuitemsencien = new MenuItem("科学型");
        watchMenu.add(menuitemstandard);
        watchMenu.add(menuitemsencien);
        watchMenu.addSeparator();
        watchMenu.add(new MenuItem("数字分组"));
        menuitemstandard.addActionListener(this);
        menuitemsencien.addActionListener(this);
        // 以下是帮助菜单项
        Menu helpMenu = new Menu("帮助");
        myMenuBar.add(helpMenu);
        CheckboxMenuItem menuitemhelp = new CheckboxMenuItem("帮助主题", false);
        MenuItem menuitemaboutcal = new MenuItem("关于计算器");
        helpMenu.add(menuitemhelp);
        helpMenu.addSeparator();
        helpMenu.add(menuitemaboutcal);
        menuitemhelp.addActionListener(this);
        menuitemaboutcal.addActionListener(this);
    }
    public static void main(String[] args) {
        new Cal();
    }
}
Util.java辅助类
package wang.window.impl;
public class Util {
    /** DoubleString格式化显示.如果有小数点,只对小数点前面进行格式化. */
    private String DoubleFormat(String str) {
        StringBuilder sb = new StringBuilder();
        int length = str.length();
        int left = length % 3;
        int count = 0;
        if (left == 0)
            left = 3;
        String tail = "";
        if (str.contains(".")) {
            int index = str.indexOf('.');
            tail = str.substring(index);
            str = str.substring(0, index);
        }
        for (int i = 0; i < str.length(); i++) {
            if (i == left)
                sb.append(",");
            else if (i > left) {
                count++;
                if (count % 3 == 0)
                    sb.append(",");
            }
            sb.append(str.charAt(i));
        }
        sb.append(tail);
        return sb.toString();
    }
    private void display() {
    }
    /** 根据两double类型的操作数,和操作符,计算后返回double类型结果 */
    public static double calculate(double leftOper, double rightOper,
            int operator) {
        double result = 0;
        switch (operator) {
        case 1:
            result = leftOper + rightOper;
            break;
        case 2:
            result = leftOper - rightOper;
            break;
        case 3:
            result = leftOper * rightOper;
            break;
        case 4:
            if (leftOper == 0)
                throw new ArithmeticException();
            result = leftOper / rightOper;
            break;
        default:
            System.out.println("欢迎来到地狱!");
            break;
        }
        return result;
    }
    public String format(int isfloat, boolean isNeg, StringBuilder text) {
        int start = 0;//.前一个位置
        int end;//-后一个位置
        int count = 0;//计数
        if (isfloat != 2)
            start = text.length() - 1;//java里数组的长度不用扫描?
        if (isNeg)
            end = 1;
        else
            end = 0;
        StringBuilder sb = new StringBuilder();
        for (int i = text.length() - 1; i >= 0; i++) {
            char temp = text.charAt(i);
            if (isfloat == 2) {
                if (temp == '.')
                    start = i - 1;
            }
            if (i == start && i <= end) {
                if (count == 2)
                    sb.append(",");//插入,的条件
                count = (count + 1) % 3;
            }
            sb.append(temp);
        }
        return sb.reverse().toString();//逆序
    }
}
运行界面:
有些地方还没有完善。高手飘过,探讨改进啊。