Java编写计算器

一点感悟 
最初看这个代码时,看不懂! 
最大的困惑就是运算符这块,当你输入第一个运算数,再输入运算符,这个时候没有第二个运算数,是无法进行运算的,百事不得其解!! 
突然想到用System.out.println();来观察程序的运行顺序!!! 
然后有了重大发现!!!! 
举个例子:当你输入第一个运算数时,再输入+号,而之前声明operator默认为=,所以执行的是=的方法,将第一个运算数赋值给中间变量resultNum;(这个设计很精妙) 
再令operator=label,即operator=“+”; 
然后再输入第二个运算数,由 getNumBerFromText()方法获取; 
接着输入=,但此时operator=“+”;故而执行+的方法,resultNum+=getNumberFrom!!!!! 
 
 
原程序有些bug,已改进 
1、±运算 
2、handleBackspace有点小问题 
 

感谢别人的分享,模仿是最好的老师,站在巨人的肩膀上才能看得更远!!!!!! 

感谢别人的帮助,并学会去帮助别人!!!!!!! 

package cn.bjsxt.swingCalculator;
/**
 * 1.继承,super()
 * 2.数组的声明,赋值,初始化,方法
 * 3.构造器,构造器里可以写哪些方法
 * 4.String类好好看看,一些常用方法要熟悉
 * 5.学会使用API,不知道的方法百度 
 * 6.养成写注释的习惯
 * 7.方法里可以嵌套方法,独立的方法之间又相互联系
 * 8.用假设法,举例法验证自己的猜想,注意程序的顺序,注意细节!!!
 * 9。善用System.out.println()进行检查,观察程序的执行顺序
 * 10.学会debug进行调试
 * 11.抽象方法
 * 12.类变量,实例变量;类方法,实例方法
 * 13.局部变量和全局变量
 * 14.C键的处理方法,与其思考怎么去删除(过程),不如考虑删除后的样子(结果)
 * 15.思考任何问题都可以从过程和结果两方面考虑
 * 16.举反例帮助理解,如果不这样会怎样!!!
 * 17.try,catch语句
 * 18.对于各种控制语句学会灵活运用
 */

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;


/*
 * 编写一个计算器,与Windows附件计算器标准版的功能、界面相仿,但不支持键盘输入。
 */

public class Calculator extends javax.swing.JFrame implements ActionListener {
	//计算器上键的显示名字
	private final String KEY[]={"7","8","9","/","√","4","5","6","*","%","1","2","3","-","1/x","0","±",".","+","="};//数组常量,常量名大写
    //计算器上的功能键显示的名字
	private final String COMMAND[]={"Backspace","CE","C"};
    //计算器左边的M的显示名字
	private final String M[]={"MC","MR","MS","M+","M-"};
	
	//计算器上键的按钮
	private JButton key[]=new JButton[KEY.length];
	//计算器上的功能键的按钮
	private JButton command[]=new JButton[COMMAND.length];
	//计算器左边的M键的按钮
	private JButton m[]=new JButton[M.length];
	//计算结果文本框
	private JTextField resultText=new JTextField("0");
	
	//标志用户按的是否是整个表达式的第一个数字,或是运算符后的第一个数字
	private boolean firstDigit=true;
	//计算的中间结果
	private double resultNum=0.0;
	//当前运算的运算符
	private String operator="=";
	//操作是否合法
	private boolean operateValidFlag=true;
	
	
	//构造函数********************************
	public Calculator(){
		super();
		//初始化计算器
		init();
		//设置计算器的背景颜色
		this.setBackground(Color.LIGHT_GRAY);
		//设置计算器的标题
		this.setTitle("我是计算器");
		//在屏幕(500,300)坐标处显示计算器
		this.setLocation(500,300);
		//不能修改计算器的大小
		this.setResizable(false);
		//使计算器各组件大小合适
		this.pack();//Causes this Window to be sized to fit the preferred size and layouts of its subcomponents.
		
	}

	//初始化计算器**************************
	private void init() {
		// TODO Auto-generated method stub
		//文本框中内容采用右对齐方式
		resultText.setHorizontalAlignment(JTextField.RIGHT);
		//不允许修改结果文本框
		resultText.setEditable(false);
		//设置文本框背景颜色为白色
		resultText.setBackground(Color.white);
		
		
		//初始化计算器上键的按钮,将键画在一个面板内
		JPanel calkeyPanel=new JPanel();
		//用网格布局管理器,创建一个4行5列的网格,网格的水平间距为3个像素,垂直间距为3个像素
		calkeyPanel.setLayout(new GridLayout(4,5,3,3));
		for(int i=0;i<KEY.length;i++){
			key[i]=new JButton(KEY[i]);
			calkeyPanel.add(key[i]);
			key[i].setForeground(Color.BLUE);
		}
		//运算符键用红色标示,其他键用蓝色表示
		key[3].setForeground(Color.red);
		key[8].setForeground(Color.red);
		key[13].setForeground(Color.red);
		key[18].setForeground(Color.red);
		key[19].setForeground(Color.red);
		
		
		//初始化功能键,都用红色表示,将功能键放在一个画板内
		JPanel commandPanel=new JPanel();
		//用网格布局器,创建1行3列的网格,水平间距为3个像素,垂直间距为3个像素
		commandPanel.setLayout(new GridLayout(1,3,3,3));
		for(int i=0;i<COMMAND.length;i++){
			command[i]=new JButton(COMMAND[i]);
			commandPanel.add(command[i]);
			command[i].setForeground(Color.red);
		}
		
		
		//初始化M键,用红色表示,将其放在一个面板内
		JPanel calmPanel=new JPanel();
		//用网格布局器,创建5行1列的网格,网格之间的水平间距为3个像素,垂直间距为3个像素
		calmPanel.setLayout(new GridLayout(5,1,3,3));
		for(int i=0;i<M.length;i++){
			m[i]=new JButton(M[i]);
			calmPanel.add(m[i]);
			m[i].setForeground(Color.red);
		}
		
		
		//下面进行计算器的整体布局,将calkeyPanel和commandPanel面板放在计算器的中部
		//将文本框放在北部,calmPanel面板放在西部
		
		//新建一个大的画板,将calkeyPanel和commandPanel面板放在其中
		JPanel panel1=new JPanel();
		//画板采用边框布局管理器,画板里组件之间垂直和水平间距为3像素
		panel1.setLayout(new BorderLayout(3,3));
		panel1.add("North",calkeyPanel);
		panel1.add("West",commandPanel);
		
		
		//创建一个画板放文本框
		JPanel top=new JPanel();
		top.setLayout(new BorderLayout());
		top.add("Center",resultText);
		
		
		//整体布局
		//public Container getContentPane() {return getRootPane().getContentPane();}
 		getContentPane().setLayout(new BorderLayout(3,5));
		getContentPane().add("North",top);// public Component add(String name, Component comp)
		getContentPane().add("West", calmPanel);
		getContentPane().add("Center",panel1);
		
		
		//为各按钮添加事件监听器
		//都使用同一个事件监听器,即本对象。本类的声明中有implements ActionListener
		for(int i=0;i<KEY.length;i++){
			key[i].addActionListener(this);
		}
		for(int i=0;i<COMMAND.length;i++){
			command[i].addActionListener(this);
		}
		for(int i=0;i<M.length;i++){
			m[i].addActionListener(this);
		}
	
	}
	
	
	
	

	//处理事件***************************************************
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
  		//获取事件源的标签
		String lable=e.getActionCommand();
		if(lable.equals(COMMAND[0])){
			//用户按了“Backspace”键
			handleBackspace();
		}else if(lable.equals(COMMAND[1])){
			//用户按了“CE”键
			resultText.setText("0");
		}else if(lable.equals(COMMAND[2])){
			//用户按了“C”键
			handleC();
		}else if("1234567890.".indexOf(lable)>=0){
			//用户按了数字键或小数点键
			handleNum(lable);
		}else{
			//用户按了运算符键
			handleOperator(lable);
		}
		
	}
	
	
	
	//处理运算符按下的事件*******************************************
	private void handleOperator(String key) {
		// TODO Auto-generated method stub
		if(operator.equals("/")){
			//除法运算
			//如果当前文本框中的值为零
			if(getNumberFromText()==0.0){
				//操作不合法
				operateValidFlag=false;
				resultText.setText("除数不能为0");
			
			}else{
				resultNum=resultNum/getNumberFromText();
			}
		}else if(operator.equals("1/x")){
			//倒数运算
			if(resultNum==0.0){
				//操作不合法
				operateValidFlag=false;
				resultText.setText("0没有倒数!");
			}else{
				resultNum=1/resultNum;
			}
		
		}else if(operator.equals("+")){
			//加法运算
			resultNum=resultNum+getNumberFromText();
			System.out.println("计算器");
			System.out.println(resultNum);
			System.out.println(getNumberFromText());
		}else if(operator.equals("-")){
			//减法运算
			resultNum=resultNum-getNumberFromText();
		}else if(operator.equals("*")){
			//乘法运算
			resultNum=resultNum*getNumberFromText();
		}else if(operator.equals("√")){
			//平方根运算
			resultNum=Math.sqrt(resultNum);
		}else if(operator.equals("%")){
			//百分号运算
			resultNum=resultNum/100;
		}else if(operator.equals("±")){
			//正负号运算
			resultNum=resultNum*(-1);
		}else if(operator.equals("=")){
			//赋值运算
			resultNum=getNumberFromText();
			System.out.println(getNumberFromText());
		}
		if(operateValidFlag){
			//双精度浮点数的运算
			long t1;
			double t2;
			t1=(long)resultNum;
			t2=resultNum-t1;
			if(t2==0){
				resultText.setText(String.valueOf(t1));
				System.out.println("t1=t2");
			}else{
				resultText.setText(String.valueOf(resultNum));
				System.out.println("t1!!=t2");
			}
		}
		//运算符等于用户按的按钮
		operator=key;
		firstDigit=true;
		operateValidFlag=true;
		
		
		
	}
	
	
	//从结果文本框中获取数字**********************************
	private double getNumberFromText() {
		// TODO Auto-generated method stub
		double result=0;
		try{
			//public static Double valueOf(String s)
            //throws NumberFormatException
			//返回保存用参数字符串 s 表示的 double 值的 Double 对象。
			//如果 s 为 null,则抛出 NullPointerException 异常。 
			//public double doubleValue()
			//返回此 Double 对象的 double 值。 
		result=Double.valueOf(resultText.getText()).doubleValue();
		}catch(NumberFormatException e){
			
		}
		return result; 
	}
	
	
	
	//处理数字键***************************************
	private void handleNum(String key) {
		// TODO Auto-generated method stub
		if(firstDigit){
			//输入的第一个数字
			resultText.setText(key);
		}else if((key.equals("."))&&(resultText.getText().indexOf(".")<0)){
			//输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面
			resultText.setText(resultText.getText()+".");
		}else if(!key.equals(".")){
			//如果输入的不是小数点,则将数字附在结果文本框的后面
			resultText.setText(resultText.getText()+key);
		}
		//以后输入的肯定不是第一个数字
		firstDigit=false;
	}
	
	
	//处理C键***************************************************
	private void handleC() {
		// TODO Auto-generated method stub
		//初始化计算器的各种值
		resultText.setText("0");
		firstDigit=true;
		operator="=";
		
	}
	
	
	//处理Backspace键被按下的事件*************************************
	private void handleBackspace() {
		// TODO Auto-generated method stub
		String text=resultText.getText();//获取文本框的内容赋给变量text
		int i=text.length();
		if(i>0){
			//退格,将文本最后一个字符去掉
			text=text.substring(0, i-1);
			if(text.length()==0){
				//如果文本框只有1个字符,按下Backspace键后文本框字符为0
				resultText.setText("0");
				//如果文本框没有内容,则初始化计算器的各种值
				firstDigit=true;
				operator="=";
			}else{
				//显示新的文本
				resultText.setText(text);
			}
			
		}
		
	}
	
	
	//主方法,程序的入口***************************************************
	public static void main(String[] args){
		Calculator calculator1=new Calculator();
		calculator1.setVisible(true);
		calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值