zoukankan      html  css  js  c++  java
  • java新手自己实现的计算器,有点乱

    因为是新手(很纯的那种),所以有点凌乱,代码很渣很冗余(后面会精简),命名规则请无视。当然这个计算器还只是能跑起来的程度,估计会有莫名其妙的错误,比如我的指数运算的指数只支持整数等。毕竟是第一次自己独立写一个小东西,还是很开心的。

    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 "";
    	}
    }
    

      

  • 相关阅读:
    国家行政区划地区编码表
    Java循环中标签的作用(转)
    通过ribbon 根据服务名获取所有服务实例的IP和端口列表
    rabbitmq重装依赖的erlang 要注意
    Rabbitmq关于集群节点功能的读书笔记
    CentOS7统计某个进程当前的线程数
    理解同步、异步、阻塞、非阻塞(传送门)
    代理模式和装饰模式区别
    【转载】Asp.Net生成图片验证码工具类
    【转载】使用宝塔Linux面板屏蔽某些IP访问你的服务器
  • 原文地址:https://www.cnblogs.com/chen-jack/p/8296159.html
Copyright © 2011-2022 走看看