wangflood

精心维护一个技术blog,为了工作,也是爱好。

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  14 Posts :: 19 Stories :: 8 Comments :: 0 Trackbacks
这是我在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(5105));
    JPanel pc 
= new JPanel(new GridLayout(1350));
    JPanel pb 
= new JPanel(new GridLayout(4555));
    JPanel pbc 
= new JPanel(new BorderLayout(55));
    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(105));
        pane.add(pdisplay, BorderLayout.NORTH);
        pane.add(pbcm, BorderLayout.CENTER);

        
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
this.setBounds(300200400260);
        
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();//逆序
    }
}

运行界面:

有些地方还没有完善。高手飘过,探讨改进啊。
posted on 2010-11-13 08:03 wangflood 阅读(922) 评论(0)  编辑  收藏 所属分类: java

只有注册用户登录后才能发表评论。


网站导航: