java圖形化界面實現簡單混合運算計算器

碼雲地址:https://gitee.com/zhang_yi_qiang/A-simple-hybrid-calculator

寫了好幾天了終於寫完了這個四則運算計算器,總代碼放在後面

截圖如下:

首先是佈局都比較簡單,最上面的一個框是總的輸出框,

第二個框是每次輸入的數字顯示在框內,

對於每一個按鈕都增加監聽器,

 

對於數字按鈕:當長度大於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();
    }
	 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章