因为是新手(很纯的那种),所以有点凌乱,代码很渣很冗余(后面会精简),命名规则请无视。当然这个计算器还只是能跑起来的程度,估计会有莫名其妙的错误,比如我的指数运算的指数只支持整数等。毕竟是第一次自己独立写一个小东西,还是很开心的。
1.主要部分(布局以及点击事件ActionEvent监听)
package 计算器; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class JiSuanQi { //三个基础布局组件 Frame f = new Frame("计算器"); TextField t = new TextField("0",40); Panel p = new Panel(new GridLayout(5,4,10,10)); //panel是网格布局 //加载业务逻辑 YeWuLuoJi ywlj = new YeWuLuoJi(); //button String String strNum = "0123456789"; String strToken = "+-*/"; String strEqual = "="; String strPoint = "."; String strClear = "c"; String[] buttonStr = {"c","+/-","x^2","x^y","1","2","3","+","4","5","6","-","7","8","9","*","0",".","=","/"}; //监听事件 ActionListener al = null; //创建并添加Button,并加入监听事件 public void init() { for(String i : buttonStr) { Button b = new Button(i); b.addActionListener(getAL()); p.add(b); } f.addWindowListener(new windowL()); f.add(t,BorderLayout.NORTH); f.add(p); //默认是BorderLayout.CENTER布局 f.pack(); //自适应合适大小 f.setVisible(true); //f设置为可见 } //获取监听事件,注意匿名内部类不要使用局部变量,因为一个在内存堆中,一个在栈中,生命周期不同 public ActionListener getAL() { if(al==null) { al = new ActionListener() { public void actionPerformed(ActionEvent e) { String buttonStr1 = e.getActionCommand(); //返回与事件向关联的组件的名称 String textStr = t.getText(); result = ywlj.yewuMethod(buttonStr1,textStr); //运行业务逻辑 t.setText(textStr); } }; //这只是一条语句,分号结尾 } return al; } //窗口关闭事件 class windowL extends WindowAdapter{ @Override public void windowClosing(WindowEvent e) { System.exit(0); } } public static void main(String[] args) { // TODO 自动生成的方法存根 new JiSuanQi().init(); } }
2.运算规则部分(运用了BigDecimal,不是很熟悉)
package 计算器; import java.math.BigDecimal; public class YunSuan { //--------------------------加法 public static String plus(String a,String b) { BigDecimal bigA = new BigDecimal(a); //最好用String来构造BigDecimal BigDecimal bigB = new BigDecimal(b); return bigA.add(bigB).toString(); } //---------------------------减法 public static String minus(String a,String b) { BigDecimal bigA = new BigDecimal(a+""); //最好用String来构造BigDecimal BigDecimal bigB = new BigDecimal(b+""); return bigA.subtract(bigB).toString(); } //--------------------------乘法 public static String multi(String a,String b) { BigDecimal bigA = new BigDecimal(a+""); //最好用String来构造BigDecimal BigDecimal bigB = new BigDecimal(b+""); return bigA.multiply(bigB).toString(); } //------------------------除法 public static String divide(String a,String b) { BigDecimal bigA = new BigDecimal(a+""); //最好用String来构造BigDecimal BigDecimal bigB = new BigDecimal(b+""); return bigA.divide(bigB).toString(); } //-------------------------平方运算 public static String square(String a ) { BigDecimal bigA = new BigDecimal(a); return bigA.multiply(bigA).toString(); } //------------------------x^y的幂指数运算 public static String zhishu(String a ,int b){ BigDecimal bigA = new BigDecimal(a); BigDecimal bigZ = bigA; for(int i=1;i<b;i++) { bigZ = bigA.multiply(bigZ); } return bigZ.toString(); } }
3.主要的业务逻辑(主要是各种按键的切换点击逻辑)
package 计算器; public class YeWuLuoJi { //Button标签 private String strNum = "0123456789"; private String strZF = "+/-"; private String[] strToken = {"+","-","*","/","x^y"}; private String strSquare = "x^2"; private String strEqual = "="; private String strPoint = "."; private String strClear = "c"; //clear键,复位 //状态记录码 String fInt = null; boolean f = false; //第一个数字,如果第一个数字也为0呢(联合刻画记录第一次点击的数字),如果获取的是double类型呢,怎么复制 String sInt = null; boolean s = false; //第二个数字,s刻画记录第二次点击的数字 String token = ""; boolean tokenClickIf = false; //是否点击运算符号 boolean equalClickIf = false; //是否点击等于号 boolean zfClickIf = false; //是否点击正负号 +/- //返回的应该是是设置textField的string-》textStr public String yewuMethod(String buttonStr,String textStr ) { //获取的button字符,如果没点击数字button,事件监听监听到的(还要分int和double) //如果第一个数字没有初始化,那么将第一个数字初始化(分int和double) if(f==false && isNum(buttonStr)) { //初始化第一位数字, 并且f->true fInt = buttonStr; f=true; //将textStr设置为该数字对应的String textStr = String.valueOf(fInt); } //已经点击下第一位数字,但没有点击运算符号而是继续点击第二个数字,比如点击12这样的数字 else if(f==true && isNum(buttonStr) && tokenClickIf==false) { textStr = textStr + buttonStr; fInt = textStr; } //设置了第一个数字后,点击运算符号 else if(f==true && isToken(buttonStr) && tokenClickIf == false) { tokenClickIf = true; token = buttonStr; //记录点击的运算符号 zfClickIf = false; // 复位正负号状态 } //点击的第二个数字 else if(f==true && s==false && tokenClickIf==true && isNum(buttonStr)) { textStr = buttonStr; sInt = textStr; s= true; } //第二个数字的连续点击输入 else if(f==true && s==true && tokenClickIf==true && isNum(buttonStr)) { textStr = textStr + buttonStr; sInt = textStr; } //已经点击过运算符号,且设置过第一和第二个数字,继续点击运算符号,关键是如果结果是double怎么赋予第一个数值 else if(f==true && s==true && tokenClickIf==true && isToken(buttonStr)) { //更新文本框中的计算结果 textStr = jisuan(buttonStr); //将计算所得的结果赋予第一个数字 fInt = textStr; } //如果点击的是点point else if (isPoint(buttonStr)) { if(hasPoint(textStr)==false) { textStr = textStr+buttonStr; if(f==true) { if(s==false) fInt = textStr; else sInt = textStr; } } } //如果点击的是正负号 else if(f==true && isZF(buttonStr)) { if(s==false && zfClickIf==false) { //第二个数字没有赋值,或者已经运算结束被初始化了 textStr = "-"+textStr; fInt = textStr; zfClickIf=true; } else if (s==true && zfClickIf==false) { textStr = "-"+textStr; sInt = textStr; zfClickIf=true; } //连续点击正负号 else if (s==false && zfClickIf == true) { textStr = textStr.split("-")[1]; fInt = textStr; zfClickIf = false; } else if (s==true && zfClickIf==true) { textStr = textStr.split("-")[1]; sInt = textStr; zfClickIf = false; } } //如果点击的是等于号“=” else if(f==true && s==true && tokenClickIf==true && isEqual(buttonStr)) { textStr = jisuan(token); fInt = textStr; //更新状态 s=false; zfClickIf = false; //pointClickIf = false; 浮点运算的话,还是不要清除point的状态,要不然结果还能继续加point tokenClickIf=false; token=""; sInt = null; } //点击的是平方符号 else if (f==true && isSquare(buttonStr)) { textStr = YunSuan.square(fInt); fInt = textStr; //复位正负号 zfClickIf=false; } //点击复位键,clear else if(isClear(buttonStr)) { //复位全部状态 fInt = null; f = false; //第一个数字,如果第一个数字也为0呢(联合刻画记录第一次点击的数字),如果获取的是double类型呢,怎么复制 sInt = null; s = false; //第二个数字,s刻画记录第二次点击的数字 token = ""; tokenClickIf = false; //是否点击运算符号 equalClickIf = false; //是否点击等于号 zfClickIf = false; textStr = "0"; } return textStr; } //判断点击的是否为数字,strNum.split("")返回的是一个按界定符切割后的String数组 public boolean isNum(String buttonStr) { for(String i:strNum.split("")) { if(buttonStr.equals(i)) return true; } return false; } //判断按键是否为运算符号token public boolean isToken(String buttonStr) { for(String i:strToken) { if (buttonStr.equals(i)) return true; } return false; } //是否正负号 public boolean isZF(String buttonStr) { if(buttonStr.equals(strZF)) return true; return false; } //是否是平方 public boolean isSquare(String buttonStr) { if(buttonStr.equals(strSquare)) return true; return false; } //判断按键是否为等于号 public boolean isEqual(String buttonStr) { if(buttonStr.equals(strEqual)) return true; return false; } //判断是否为点point public boolean isPoint(String buttonStr) { if(buttonStr.equals(strPoint)) return true; return false; } //判断是否为复位键 public boolean isClear(String buttonStr) { if(buttonStr.equals(strClear)) return true; return false; } //用于判断文本中是否有point public boolean hasPoint(String textStr) { for(String i : textStr.split("")) { if(i.equals(".")) return true; } return false; } //计算 public String jisuan(String buttonStr) { if(buttonStr.equals("+")) return YunSuan.plus(fInt,sInt); else if(buttonStr.equals("-")) return YunSuan.minus(fInt,sInt); else if(buttonStr.equals("*")) return YunSuan.multi(fInt,sInt); else if(buttonStr.equals("/")) return YunSuan.divide(fInt,sInt); else if(buttonStr.equals("x^y")) return YunSuan.zhishu(fInt,Integer.parseInt(sInt)); return ""; } }