java图形化界面实现简单混合运算计算器

写了好几天了终于写完了这个四则运算计算器,总代码放在后面

截图如下:

首先是布局都比较简单,最上面的一个框是总的输出框,

第二个框是每次输入的数字显示在框内,

对于每一个按钮都增加监听器,

 

对于数字按钮:当长度大于8的 或者等号已经出现之后就不再处理按钮事件

if(e.getSource().equals(button1)) {
	s=numberText.getText();
        //数字长度大于8或者等号已出现
	if(s.length()>8 || equalbook == 1) {
				
	}
	else if(s.equals("0") || s.equals("")) {
	    numberText.setText("1");
	}else {
	    numberText.setText(s + "1");
	}	
}

 其余的按钮都差不多。

当按钮为小数点时,长度大于7就不再处理,因为总的长度不能超过8,而小数点后面还要与数字,

同时标记小数点已经出现过,因为一个数中最多出现一个小数点

//当按钮为小数点时
if(e.getSource().equals(buttonpoint)) {
	s=numberText.getText();
	if(s.length()>7 || equalbook == 1) {
				
	}
	if(pointbook==0) {
		numberText.setText(s + ".");
		pointbook = 1;
	}
}

当按钮为加号时:

当数字输入框为空时不做处理

也有可能是最后一位是小数点,当然也不处理

当最上方的输出框的最后一位是右括号的时候,可以用加号

//当按钮为加号时
if(e.getSource().equals(buttonadd)) {
	s=numberText.getText();
	char ch1[] = s.toCharArray();
	int length1 = s.length() - 1;
	
	String S = expressText.getText();
	char ch2[] = S.toCharArray();
	int length2 = S.length() - 1;
	//当数字为空或为0或数字的最后一位是小数点时不作处理
	if((length2 == -1 ||ch2[length2] != ')') && (s.equals("0") || s.equals("") || ch1[length1] == '.')) {
		
	}else {
		numberText.setText("");
		expressText.setText(expressText.getText() + s + "+");
	}
	
}

+, -, *, /都差不多

 

当前面是运算符或者左括号的时候才能用左括号, 注意当框内无元素的时候也可以加左括号, 但是需要判断元素的个数是否大于0

if(e.getSource().equals(buttonleft)) {
	if(!numberText.getText().equals("0") && !numberText.getText().contentEquals("")) {
		expressText.setText(expressText.getText() + numberText.getText());
	}
	s=expressText.getText();
	char ch[] = s.toCharArray();
	int length = s.length() - 1;
	/*
	 * 当前面是运算符或者左括号的时候才能用左括号
	 * 注意当框内无元素的时候也可以加左括号
	 * 但是需要判断元素的个数是否大于0
	 */
	if(length == -1 || ch[length] == '+' || ch[length] == '-' || 
	   ch[length] == '*' || ch[length] == '/' || 
	   ch[length] == '(' || s.equals("")) {
		expressText.setText(expressText.getText() + '(');
		leftNum++;
	}
	
}

右括号就不一样

if(e.getSource().equals(buttonright)) {
	if(!numberText.getText().equals("0")) {
		expressText.setText(expressText.getText() + numberText.getText());
		numberText.setText("");
	}
	
	s=expressText.getText();
	char ch[] = s.toCharArray();
	int length = s.length() - 1;
	/*
	 * 只有前面是数字的时候且左括
	 * 号的数量大于右括号的数量的时候才能加右括号
	 */
	if(Character.isDigit(ch[length]) && leftNum > rightNum)  {
		rightNum++;
		expressText.setText(expressText.getText() + ')');
	}
	
}

当按钮为 C时,清除所有内容并更新等号状态, 左括号数量, 右括号数量, 小数点状态,当一次计算完成之后,只有按C按钮才能进行新的计算。

当按钮为CE时,只清除数字框中的内容。

if(e.getSource().equals(buttonC)) {
    numberText.setText("0");
    expressText.setText("");
    leftNum = 0;
    rightNum = 0;
    pointbook = 0;
    equalbook = 0;
}

 

当按钮为等号时就把总输出框中显示的字符串取出进行计算,因为这个计算器是带括号的,所以这里我用了逆波兰表达式做的,需要把中缀表达式变为后缀表达式,然后进行计算,这一点我认为是最困难的一点,后面有时间我会再写关于 逆波兰表达式实现以及 逆波兰表达式的求值。

关于逆波兰表达式的转化与求值 : https://blog.csdn.net/qq_41505957/article/details/103026407

 

需要注意588行的代码,最后的两个括号的条件没有加上,导致花了周末一天在找bug......

else if((ch[j] == '*' || ch[j] == '/') &&
        (operater1=='+' || operater1=='-') || 
        (operater1=='(' || operater1 == ')')) {
	    Operater.push(ch[j]);
            break;
}

所有代码:

package cn.edu.shengda;

/*
 * author 201705050153 张宜强
 */

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Calculator extends JFrame implements ActionListener {
	Calculator() {
		init();
	}
	public void init() {
	JFrame frame = new JFrame ("计算器");
        frame.setLayout(null);
        
        //放置数字0
        button0 = new JButton("0");
        button0.setBounds(20, 200, 100, 25);
        frame.add(button0);
        
        //放置数字1
        button1 = new JButton("1");
        button1.setBounds(20, 170, 45, 25);
        frame.add(button1);
        
        //放置数字2
        button2 = new JButton("2");
        button2.setBounds(75, 170, 45, 25);
        frame.add(button2);
        
        //放置数字3
        button3 = new JButton("3");
        button3.setBounds(130, 170, 45, 25);
        frame.add(button3);
        
        //放置数字4
        button4 = new JButton("4");
        button4.setBounds(20, 140, 45, 25);
        frame.add(button4);
        
        //放置数字5
        button5 = new JButton("5");
        button5.setBounds(75, 140, 45, 25);
        frame.add(button5);
        
        //放置数字6
        button6 = new JButton("6");
        button6.setBounds(130, 140, 45, 25);
        frame.add(button6);
        
        //放置数字7
        button7 = new JButton("7");
        button7.setBounds(20, 110, 45, 25);
        frame.add(button7);
        
        //放置数字8
        button8 = new JButton("8");
        button8.setBounds(75, 110, 45, 25);
        frame.add(button8);
        
        //放置数字9
        button9 = new JButton("9");
        button9.setBounds(130, 110, 45, 25);
        frame.add(button9);
        
        //放置 .
        buttonpoint = new JButton(".");
        buttonpoint.setBounds(130, 200, 45, 25);
        frame.add(buttonpoint);
        
        //放置 +
        buttonadd = new JButton("+");
        buttonadd.setBounds(185, 200, 45, 25);
        frame.add(buttonadd);
        
        //放置 -
        buttonreduce = new JButton("-");
        buttonreduce.setBounds(185, 170, 45, 25);
        frame.add(buttonreduce);
        
         //放置 *
        buttonride = new JButton("*");
        buttonride.setBounds(185, 140, 45, 25);
        frame.add(buttonride);
             
        //放置 /
        buttonexcept = new JButton("/");
        buttonexcept.setBounds(185, 110, 45, 25);
        frame.add(buttonexcept);
        
        //放置 =
        buttonequal = new JButton("=");
        buttonequal.setBounds(240, 170, 55, 55);
        frame.add(buttonequal);
        
        //计算1/x
        buttoninvert = new JButton("1/x");
        buttoninvert.setBounds(240, 110, 55, 55);
        frame.add(buttoninvert);
        
        //放置左括号
        buttonleft = new JButton("(");
        buttonleft.setBounds(20, 80, 45, 25);
        frame.add(buttonleft);
        
        //放置右括号
        buttonright = new JButton(")");
        buttonright.setBounds(75, 80, 45, 25);
        frame.add(buttonright);
        
        //放置C  消除所有输入
        buttonC = new JButton("C");
        buttonC.setBounds(130, 80, 75, 25);
        frame.add(buttonC);
        
        //放置CE 消除当前输入
        buttonCE = new JButton("CE");
        buttonCE.setBounds(220, 80, 75, 25);
        frame.add(buttonCE);
        
        //添加表达式文本框
        expressText = new JTextField();
        expressText.setBounds(20, 10, 300, 30);
        frame.add(expressText);
        
        //添加数字文本框
        numberText = new JTextField("0");
        numberText.setBounds(20, 40, 300, 30);
        frame.add(numberText);
        
        //加监听器
        button0.addActionListener(this);
        button1.addActionListener(this);
        button2.addActionListener(this);
        button3.addActionListener(this);
        button4.addActionListener(this);
        button5.addActionListener(this);
        button6.addActionListener(this);
        button7.addActionListener(this);
        button8.addActionListener(this);
        button9.addActionListener(this);
        buttonpoint.addActionListener(this);
        buttonadd.addActionListener(this);
        buttonreduce.addActionListener(this);
        buttonride.addActionListener(this);
        buttonexcept.addActionListener(this);
        buttoninvert.addActionListener(this);
        buttonequal.addActionListener(this);
        buttonleft.addActionListener(this);
        buttonright.addActionListener(this);
        buttonC.addActionListener(this);
        buttonCE.addActionListener(this);
        numberText.addActionListener(this);
        expressText.addActionListener(this);
    
        frame.setBounds(0, 0, 350, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
	}
	
	JButton button0;
	JButton button1;
	JButton button2;
	JButton button3;
	JButton button4;
	JButton button5;
	JButton button6;
	JButton button7;
	JButton button8;
	JButton button9;
	JButton buttonpoint;
	JButton buttonadd;
	JButton buttonreduce;
	JButton buttonride;
	JButton buttonexcept;
	JButton buttonequal;
	JButton buttoninvert;
	JButton buttonleft;
	JButton buttonright;
	JButton buttonC;
	JButton buttonCE;
	JTextField numberText;
	JTextField expressText;
	
	
	String s = null;          
    //记录小数点是否出现,每次当前数字框中只能出现一个小数点
	int pointbook = 0;
    //记录等号是否出现,每次计算的总算式只能出现一个等号
     int equalbook = 0; 
     //记录左括号的数量
     int leftNum = 0;
     //记录有括号的数量
     int rightNum = 0;
     
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		             
		//当按钮为0时
		if(e.getSource().equals(button0)) {
			s=numberText.getText();
			if(s.length()>8) {
				
			}
			else if(s.equals("0") || equalbook == 1) {
				
			}else {
				numberText.setText(s + "0");
			}
		}
		
		//当按钮为1时
		if(e.getSource().equals(button1)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("1");
			}else {
				numberText.setText(s + "1");
			}	
		}
		
		//当按钮为2时
		if(e.getSource().equals(button2)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("2");
			}else {
				numberText.setText(s + "2");
			}	
		}
		
		//当按钮为3时
		if(e.getSource().equals(button3)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("3");
			}else {
				numberText.setText(s + "3");
			}	
		}
		
		//当按钮为4时
		if(e.getSource().equals(button4)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("4");
			}else {
				numberText.setText(s + "4");
			}	
		}
		
		//当按钮为5时
		if(e.getSource().equals(button5)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("5");
			}else {
				numberText.setText(s + "5");
			}	
		}
		
		//当按钮为6时
		if(e.getSource().equals(button6)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("6");
			}else {
				numberText.setText(s + "6");
			}	
		}
		
		//当按钮为7时
		if(e.getSource().equals(button7)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("7");
			}else {
				numberText.setText(s + "7");
			}	
		}
		
		//当按钮为3时
		if(e.getSource().equals(button8)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("8");
			}else {
				numberText.setText(s + "8");
			}	
		}
		
		//当按钮为9时
		if(e.getSource().equals(button9)) {
			s=numberText.getText();
			if(s.length()>8 || equalbook == 1) {
				
			}
			else if(s.equals("0") || s.equals("")) {
				numberText.setText("9");
			}else {
				numberText.setText(s + "9");
			}	
		}
		
		//当按钮为小数点时
		if(e.getSource().equals(buttonpoint)) {
			s=numberText.getText();
			if(s.length()>7 || equalbook == 1) {
				
			}
			if(pointbook==0) {
				numberText.setText(s + ".");
				pointbook = 1;
			}
		}
		
		//当按钮为加号时
		if(e.getSource().equals(buttonadd)) {
			s=numberText.getText();
			char ch1[] = s.toCharArray();
			int length1 = s.length() - 1;
			
			String S = expressText.getText();
			char ch2[] = S.toCharArray();
			int length2 = S.length() - 1;
			//当数字为空或为0或数字的最后一位是小数点时不作处理
			if((length2 == -1 ||ch2[length2] != ')') && (s.equals("0") || s.equals("") || ch1[length1] == '.')) {
				
			}else {
				numberText.setText("");
				expressText.setText(expressText.getText() + s + "+");
			}
			
		}
		
		//当按钮为减号时
		if(e.getSource().equals(buttonreduce)) {
			s=numberText.getText();
			char ch1[] = s.toCharArray();
			int length1 = s.length() - 1;
			
			String S = expressText.getText();
			char ch2[] = S.toCharArray();
			int length2 = S.length() - 1;
			if((length2 == -1 ||ch2[length2] != ')') && (s.equals("0") || s.equals("") || ch1[length1]=='.')) {
				
			}else {
				numberText.setText("");
				expressText.setText(expressText.getText() + s + "-");
			}
		}
		
		//当按钮为乘号时
		if(e.getSource().equals(buttonride)) {
			s=numberText.getText();
			char ch1[] = s.toCharArray();
			int length1 = s.length() - 1;
			
			String S = expressText.getText();
			char ch2[] = S.toCharArray();
			int length2 = S.length() - 1;
			if((length2 == -1 ||ch2[length2] != ')') &&  (s.equals("0") || s.equals("") || ch1[length1]=='.')) {
				
			}else {
				numberText.setText("");
				expressText.setText(expressText.getText() + s + "*");
			}
		}
		
		//当按钮为除号时
		if(e.getSource().equals(buttonexcept)) {
			s=numberText.getText();
			char ch1[] = s.toCharArray();
			int length1 = s.length() - 1;
			
			String S = expressText.getText();
			char ch2[] = S.toCharArray();
			int length2 = S.length() - 1;
			if((length2 == -1 ||ch2[length2] != ')') &&  (s.equals("0") || s.equals("") || ch1[length1]=='.')) {
				
			}else {
				numberText.setText("");
				expressText.setText(expressText.getText() + s + "/");
			}
		}
		
		//当按钮为左括号时
		if(e.getSource().equals(buttonleft)) {
			if(!numberText.getText().equals("0") && !numberText.getText().contentEquals("")) {
				expressText.setText(expressText.getText() + numberText.getText());
			}
			s=expressText.getText();
			char ch[] = s.toCharArray();
			int length = s.length() - 1;
			/*
			 * 当前面是运算符或者左括号的时候才能用左括号
			 * 注意当框内无元素的时候也可以加左括号
			 * 但是需要判断元素的个数是否大于0
			 */
			if(length == -1 || ch[length] == '+' || ch[length] == '-' || 
			   ch[length] == '*' || ch[length] == '/' || 
			   ch[length] == '(' || s.equals("")) {
				expressText.setText(expressText.getText() + '(');
				leftNum++;
			}
			
		}
		
		//当按钮为右括号时
		if(e.getSource().equals(buttonright)) {
			if(!numberText.getText().equals("0")) {
				expressText.setText(expressText.getText() + numberText.getText());
				numberText.setText("");
			}
			
			s=expressText.getText();
			char ch[] = s.toCharArray();
			int length = s.length() - 1;
			/*
			 * 只有前面是数字的时候且左括
			 * 号的数量大于右括号的数量的时候才能加右括号
			 */
			if(Character.isDigit(ch[length]) && leftNum > rightNum)  {
				rightNum++;
				expressText.setText(expressText.getText() + ')');
			}
			
		}
		
		
		
		/*
        *当按钮为 C时
        *清除所有内容
        *并更新等号状态, 左括号数量, 右括号数量, 小数点状态
        *当一次计算完成之后,只有按CE按钮才能进行新的计算
        */
                    
        if(e.getSource().equals(buttonC)) {
           numberText.setText("0");
           expressText.setText("");
           leftNum = 0;
           rightNum = 0;
           pointbook = 0;
           equalbook = 0;
        }
                    
       /*
        *当按钮为CE时,
        *清除当前数字框中内容   
        *更新小数点状态
        */
        if(e.getSource().equals(buttonCE)) {
           numberText.setText("0");
           pointbook = 0;   
        }
        
        //当按钮为1/x时把输入框中的值变为倒数     
        if(e.getSource().equals(buttoninvert) ) {
        	s = numberText.getText();
        	//等于0的时候不进行操作
        	if(s.equals("0")) {
        		
        	}else {
        		double a = Double.parseDouble(numberText.getText());
	        	a = 1/a;
	        	numberText.setText(String.valueOf(a));
        	}
        	
        }
                    
		//当按钮为等于号时
		if(e.getSource().equals(buttonequal)) {
			s=numberText.getText();
			if(!s.equals("0") && !s.equals("")) {
				expressText.setText(expressText.getText() + s);
			}
            //当等号没有出现时才能输入等号 
			if(equalbook == 0) {  
                numberText.setText("");
                //补全右括号
                for(int i = 0; i < leftNum - rightNum; i++) {
                	expressText.setText(expressText.getText() + ')');
                }
                
		        /*
		         * 声明栈
		         * 一个char型存储运算符
		         * 将中缀表达式转化为逆波兰表达式
		        */
		        String[] ansString = new String[100];
		        int Size = 0;
		        Stack<Character> Operater = new Stack<Character>();
		        
		        s = expressText.getText();
		        char ch[] = s.toCharArray();
		        int length = ch.length;
		        for(int j = 0; j < length; j++) {
		        	//当数组元素为数字时
		        	if(ch[j] >='0' && ch[j] <= '9') {
		        		double Number = ch[j] - '0';
		        		//继续往后遍历,直到不是数字和小数点
		        		//记录小数点是否出现
		        		int point = 0;
		        		//记录小数点出现后的位数
		        		int bit = 1;
		        		if(j==length-1) {
		        			ansString[Size++] = String.valueOf(Number);
		        		}
		        		for(j++; j<length; j++) {
		        			if((ch[j] < '0' || ch[j] >'9') && ch[j]!='.') {
		        				j--;
		        				ansString[Size++] = String.valueOf(Number);
		        				break;
		        			}
		        			if(ch[j] == '.') {
		        				point = 1;
		        				continue;
		        			}
		        			if(ch[j] >= '0' && ch[j] <= '9') {
		        				/*
		        				 * 当小数点没有出现时和没出现时要分开讨论
		        				 */
		        				if(point == 0) {
		        					Number = Number * 10 + (ch[j] - '0');
		        				} else {
		        					Number = Number + Math.pow(10, -bit) * (ch[j]-'0');
		        					bit++;
		        				} 
		        			}
		        		}
		        	} else { //考虑运算符
		        		if(ch[j] =='(') {
		        			Operater.push('(');
		        		} else if(ch[j]==')') {
		        			while(!Operater.peek().equals('(')) {
		        				ansString[Size++] = String.valueOf(Operater.peek());
		        				Operater.pop();
		        			}
		        			Operater.pop();
		        		} else {
		        			if(Operater.empty()) {
		        				Operater.push(ch[j]);
		        			}
		        			else {
		        				//System.out.println("!" + ch[j]);
		        			
		        				while(true) {
		        					
		        					if(Operater.empty()) {
				        				Operater.push(ch[j]);
				        				break;
				        			}
                                                                char operater1 = Operater.peek();
		        					if((ch[j] == '*' || ch[j] == '/') &&
		        					   (operater1=='+' || operater1=='-') || (operater1=='(' || operater1 == ')')) {
		        						Operater.push(ch[j]);
		        						break;
		        					}
		        					else {
		        						ansString[Size++] = String.valueOf(Operater.peek());
		        						Operater.pop();
		        					}
		        				}
		        			}
		        		}
		        	}
		        }//System.out.println(s);
		        while(!Operater.empty()) {
		        	ansString[Size++] = String.valueOf(Operater.peek());
		        	Operater.pop();
		        }
//		        for(int i=0; i<Size; i++)
//		        	System.out.println(ansString[i]);
		        //最后计算逆波兰表达式的值
		        Stack<Double> Last = new Stack<Double>();
		        for(int i=0; i<Size; i++) {
		        	String s1 = ansString[i];
		        	char ch2[] = s1.toCharArray();
		        	if(ch2[0]>='0' && ch2[0]<='9') {
		        		Last.push(Double.parseDouble(s1));
		        	}
		        	else {
		        		double num1 = Last.pop();
		        		double num2 = Last.pop();
		        		double num3 = 0;
		        		if(ch2[0]=='+') 
		        			num3 = num2 + num1;
		        		else if(ch2[0]=='-')
		        			num3 = num2 - num1;
		        		else if(ch2[0]=='*')
		        			num3 = num2 * num1;
		        		else if(ch2[0]=='/')
		        			num3 = num2 / num1;
		        		
		        		Last.push(num3);
		        	}
		        }
		        expressText.setText(expressText.getText() + "=" + Last.pop());
		        equalbook = 1;
   
            }	
         }
		
	}  
	
    public static void main(String []args) {
    	Calculator calculator = new Calculator();
    }
	 
}

 

posted @ 2019-11-08 10:53  宿星  阅读(1254)  评论(0编辑  收藏  举报