• Java实现windows7标准型计算器


    程序能实现基本的算术运算,并能够对运算结果的精度进行有效控制,并且实现了存储器相关功能

    功能如下:

    MC:清除存储数据
    MR:读取存储数据显示在屏幕上
    MS:将显示的数据覆盖存储到存储器中
    M+:用存储的数据加上屏幕上显示的数并更新存储器里的值
    M-: 用存储的数据减去屏幕上显示的数并更新存储器里的值
    ←: 删除输入数的尾数
    C:   清除计算器数据,下一次输入数据开始新的运算
    CE:  清除当前输入的数
    ±:  正负数转换
    √:  开平方
    +,-,*,/ 加减乘除,将结果
    %:取模
    1/x:取倒数

    程序流程图:



    代码实现:

    class operateNum {//操作数类
    	public double value;//操作数的实际值
    	public int dotWei;//操作数如果是小数,记录小数点后的位数
    	public String invertedString;//1/x字符串
    	public String sqrtedString;//sqrt(x)字符串
    	public boolean isSqrted,isInverted;//做标记是否√,1/x过,用于后续判断
    	public boolean clear;//clear为真表示是否重置操作数
    	public boolean isFloat;//isFloat为真,表示操作数是小数
    	public operateNum()
    	{
    		value=0;
    		dotWei=0;
    		sqrtedString=null;
    		invertedString=null;
    		isSqrted=false;
    		isInverted=false;
    		clear=false;
    		isFloat=false;
    	}
    	public void reset()//重置操作数
    	{
    		value=0;
    		dotWei=0;
    		sqrtedString=null;
    		invertedString=null;
    		isSqrted=false;
    		isInverted=false;
    		clear=false;
    		isFloat=false;
    	}
    }
    


    class storageField {//存储区
    	public double storageNum;//存储区存储的数据
    	public boolean storageMode;//是否启动存储区
    	public storageField()
    	{
    		storageNum=0;
    		storageMode=false;
    	}
    }
    


    import java.awt.*;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.math.BigDecimal;
    
    import javax.swing.*;
    import javax.swing.border.Border;
    import javax.swing.border.LineBorder;
    public class calc extends JFrame{
    	private JTextField display1,display2,display3;
    	private JButton num[],operate[];
    	private String name[]={"MC","MR","MS","M+","M-","←","CE","C","±","√","7","8","9","/","%","4","5","6","*","1/x","1","2","3","-","=","0",".","+"};
    	private operateNum op1=new operateNum(),op2=new operateNum();//操作数1,操作数2
    	private storageField storage=new storageField();//存储区
    	private String action="op1";//表示要操作的对象  "op1"操作第一个操作数,"op2"操作第二个操作数
    	private String sign="";//运算符,默认为空
    	private String screen1,screen2;
    	private boolean Disable=false;
    	public calc()
    	{
    		super("计算器");
    		this.setLayout(null);
    		this.setSize(228, 324);
    		this.setResizable(false);
    		JPanel jp=new JPanel(null);
    		jp.setBounds(10,15,getWidth()-24,getHeight());
    		jp.setBackground(new Color(217,228,241));
    		this.getContentPane().setBackground(new Color(217,228,241));
    		/**显示屏**/
    		display1=new JTextField("");
    		display2=new JTextField("0");
    		display3=new JTextField("");
    		display1.setEnabled(false);
    		display2.setEnabled(false);
    		display3.setEnabled(false);
    		display1.setBounds(0, 0, 204, 26);
    		display2.setBounds(20, 20, 184, 34);
    		display3.setBounds(0, 20, 20, 34);
    		display1.setHorizontalAlignment(JLabel.RIGHT);
    		display2.setHorizontalAlignment(JLabel.RIGHT);
    		display3.setHorizontalAlignment(JLabel.CENTER);
    		display1.setFont(new Font("宋体",Font.PLAIN,12));
    		display2.setFont(new Font("宋体",Font.BOLD,20));
    		display3.setFont(new Font("宋体",Font.PLAIN,20));
    		display1.setDisabledTextColor(Color.BLACK);
    		display2.setDisabledTextColor(Color.BLACK);
    		display3.setDisabledTextColor(Color.BLACK);
    		display1.setBorder(new LineBorder(new Color(242,247,252)));
    		display2.setBorder(new LineBorder(new Color(242,247,252)));
    		display3.setBorder(new LineBorder(new Color(242,247,252)));
    		display1.setBackground(new Color(242,247,252));
    		display2.setBackground(new Color(242,247,252));
    		display3.setBackground(new Color(242,247,252));
    		/**按钮 35px*29px 28个***/
    		int i;
    		operate=new JButton[28];
    		/**前24个**/
    		for(i=0;i<24;i++)
    		{
    			operate[i]=new JButton(name[i]);
    			operate[i].setMargin(new java.awt.Insets(0,0,0,0)); 
    			operate[i].setBounds(i%5*(35+7), 60+i/5*(29+5)+5, 35, 29);
    			jp.add(operate[i]);
    		}
    		/***=号***/
    		operate[i]=new JButton(name[i]);
    		operate[i].setMargin(new java.awt.Insets(0,0,0,0)); 
    		operate[i].setBounds(i%5*(35+7), 60+i/5*(29+5)+5, 35, 29*2+5);
    		jp.add(operate[i]);
    		i++;
    		/***0号***/
    		operate[i]=new JButton(name[i]);
    		operate[i].setMargin(new java.awt.Insets(0,0,0,0)); 
    		operate[i].setBounds(i%5*(35+7), 60+i/5*(29+5)+5, 35*2+7, 29);
    		jp.add(operate[i]);
    		/**前24个**/
    		for(i=i+1;i<name.length;i++)
    		{
    			operate[i]=new JButton(name[i]);
    			operate[i].setMargin(new java.awt.Insets(0,0,0,0)); 
    			operate[i].setBounds((i+1)%5*(35+7), 60+i/5*(29+5)+5, 35, 29);
    			jp.add(operate[i]);
    		}
    		
    		/**
    		 * 给按钮注册鼠标监听器,键盘监听器和背景
    		 */
    		mouseAdapter ml=new mouseAdapter();
    		keyAdapter kl=new keyAdapter();
    		
    		for(i=0;i<name.length;i++)
    		{
    			operate[i].addMouseListener(ml);
    			operate[i].addKeyListener(kl);
    			operate[i].setBackground(new Color(233,240,247));
    			operate[i].setForeground(new Color(30,57,91));
    		}
    		jp.add(display1);
    		jp.add(display2);
    		jp.add(display3);
    		jp.addKeyListener(kl);
    		this.add(jp);
    		this.setVisible(true);
    	}
    	class mouseAdapter extends MouseAdapter{
    		public void mouseClicked(MouseEvent e)
    		{
    			
    			JButton operate=(JButton)e.getSource();
    			if(Disable)//禁用按钮,点击C 恢复计算器
    			{
    				if(operate.getText()=="C")
    				{	clear();
    					Disable=false;
    				}
    				else
    					return;
    			}
    			switch(operate.getText())
    			{
    			case "MC":mc();break;
    			case "MR":mr();break;
    			case "MS":ms();break;
    			case "M+":mAdd();break;
    			case "M-":mCut();break;
    			case "←":cutEnd();break;
    			case "CE":cutNum();break;
    			case "C":clear();break;
    			case "±":revolt();break;
    			case "√":sqrt();break;
    			case "7":
    			case "8":
    			case "9":
    			case "4":
    			case "5":
    			case "6":
    			case "3":
    			case "2":
    			case "1":
    			case "0":read(Integer.parseInt(operate.getText()));break;//将按键上的文本转化为Int型
    			case "/":divide();break;
    			case "%":mo();break;
    			case "*":mul();break;
    			case "1/x":inverted();break;
    			case "-":cut();break;
    			case "+":add();break;
    			case "=":sum();break;
    			case ".":dot();break;	
    			}	
    		}
    		public void mouseEntered(MouseEvent e)
    		{
    			((JButton)e.getSource()).setBackground(new Color(255,211,113));
    		}
    		public void mouseExited(MouseEvent e)
    		{
    			((JButton)e.getSource()).setBackground(new Color(233,240,247));
    		}
    	}
    	/*
    	 * MC  取消存储区,清空存储区数据
    	 */
    	public void mc()
    	{	
    		storage.storageNum=0;
    		storage.storageMode=false;
    		display3.setText(null);
    	}
    	/*
    	 * MR 读取存储器存储的数据
    	 */
    	public void mr()
    	{
    		op1.value=storage.storageNum;
    		screen2=""+op1.value;
    		if(op1.value==Math.floor(op1.value))
    			screen2=""+(int)op1.value;
    		display2.setText(screen2);
    		op1.clear=true;
    	}
    	/*
    	 * MS 保存数据到存储器
    	 */
    	public void ms()
    	{
    		storage.storageNum=op1.value;
    		display3.setText("M");//屏幕左下角显示M标志
    	}
    	/*
    	 * M+ 已经储存的数加上当前计算结果并将和存入存储器
    	 */
    	public void mAdd()
    	{
    		storage.storageNum=storage.storageNum+op1.value;		
    	}
    	/*
    	 * M- 已经储存的数减去当前计算结果并将差存入存储器
    	 */
    	public void mCut()
    	{
    		storage.storageNum=storage.storageNum-op1.value;	
    	}
    	/*
    	 * ← 输入的数去掉尾数
    	 * 
    	 */
    	public void cutEnd()
    	{
    		if(action=="op1"&&op1.value!=0)//表示对op1进行操作
    		{
    			if(op1.isFloat==false)//如果op1为整数
    			{
    				op1.value=(int)op1.value/10;
    				screen2=""+(int)op1.value;
    			}
    			else{//如果op1为小数
    				BigDecimal bd=new BigDecimal(op1.value);   
    				op1.value=bd.setScale(--op1.dotWei,BigDecimal.ROUND_DOWN).doubleValue();
    				screen2=""+op1.value;
    				if(op1.dotWei==0)//小数点后数位都去除掉后,变位整数,更新isFloat标记
    					op1.isFloat=false;
    			}
    		}
    		else if(action=="op2"&&op2.value!=0)//表示对op2进行操作
    		{
    			if(op2.isFloat==false)//如果op2位整数
    			{
    				op2.value=(int)op2.value/10;
    				screen2=""+(int)op2.value;
    			}
    			else{//如果op2为小数
    				BigDecimal  bd=new BigDecimal(op2.value);   
    				op2.value=bd.setScale(--op2.dotWei,BigDecimal.ROUND_DOWN ).doubleValue();
    				screen2=""+op2.value;
    				if(op2.dotWei==0)//小数点后数位都去除掉后,变位整数,更新isFloat标记
    					op2.isFloat=false;
    			}
    		}
    		display2.setText(screen2);//输出修改后的操作数
    	}
    	/*
    	 * CE 清空当前操作数操作数
    	 */
    	public void cutNum()
    	{
    		if(action=="op1")
    			op1.reset();
    		else if(action=="op2")
    			op2.reset();
    		display2.setText("0");//初始化显示屏2
    	}
    	/*
    	 * C 归零 重置计算器
    	 */
    	public void clear()
    	{
    		op1.reset();
    		op2.reset();
    		//初始化数据成员
    		action="op1";
    		sign="";
    		//初始化显示屏
    		display1.setText("");
    		display2.setText("0");
    	}
    	/*
    	 * ± 正负号
    	 */
    	public void revolt()
    	{
    		if(action=="op1")
    		{
    			op1.value=-op1.value;
    			screen2=""+op1.value;	
    		}
    		else if(action=="op2")
    		{
    			op2.value=-op2.value;
    			screen2=""+op2.value;
    		}
    		display2.setText(screen2);
    	}
    	/*
    	 * √ 根号
    	 */
    	public void sqrt()
    	{
    		double x;//临时变量
    		if(action=="op1")
    		{
    			op1.sqrtedString="sqrt("+op1.value+")";
    			op1.value=Math.sqrt(op1.value);
    			op1.isSqrted=true;
    			x=op1.value;	
    		}
    		else
    		{
    			op2.sqrtedString="sqrt("+op2.value+")";
    			op2.value=Math.sqrt(op2.value);
    			op2.isSqrted=true;
    			x=op2.value;
    		}
    		screen2=x+"";
    		if(x==Math.floor(x))//如果x为整数
    		{
    			screen2=(int)x+"";//则将浮点数x先转化为int再转化成字符串
    		}
    		display2.setText(screen2);
    		
    	}
    	/*
    	 * 按下数字键
    	 */
    	public void read(int value)
    	{
    		display2.setFont(new Font("宋体",Font.BOLD,20));//默认字体大小
    		display2.setText(null);//清屏
    		if(op1.clear==true)
    			op1.reset();
    		if(op2.clear==true)
    			op2.reset();
    		if(action=="op1")//表示输数据给op1
    		{	
    			
    			if(op1.isFloat==true)//若op1为浮点数
    			{
    				int i=1;
    				double num=value;
    				++op1.dotWei;
    				while(i<=op1.dotWei)
    				{
    					num*=0.1;
    					i++;
    				}
    				op1.value=op1.value+num;//将新的小数点位添加到操作数op1中
    				//因为双精度浮点数 其精度比较高,而我们只需取它的op1.dotWei保存
    				op1.value=Double.parseDouble(String.format("%."+op1.dotWei+"f",op1.value));
    				//因为双精度浮点数 其精度比较高,而我们只需取它的op1.dotWei显示在屏幕上
    				display2.setText(String.format("%."+op1.dotWei+"f", op1.value));
    			}
    			else//op1为整数
    			{	
    				op1.value=op1.value*10+value;//将新的整数位加倒op1中
    				display2.setText((int)op1.value+"");//屏幕输出op1的值
    			}
    		}
    		else if(action=="op2")//表示输数据给op2
    		{
    			if(op2.isFloat==true)//若op2为浮点数
    			{
    				int i=1;
    				double num=value;
    				++op2.dotWei;
    				while(i<=op2.dotWei)
    				{
    					num*=0.1;
    					i++;
    				}
    				op2.value=op2.value+num;//将新的小数点位添加到操作数op2中
    				//因为双精度浮点数 其精度比较高,而我们只需取它的op2.dotWei保存
    				op2.value=Double.parseDouble(String.format("%."+op2.dotWei+"f",op2.value));
    				//因为双精度浮点数 其精度比较高,而我们只需取它的op2.dotWei显示在屏幕上
    				display2.setText(String.format("%."+op2.dotWei+"f", op2.value));
    			}
    			else//op2为整数
    			{
    				op2.value=op2.value*10+value;
    				display2.setText((int)op2.value+"");
    			}
    			
    		}
    	}
    	public void divide()
    	{
    		run("/");
    	}
    	public void mo()
    	{
    		run("%");
    	}
    	public void mul()
    	{
    		run("*");
    	}
    	/*
    	 * 1/x
    	 */
    	public void inverted()
    	{
    		double num;
    		String str;
    		if(action=="op1")
    		{
    			op1.invertedString="1/"+op1.value;//1/x形式字符串
    			op1.value=1/op1.value;
    			op1.isInverted=true;
    			num=op1.value;
    		}
    		else{
    			op2.invertedString="1/"+op2.value;//1/x形式字符串
    			op2.value=1/op2.value;
    			op1.isInverted=true;
    			num=op2.value;
    		}
    		str=num+"";
    		if(str.length()>=16)//计算器屏幕所能显示数据的最大长度
    		{
    			display2.setFont(new Font("宋体",Font.BOLD,14));//缩小字体输出
    			display2.setText(str.substring(0, 16));	
    		}
    		else
    			display2.setText(str);
    	}
    	public void cut()
    	{
    		run("-");
    	}
    	public void add()
    	{
    		run("+");
    	}
    	public void sum()
    	{
    		display2.setFont(new Font("宋体",Font.BOLD,20));
    		int d1=op1.dotWei,d2=op2.dotWei,i;
    		switch(sign)
    		{ 	//运算后 结果保存到op1中
    			case "+":op1.value=op1.value+op2.value;break;
    			case "-":op1.value=op1.value-op2.value;break;
    			case "*":op1.value=op1.value*op2.value;break;
    			case "/":op1.value=op1.value/op2.value;break;
    			case "%":op1.value=op1.value%op2.value;break;
    		}
    		if(op2.value==0&&sign=="/")//除数为0
    		{
    			Disable=true;
    			display2.setText(op1.value+"");
    			display1.setText(null);
    			action="op1";
    			return ;
    		}
    		if(op1.value==Math.floor(op1.value))//结果为整数
    		{
    			display2.setText((int)op1.value+"");
    			op1.dotWei=0;
    			op1.isFloat=false;
    		}
    		else{//结果为小数
    			String str=op1.value+"";
    			//准确控制算术运算结果的精度,加,减,取模运算,小数点后的有效数字最多为max(d1,d2)位
    			if(sign.equals("+")||sign.equals("-")||sign.equals("%"))
    			{
    				i=d1>d2?d1:d2;
    				str=op1.value+"";
    				str=str.substring(0, str.indexOf(".")+i+1);//取i位输出
    			}
    			//准确控制算术运算结果的精度,乘法运算,小数点后的有效数字最多为d1+d2位
    			else if(sign.equals("*"))
    			{
    				i=d1+d2;
    				BigDecimal bd=new BigDecimal(op1.value); 
    				op1.value=bd.setScale(i,BigDecimal.ROUND_DOWN ).doubleValue();
    				str=op1.value+"";//更新修改后的str
    			}
    			//结果超过显示数据的最大长度
    			if(str.length()>=16)
    			{
    				display2.setFont(new Font("宋体",Font.BOLD,14));
    				str=str.substring(0, 16);
    			}
    				display2.setText(str);
    				op1.dotWei=str.length()-str.indexOf(".")-1;//更新op1w值
    		}		
    
    		display1.setText(null);
    		action="op1";
    		op1.clear=true;//开始新的表达式运算时,op1要先重置
    		op2.clear=true;//开始新的表达式运算时,op2要先重置
    		sign="";
    	}
    	public void dot()
    	{
    		if(action=="op1")
    			op1.isFloat=true;
    		else
    			op2.isFloat=true;
    		display2.setText(display2.getText()+".");
    	}
    	public void run(String SIGN)
    	{
    		display2.setFont(new Font("宋体",Font.BOLD,20));
    		action="op2";
    		int d1=op1.dotWei,d2=op2.dotWei,i;
    		if(!sign.equals(""))//检测是否为以为表达式的第一运算
    		{
    			switch(sign)
    			{//运算后 结果保存到op1中
    			case "+":op1.value=op1.value+op2.value;break;
    			case "-":op1.value=op1.value-op2.value;break;
    			case "*":op1.value=op1.value*op2.value;break;
    			case "/":op1.value=op1.value/op2.value;break;
    			case "%":op1.value=op1.value%op2.value;break;
    			}
    		}
    		String temp=isSpecileHandle();
    		if(temp==null)
    			temp=display2.getText();//先保存display2文本框里的数据
    		if(op2.value==0&&sign=="/")//除数为0
    		{
    			Disable=true;
    			display2.setText(op1.value+"");
    			display1.setText(display1.getText()+op1.value);
    		}
    		if(op1.value==Math.floor(op1.value))//结果为整数
    		{
    			display2.setText((int)op1.value+"");
    			op1.dotWei=0;
    			op1.isFloat=false;
    		}
    		else{
    			String str=op1.value+"";
    			//准确控制算术运算结果的精度,加,减,取模运算,小数点后的有效数字最多为max(d1,d2)位
    			if(sign.equals("+")||sign.equals("-")||sign.equals("%"))
    			{
    				i=d1>d2?d1:d2;
    				BigDecimal bd=new BigDecimal(op1.value); 
    				op1.value=bd.setScale(i,BigDecimal.ROUND_DOWN ).doubleValue();
    				str=op1.value+"";//更新修改后的str
    			}
    			//准确控制算术运算结果的精度,乘法运算,小数点后的有效数字最多为d1+d2位
    			else if(sign.equals("*"))
    			{
    				i=d1+d2;
    				BigDecimal bd=new BigDecimal(op1.value); 
    				op1.value=bd.setScale(i,BigDecimal.ROUND_DOWN ).doubleValue();
    				str=op1.value+"";//更新修改后的str
    			}
    			//结果超过显示数据的最大长度
    			if(str.length()>=16)
    			{
    				display2.setFont(new Font("宋体",Font.BOLD,14));
    				str=str.substring(0, 16);
    			}
    			display2.setText(str);
    			op1.dotWei=str.length()-str.indexOf(".")-1;//每次加完后,如果结果op1的值为小数则更新op1w的值	
    		}		
    		sign=SIGN;
    		display1.setText(display1.getText()+temp+sign);
    		op2.value=op1.value;//运算后,操作数op2默认的值为op1的值	
    		op2.clear=true;//下一次键入数据,op2要重置
    		op1.clear=false;//下一次键入数据,op1不要重置
    	}
    	/*
    	 * isSpecileHandle() 
    	 * 操作数是否sqrt()或1/x过,
    	 * 如果有,则返回"sqrt(x)"或"1/x"字符串
    	 */
    	public String isSpecileHandle()
    	{
    		String temp=null;
    		if(op1.isSqrted)
    		{
    			temp=op1.sqrtedString;
    			op1.isSqrted=false;
    		}
    		else if(op2.isSqrted)
    		{
    			temp=op2.sqrtedString;
    			op2.isSqrted=false;
    		}
    		if(op1.isInverted)
    		{
    			temp=op1.invertedString;
    			op1.isInverted=false;
    		}
    		else if(op2.isInverted)
    		{
    			temp=op2.invertedString;
    			op2.isInverted=false;
    		}
    		return temp;
    	}
    	class keyAdapter extends KeyAdapter{
    		public void keyPressed(KeyEvent e)
    		{
    		
    			int keycode=e.getKeyCode();
    			if((keycode>=96&&keycode<=105)||(keycode>=48&&keycode<=57))//数字键
    			{
    				if(keycode>=96)
    					keycode-=48;
    				switch(keycode)
    				{
    				case 48:read(0);break;
    				case 49:read(1);break;
    				case 50:read(2);break;
    				case 51:read(3);break;
    				case 52:read(4);break;
    				case 53:read(5);break;
    				case 54:read(6);break;
    				case 55:read(7);break;
    				case 56:read(8);break;
    				case 57:read(9);break;
    				}
    			}
    			//运算符键+ - * / =和. 以及退格键(* =号)
    			else if((keycode==110||keycode==46)||(keycode==111||keycode==47)||(keycode==45||keycode==109)||keycode==107||keycode==106||keycode==61||keycode==10||keycode==8)
    			{
    				if((keycode==110||keycode==46))
    					dot();
    				else if(keycode==111||keycode==47)
    					run("/");
    				else if(keycode==45||keycode==109)
    					run("-");
    				else if(keycode==107)
    					run("+");
    				else if(keycode==106)
    					run("*");
    				else if(keycode==61||keycode==10)//=号
    					sum();
    				else if(keycode==8)
    					cutEnd();
    			}
    		}
    	}
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		calc app=new calc();
    		
    		
    	}
    }
    

    程序截图




  • 相关阅读:
    7.4 List集合
    vue学习笔记
    javaWEB中web.xml配置文件相关
    maven常用dos命令
    Oracle,sqlserver,mySQl的区别和联系:
    oracle数据库视图,序列,索引的sql语句查看
    java 异常处理
    线程专题
    package、folder和source folder的区别
    Java内存分配之堆、栈和常量池
  • 原文地址:https://www.cnblogs.com/chenny3/p/10226236.html
Copyright © 2020-2023  润新知