Calculator based on Java GUI Graphical Interface

"Implement an application based on Java GUI" - this is a big assignment of the java course on December 20 last semester. I wanted to blog when I finished it, but I didn't send it until now.

What I did for this big assignment was a calculator, which was more complicated than I expected. Calculator is not so easy to do, ha ha, really think easy to do on the muddle.

I hope it can be used for reference by students. Let's study together. If you have any questions, you can do it yourself.

If the code is too long, you can get the source code and executable file from Baidu online disk:

Link: https://pan.baidu.com/s/1KZr7PkqTpv922sCWyScs8g
Extraction code: w434

Design sketch:

Main algorithm: receive the expression input by the user on the graphical interface, cut the whole string into an array, which is an array of infix expressions. Stack technology is used to compare operator priority for infix expression, and special string (bracket) is limited to be converted into suffix expression array. Bracket operators exist in infix expression array. When converting to suffix expression, all bracket operators must be deleted. The suffix expression does not need brackets, and the priority already exists in the order of precedence. When the suffix expression is obtained, stack technology is also used to store and extract stack elements for calculation.

 

Interface layout: Based on GUI Graphical interface, use WindowBuilder visualization tool to absolutely locate the module layout. The interface uses buttons, text boxes, input boxes, scrollable text fields and other components. It also sets table box colors, font styles and so on.

 

Summary: This is the second attempt to do the calculator in this big job. I have also done the calculator in web version before, but I didn't know infix expression, suffix expression and stack technology at that time. It can be said that these are the core methods to complete the calculator. The calculator took three nights to complete and two nights to conduct BUG test. Basically, there is no BUG now. The biggest difficulty to complete the calculator lies in the two methods of converting infix expression to suffix expression and calculating the result with suffix expression. These two methods are also the core code of calculator. The standard calculator that comes with the computer is without bracket operator, but it has the function of cumulative calculation. The effect of cumulative calculation is not difficult. At the beginning of the calculation, I also made a cumulative calculation. Later, I improved and added bracket operation to remove the cumulative calculation. With parenthesis, the difficulty of calculator is increased again. Because in infix expression to suffix expression, I need to judge the priority inside and outside the brackets. After comparison, I can't pass the bracket operator into the suffix expression, because the suffix expression doesn't need brackets. Compared with the standard calculator that comes with the computer, the standard calculator actually has two display expressions, one is the display input, the other is the total expression, and I only have one display expression, so there are some limitations in the input of operators and values. For example: you can't enter a negative sign directly. You have to enter zero minus a number. I have made a lot of input restrictions for the standardization of user input. For example, there cannot be two or more connected operators, the decimal point of a value cannot be dotted again, the number of right parentheses must be the same as that of left parentheses, etc., which are written in the code logic, so as to give users a better sense of experience and prevent the error of incoming data. Of course, if the user ends the expression with the addition, subtraction, multiplication and division operator and presses the equal directly, or if the closing bracket is missing, it's OK, and it won't affect. In general, the harvest of making calculators is still great.

Class with:

Calculator class: GUI Graphical interface implementation class, which implements the overall layout of the calculator, and calls the StackToCalculator class to return content. It contains the internal class ButtonHandler that implements the listening function and the method used for initialization (doInit()).

StackToCalculator class: the main algorithm implementation class of calculator. Among them, string to array method (toArr(String text)), infix expression to suffix expression method (ToSuffix(String[] textArray)), method to determine whether it is a numeric value (isNum(char strNum), isNum(String strNum)), method to compare the precedence of operators (tocampare (string) STR1) and finally the method of stack calculation using suffix expression (tocalcultitor (string CText)).

 

Upper Code:

package work7;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.JLabel;

/** 
* @author YoungIT
* @version 2019 December 18, 2014 11:12:14 PM 
* @tips Calculator
*/ 
public class Cacultor extends JFrame {

	private JPanel contentPane;
	private JTextArea textArea;
	private JButton btnNewButton,btnNewButton_1,btnNewButton_2,btnNewButton_3,
	btnNewButton_4,btnNewButton_5,btnNewButton_6,btnNewButton_7,button,button_1,
	button_2,button_3,button_4,button_5,button_6,button_7,
	button_8,button_9,button_10,button_11,button_12;
	private String textA = "";
	private String cString = "";
	private JTextField textField;
	private int count = 0;//"+-x/"
	private int cleft = 0;//Mark "(") ".
	private int cright = 0;//Mark ""
	private int point = 0;//Mark "."
	private int cnum = 0;//Tag number
	private int flag = 0;//1-number, 2-operator, 3-point, 4-left surround, 5-right surround
	private int fsum = 0;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Cacultor frame = new Cacultor();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public Cacultor() {
		super("Super intelligent calculator");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(700, 500, 620, 430);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(null);
		setContentPane(contentPane);
		
		btnNewButton = new JButton("C");
		btnNewButton.setBounds(10, 78, 83, 44);
		contentPane.add(btnNewButton);
		
		btnNewButton_1 = new JButton(".");
		btnNewButton_1.setBounds(92, 78, 83, 44);
		contentPane.add(btnNewButton_1);
		
		btnNewButton_3 = new JButton("BackSace");
		btnNewButton_3.setBounds(174, 78, 200, 44);
		contentPane.add(btnNewButton_3);
		
		btnNewButton_4 = new JButton("7");
		btnNewButton_4.setBounds(10, 129, 83, 44);
		contentPane.add(btnNewButton_4);
		
		btnNewButton_5 = new JButton("8");
		btnNewButton_5.setBounds(92, 129, 83, 44);
		contentPane.add(btnNewButton_5);
		
		btnNewButton_6 = new JButton("9");
		btnNewButton_6.setBounds(174, 129, 83, 44);
		contentPane.add(btnNewButton_6);
		
		btnNewButton_7 = new JButton("+");
		btnNewButton_7.setBounds(256, 129, 118, 44);
		contentPane.add(btnNewButton_7);
		
		button = new JButton("4");
		button.setBounds(10, 182, 83, 44);
		contentPane.add(button);
		
		button_1 = new JButton("5");
		button_1.setBounds(92, 182, 83, 44);
		contentPane.add(button_1);
		
		button_2 = new JButton("6");
		button_2.setBounds(174, 182, 83, 44);
		contentPane.add(button_2);
		
		button_3 = new JButton("1");
		button_3.setBounds(10, 236, 83, 44);
		contentPane.add(button_3);
		
		button_4 = new JButton("2");
		button_4.setBounds(92, 236, 83, 44);
		contentPane.add(button_4);
		
		button_5 = new JButton("3");
		button_5.setBounds(174, 236, 83, 44);
		contentPane.add(button_5);
		
		button_6 = new JButton("(");
		button_6.setBounds(10, 288, 83, 44);
		contentPane.add(button_6);
		
		button_7 = new JButton("0");
		button_7.setBounds(92, 288, 83, 44);
		contentPane.add(button_7);
		
		button_8 = new JButton(")");
		button_8.setBounds(174, 288, 83, 44);
		contentPane.add(button_8);
		
		button_9 = new JButton("-");
		button_9.setBounds(256, 182, 118, 44);
		contentPane.add(button_9);
		
		button_10 = new JButton("x");
		button_10.setBounds(256, 236, 118, 44);
		contentPane.add(button_10);
		
		button_11 = new JButton("/");
		button_11.setBounds(256, 288, 118, 44);
		contentPane.add(button_11);
		
		button_12 = new JButton("=");
		button_12.setBounds(10, 337, 364, 44);
		contentPane.add(button_12);
		
		textField = new JTextField();
		textField.setBounds(10, 10, 364, 44);
		textField.setEditable(false);
		textField.setFont(new Font("Hua Wencaiyun",Font.BOLD, 18));
		textField.setHorizontalAlignment(JTextField.RIGHT);
		contentPane.add(textField);
		textField.setColumns(10);
		
		JLabel lblByYoungit = new JLabel("by: YoungIT");
		lblByYoungit.setBounds(309, 56, 75, 22);
		contentPane.add(lblByYoungit);
		
		textArea = new JTextArea();
		textArea.setBounds(380, 10, 194, 371);
		textArea.setEditable(false);
		textArea.setLineWrap(true);
		textArea.setFont(new Font("Hua Wencaiyun",Font.BOLD, 18));
		Color b = new Color(194,214,233);
		Color c = new Color(238,238,238);
		textArea.setBackground(c);
		textArea.setBorder(BorderFactory.createMatteBorder(2,2,2,2,b));
		JScrollPane scrollpane = new JScrollPane(textArea);
//		scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollpane.setBounds(384, 10, 210, 371);
		contentPane.add(scrollpane);
		
		ButtonHandler handler = new ButtonHandler();
		button.addActionListener(handler);
		button_1.addActionListener(handler);
		button_2.addActionListener(handler);
		button_3.addActionListener(handler);
		button_4.addActionListener(handler);
		button_5.addActionListener(handler);
		button_6.addActionListener(handler);
		button_7.addActionListener(handler);
		button_8.addActionListener(handler);
		button_9.addActionListener(handler);
		button_10.addActionListener(handler);
		button_11.addActionListener(handler);
		button_12.addActionListener(handler);
		btnNewButton.addActionListener(handler);
		btnNewButton_1.addActionListener(handler);
		btnNewButton_3.addActionListener(handler);
		btnNewButton_4.addActionListener(handler);
		btnNewButton_5.addActionListener(handler);
		btnNewButton_6.addActionListener(handler);
		btnNewButton_7.addActionListener(handler);
	}
	
	public void doInit() {
		textA = "";
		textField.setText(textA);
		count = 0;//"+-x/"
		cleft = 0;//Mark "(") ".
		cright = 0;//Mark ""
		point = 0;//Mark "."
		cnum = 0;//Tag number
		flag = 0;
		fsum = 0;
	}
	
	private class ButtonHandler implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			String Ename = e.getActionCommand();
			switch (Ename) {
			case "C":
				doInit();
				break;
			case "BackSace":
				if(fsum==1) {
					doInit();
				}
				try {
					if(textA.length()>0) {
						String laString = textA.substring(textA.length() - 1);
						if(laString.equals(")")) {
							cleft++;
						}else if(laString.equals("0")) {
							cnum = 0;
						}
						textA = textA.isEmpty()?"":textA.substring(0,textA.length() - 1);
						textField.setText(textA);
					
						char c = textA.charAt(textA.length()-1);
							switch (c) {
							case '0':
							case '1':
							case '2':
							case '3':
							case '4':
							case '5':
							case '6':
							case '7':
							case '8':
							case '9':
								flag = 1;break;
							case '+':
							case '-':
							case 'x':
							case '/':
								flag = 2;break;
							case '.':
								flag = 3;break;
							case '(':
								flag = 4;break;
							case ')':
								flag = 5;
								break;
							default:
								break;
							}
					}
				}catch (Exception e2) {
					System.err.println("Don't delete it~No more content!");
				}
				break;
			case "0":
				if(fsum==1) {
					doInit();
				}
				if(flag == 2 || flag == 0){//1-number, 2-operator, 3-point, 4-left surround, 5-right surround
					cnum = 1;
					textA = textA + Ename;
					textField.setText(textA);
					flag = 1;
				}else if(flag == 1 || flag == 3|| flag == 4) {
					textA = textA + Ename;
					textField.setText(textA);
					flag = 1;
				}
				break;
			case "1":
			case "2":
			case "3":
			case "4":
			case "5":
			case "6":
			case "7":
			case "8":
			case "9"://No number can be entered after (right)
				if(fsum==1) {
					doInit();
				}
				if(flag != 5&&cnum == 0){//1-number, 2-operator, 3-point, 4-left surround, 5-right surround
					textA = textA + Ename;
					textField.setText(textA);
					flag = 1;
				}
				break;
			case "+":
			case "-":
			case "x":
			case "/"://Cannot enter: null, (,, operator
				if(fsum==1) {
					doInit();
					break;
				}
				if(flag == 1||flag == 5){//0-null, 1-number, 2-operator, 3-point, 4-left surround, 5-right surround
					textA = textA + Ename;
//					count = 1;//+-x/
					point = 0;
					cnum = 0;
					textField.setText(textA);
					flag = 2;
				}
				break;
			case "."://The front can only be numbers
				if(fsum==1) {
					doInit();
					break;
				}
				if(flag == 1&&point == 0) {
					textA = textA + Ename;
					point = 1;//Mark.
					textField.setText(textA);
					cnum = 0;
					flag = 3;
				}
				break;
			case "("://Cannot enter: (,),, number
				if(fsum==1) {
					doInit();
				}
				if(flag == 0 || flag == 2) {//Air transport operator
					textA = textA + Ename;
					cleft++;
//					cright = 0;
					textField.setText(textA);
					flag = 4;
				}
				System.out.println("cleft:"+cleft);
				break;
			case ")"://Cannot enter: (,, operator, empty
				if(fsum==1) {
					doInit();
					break;
				}
				if(((flag == 1 || flag == 4) && cleft > 0)||(flag == 5 && cleft > 0)) {//Number right parenthesis
					textA = textA + Ename;
//					cright = 0;
					cleft--;
					textField.setText(textA);
					flag = 5;
				}
				System.out.println("cleft2:"+cleft);
				break;
			case "=":
				if(fsum==1) {
					doInit();
					break;
				}
				try {
					System.out.println("****************************");
					System.out.println("Expression entered:"+textA);
					StackToCacultor stackToCacultor = new StackToCacultor();
					String lastStr = String.valueOf(textA.charAt(textA.length()-1));
					if(!stackToCacultor.isNum(lastStr)&&!lastStr.equals(")")) {//Delete last bit operator
						textA = textA.isEmpty()?"":textA.substring(0, textA.length() - 1);
					}
					int i = 0,ckey = 0;
					char c; 
					while (i<textA.length()) {//To make up for)
						c = textA.charAt(i);
						if(c=='(') {
							ckey++;
						}else if(c==')') {
							ckey--;
						}
						i++;
					}
					if(ckey > 0) {
						for(int j=0;j<ckey;j++) {
							textA = textA+")";
						}
					}
					System.out.println("Expression passed in for evaluation:"+textA);
					cString += textA;
					String text2 =  String.valueOf(stackToCacultor.ToCacultor(textA));
					textField.setText(text2);
					cString += " = "+text2 + '\n'+"******************"+ '\n';
					textArea.setText(cString);
					textA = text2;
					fsum = 1;
				}catch (Exception e2) {
					System.err.println("Please input!");
				}
					break;
			default:
				break;
			}
		}
	}
}
package work7;

import java.util.Stack;
import java.util.Vector;

/** 
* @author YoungIT
* @version 2019 1:01:18 PM, December 18, 2010 
* @tips Use stack calculation
*/ 
public class StackToCacultor{
	private static String[] textArr = new String[50];
	private static String[] textArr2 = new String[50];
	private final static int sizeofSum = 2;//priority
	private final static int sizeofSub = 2;
	private final static int sizeofMul = 3;
	private final static int sizeofDiv = 3;
	private final static int sizeofLbra = 1;
	private final static int sizeofRbra = 0;
	
	public StackToCacultor() {
		for(int i = 0; i<textArr.length; i++) {
			textArr[i] = null;
			textArr2[i] = null;
		}
	}
	//Final calculation
	public static double ToCacultor(String Ctext) {
		int numkey = 0;
		int strkey = 0;
		String[] strArr = ToSuffix(toArr(Ctext));
		Stack<String> stack = new Stack<String>();
		double sum = 0;
		try {
			for(int i=0;i<strArr.length-1;i++) {
				numkey = 0;
				strkey = 0;
				if(strArr[i]==null) {
					while(!stack.isEmpty()) {
						String top = stack.pop();
						if(isNum(top)) {
							sum = Double.parseDouble(top);//*********//						
						}
					}
					break;
				}	// 2x(3+2)
				System.out.println("ToCacultor-Suffix:"+strArr[i]);
				if(stack.empty()) {
					stack.push(strArr[i]);
				}else {
					for (String x : stack) { 
	                    if(isNum(x)) {
	                    	numkey++;
	                    }else {
	                    	strkey++;
	                    }
					}
					if(isNum(strArr[i])) {
						if(numkey==1&&strkey==1) {
							String str = stack.pop();
							double num3 = Double.parseDouble(stack.pop());
							double s2 = Double.parseDouble(strArr[i]);
							double sum2 = 0;
							switch (str) {
							case "+":
								sum2 = num3 + s2;
								break;
							case "-":
								sum2 = num3 - s2;
								break;
							case "x":
								sum2 = num3 * s2;
								break;
							case "/":
								sum2 = num3 / s2;
								break;
							}
							stack.push(String.valueOf(sum2));
						}else {
							stack.push(String.valueOf(strArr[i]));
						}
					}else {
						if(numkey>=2) {
							double num1 = Double.parseDouble(stack.pop());
							double num2 = Double.parseDouble(stack.pop());
							double s = 0;
							switch (strArr[i]) {
								case "+":
									s = num2 + num1;
									break;
								case "-":
									s = num2 - num1;
									break;
								case "x":
									s = num2 * num1;
									break;
								case "/":
									s = num2 / num1;
									break;
							}
							stack.push(String.valueOf(s));
						}else {
							stack.push(String.valueOf(strArr[i]));
						}
					}
				}
			}
		}catch (Exception e) {
			System.err.println("Calculation error! Please restart.~");
		}
		System.out.println("Calculation results:"+sum);
		return sum;

		
	}

	//Character to array
	public static String[] toArr(String text) {
		int i = 0,j = 0;
		char c;
		while (i<text.length()) {
			c = text.charAt(i);
			if(c=='('||c==')'||c =='+'||c =='-'||c =='x'||c =='/') {
				textArr[j++] = String.valueOf(c);
				i++;
			}else {//	number
				String num = "";
				while (true) {
					if(i>=text.length()) {
						break;
					}
					c = text.charAt(i);
					if(c==')'||c =='+'||c =='-'||c =='x'||c =='/') {
						break;
					}
					num += c;
					i++;
				}
				textArr[j++] = num;
			}
		}
		return textArr;
	}
	
	//Infix expression to suffix
	public static String[] ToSuffix(String[] textArray) {
		int k=0;
		Stack stack = new Stack();
		for(int i=0;i<textArray.length-1;i++) {
			if(textArray[i]!=null) {
				System.out.println("ToSuffix Infix:"+textArray[i]);
				int priority = ToCampare(textArray[i]);  //2x(3+2)
				if(isNum(textArray[i])) {//Read to number
					textArr2[k++] = textArray[i];
				}else {
					if(!stack.empty()) {
						if(textArray[i].equals("(")) {
							stack.push(textArray[i]);
							continue;
						}else if(textArray[i].equals(")")){
							System.out.println(String.valueOf(stack.peek()));
							while (!String.valueOf(stack.peek()).equals("(")) {
								textArr2[k++] = String.valueOf(stack.pop());
							}
							stack.pop();
							continue;
						}else if(priority>ToCampare(String.valueOf(stack.peek()))) {//Priority greater than top of stack
							stack.push(textArray[i]);
							continue;
						}else {
							while (priority<=ToCampare(String.valueOf(stack.peek()))) {
								textArr2[k++] = String.valueOf(stack.pop());
								if(stack.isEmpty()) {
									break;
								}
							}
							stack.push(textArray[i]);
							continue;
						}
					}else {
						stack.push(textArray[i]);
					}
				}
			}else {
				while (!stack.empty()) {
					textArr2[k++] = String.valueOf(stack.pop());
				}
			}
		}//for
		
		return textArr2;
	}
	
	//Number 1 or not
	public static boolean isNum(char strNum) {
		if(strNum=='1'||strNum=='2'||strNum=='3'||strNum=='4'
				||strNum=='5'||strNum=='6'||strNum=='7'
				||strNum=='8'||strNum=='9'||strNum=='0') {
			return true;
		}else {	
			return false;
		}
	}
	
	//Number 2 or not
	public static boolean isNum(String strNum) {
		if(!strNum.equals("+")&&!strNum.equals("-")&&!strNum.equals("x")
				&&!strNum.equals("/")&&!strNum.equals("(")&&!strNum.equals(")")) {
			return true;
		}else {
			return false;
		}
	}
	
	//Operator priority comparison STR1 > STR2 returns true
	public static int ToCampare(String str1) {
		int key = -1;
		switch (str1) {
		case "(":
			key = 1;
			break;
		case ")":
			key = 0;
			break;
		case "+":
		case "-":
			key = 2;
			break;
		case "x":
		case "/":
			key = 3;
			break;
		}
		return key;
	}
	
	//test
	public static void main(String[] args) {
//		String[] strings = toArr("(1222.2x231+232)/123123.23+(323.2+323)");
//		String[] strings = toArr("2x(3+2)");//10
//		String[] strings = toArr("1+1");
//		for(int i=0;i<strings.length-1;i++) {
//			if(strings[i]!=null) {
//				System.out.println(strings[i]);
//			}
//		}
//		System.out.println("  ");
//		ToSuffix(strings);
//		for(int i=0;i<textArr2.length-1;i++) {
//			if(textArr2[i]!=null) {
//				System.out.println(textArr2[i]);
//			}
//		}
//		System.out.println(ToCacultor("2x(3+2)"));
//		System.out.println(ToCacultor("1+1"));
	}
}

 

If the code is too long, you can get the source code and executable file from Baidu online disk:

Link: https://pan.baidu.com/s/1KZr7PkqTpv922sCWyScs8g
Extraction code: w434

 

Study modestly and make progress together~

Published 5 original articles, won praise 3, visited 259
Private letter follow

Tags: calculator Java

Posted on Sun, 08 Mar 2020 08:04:13 -0400 by hstraf