Bootstrap

Java课后作业:利用Java Swing简单实现计算器

要求

利用Java Swing写一个简单的计算器界面,并完成简单的四则运算。

界面

在这里插入图片描述
任意输入一个表达式:
在这里插入图片描述

代码

import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

/** 
 * @ClassName: Calculator
 * @description: 此计算器可用于带小数点以及括号的多位数四则运算(暂不支持开方以及多种函数的计算),同时支持判断括号输入是否正确,判断分母是否为0
 * @author: KI
 * @Date: 2019年10月2日 下午8:31:36
 */

class Stack1 {                                     //为了防止进栈出栈时各种类型转换出错,特定义两个栈
    ArrayList<Double> list = new ArrayList<>();    //此为存储中间数据以及最终结果的栈
    public void push(Double o){
        list.add(o);
    }
    public int prior(char a)
    {
    	if(a=='*'||a=='/')
    		return 4;
    	else if(a=='+'||a=='-')
    		return 3;
    	else if(a=='(')
    		return 2;
    	else if(a=='#')
    		return 1;
    	else
    		return 0;
    }
    public Double getTop() {
    	Double o = list.get(list.size() - 1);
    	return o;
    }
    public Double pop(){
        Double o = list.get(list.size() - 1);
        list.remove(o);
        return o;
    }
    public void output(){
        System.out.println(list);
    }
}
class Stack2 {                                    //存储运算符的栈
    ArrayList<Character> list = new ArrayList<>();
    public void push(Character o){
        list.add(o);
    }
    public Character getTop() {
    	Character o = list.get(list.size() - 1);
    	return o;
    }
    public boolean isEmpty() {
    	if(list.isEmpty()) {
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    public Character pop(){
    	Character o = list.get(list.size() - 1);
        list.remove(o);
        return o;
    }
    public void output(){
        System.out.println(list);
    }
}
class CalculatorClass implements ActionListener{
	JFrame f;
	JPanel panel1,panel2,panel3,panel4,panel5,panel6,panel7;
	JTextArea area;;
	String []a= {"MC","7","8","9","/","sqrt","(","4","5","6","*","%",")","1","2","3","-",
			"1/x","0","+/-","M+",".","+","="};
	String []b= {"BackSpace","CE","C"};
	JButton []Button1,Button2,Button3;
	CalculatorClass() throws IOException{                //设置计算器的外观以及内容
		f=new JFrame("计算器");
		f.setLayout(new BorderLayout(0,5));
		panel1=new JPanel(new BorderLayout(0,5));
		panel1.isBackgroundSet();panel1.setBackground(Color.LIGHT_GRAY);
		panel2=new JPanel(new GridLayout(4,6,10,10));
		panel3=new JPanel(new BorderLayout());
		panel4=new JPanel(new BorderLayout(0,5));
		panel5=new JPanel();
		panel5.setLayout(new FlowLayout(FlowLayout.LEFT));
		panel5.setSize(300,20);
		panel6=new JPanel();
		panel6.setBorder(BorderFactory.createRaisedBevelBorder());
		panel6.setBackground(Color.LIGHT_GRAY);
		panel7=new JPanel(new GridLayout(1,3,7,20));
		panel3.add(BorderLayout.WEST,panel6);
		panel3.add(BorderLayout.CENTER,panel7);
		panel3.setLayout(new FlowLayout(FlowLayout.CENTER));
		f.setSize(400, 400);
		f.add(BorderLayout.CENTER,panel1);
		area=new JTextArea(2,1);
		area.setLineWrap(true);
		panel4.add(BorderLayout.CENTER,area);
		String []c= {"编辑(E)","查看(V)","帮助(H)"};
		Button3=new JButton[c.length];
		for(int i=0;i<c.length;i++) {
			Button3[i]=new JButton(c[i]);
			Button3[i].setMargin(new Insets(0,0,0,0));
			panel5.add(Button3[i]);
		}
		panel4.add(BorderLayout.NORTH,panel5);
		f.add(BorderLayout.NORTH,panel4);
		panel1.add(BorderLayout.CENTER,panel2);
		panel1.add(BorderLayout.NORTH,panel3);
		Font font=new Font("宋体",Font.BOLD,20);
		Button1=new JButton[a.length];
		Button2=new JButton[b.length];
		for(int i=0;i<a.length;i++) {
			Button1[i]=new JButton(a[i]);
			Button1[i].setMargin(new Insets(0,0,0,0));
			Button1[i].setBackground(Color.lightGray);
			if(i==0||i==4||i==6||i==10||i==12||i==16||i==18||i==22||i==23) {
				Button1[i].setForeground(Color.RED);
			}
			else {
				Button1[i].setForeground(Color.BLUE);
			}
			Button1[i].setFont(font);
			Button1[i].addActionListener(this);
			panel2.add(Button1[i]);
		}
		panel2.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
		for(int i=0;i<b.length;i++) {
			Button2[i]=new JButton(b[i]);
			Button2[i].setMargin(new Insets(0,0,0,0));
			Button2[i].setBackground(Color.lightGray);
			Button2[i].setForeground(Color.red);
			Button2[i].setSize(250, 100);
			Button2[i].setFont(font);
			Button2[i].addActionListener(this);
			panel7.add(Button2[i]);
		}
		f.setVisible(true);
	}
	boolean match(char str[])              //括号匹配函数
	{
		Stack2 s=new Stack2();
		int k,flag=1;
		Character ch,e;
		for(k=0;k<str.length&&(flag==1);k++) {
			if(str[k]!='('&&str[k]!=')') {
				continue;                                //碰到不是括号的字符,继续向下读
			}
			switch(str[k])
			{
			case '(': ch=str[k];s.push(ch);break;     //遇到左括号进栈
			case ')':
				if(!s.isEmpty()) {
					e=s.getTop();          //在栈不为空的情况下,若当前为右括号,栈顶左括号出栈
					if(e=='(') {
						ch=s.pop();
					}
					else
						flag=0;
				}
				else {
					flag=0;
				}
				break;
			}
		}
		if(flag==1&&s.isEmpty()) {
			return true;
		}
		else {
			return false;
		}
	}
	Double compute(char a2[]) {             //计算函数
		Stack1 L1=new Stack1();
		Stack2 L2=new Stack2();            //L2运算符栈,L1操作数栈
		Character z,ch,y;
		char []a=new char[50];
		char []b=new char[50];
		char[]c=new char[50];
		Arrays.fill(b, '\0');
		Arrays.fill(c, '\0');
		Arrays.fill(a, '\0');
		int i,j=0,n,k=a2.length;
		double x1,x2,x;
		L2.push('#');
		System.arraycopy(a2, 0, a, 0, a2.length);
		a[k]='#';
		System.arraycopy(a, 0, b, 0, a.length);
		if(a[0]=='-') {                                      //如果第一个字符为减号,在前面加0
			for(n=0;a[n]!='\0';n++)
				b[n+1]=a[n];
			b[0]='0';
		}
		System.arraycopy(b, 0, a, 0, b.length);
		for(i=0;a[i]!='\0';i++) {
			if(a[i]=='('&&a[i+1]=='-') {                       //如果左括号之后为减号,在左括号之后加0
				for(n=i;a[n]!='\0';n++)
					 b[n+2]=a[n+1];
				 b[i+1]='0';
			}
		}
		for(i=0;b[i]!='\0';i++)
		{
			if(b[i]>='0'&&b[i]<='9') {
				while(b[i]>='0'&&b[i]<='9'||b[i]=='.') {          //读取一个完整的操作数(包含小数点)
					c[j]=b[i];
					i++;
					j++;
				}
				char []d=new char[j];
				System.arraycopy(c, 0, d, 0, j);
				j=0;
				Double t=Double.parseDouble(new String(d));
				L1.push(t);
				Arrays.fill(c, '\0');
			}
			if(b[i]=='(') {
				Character t=b[i];
				L2.push(t);                      //遇到左括号直接进运算符栈
			}
			if(b[i]==')') {
				do {
					z=L2.pop();                  //遇到右括号,在遇到左括号之前,依次从运算符栈读取一个运算符
					try {
						switch(z)                    //并连续从操作数栈读取两个数进行运算并将结果放入操作数栈,直到遇到左括号,左括号出栈
						{
						case '+':x2=L1.pop();x1=L1.pop();L1.push(x1+x2);break;
						case '-':x2=L1.pop();x1=L1.pop();L1.push(x1-x2);break;
						case '*':x2=L1.pop();x1=L1.pop();L1.push(x1*x2);break;
						case '/':x2=L1.pop();x1=L1.pop();L1.push(x1/x2);break;
						}
					}catch(ArithmeticException e) {
						area.append("\r\n"+"\t"+"分母不能为0!!!");
					}
					z=L2.getTop();
				}while(z!='(');
				z=L2.pop();
			}
			if(b[i]=='+'||b[i]=='-'||b[i]=='/'||b[i]=='*') {  //遇到运算符,与运算符栈栈顶运算符进行优先级比较,若栈顶运算符级别低直接入栈
				ch=L2.getTop();                               //否则栈顶运算符出栈
				if(L1.prior(b[i])>L1.prior(ch)) {
					Character t=b[i];
					L2.push(t);
				}
				else {
					do {
						ch=L2.pop();
						try {
							switch(ch)
							{
							case '+':x2=L1.pop();x1=L1.pop();L1.push(x1+x2);break;
							case '-':x2=L1.pop();x1=L1.pop();L1.push(x1-x2);break;
							case '*':x2=L1.pop();x1=L1.pop();L1.push(x1*x2);break;
							case '/':x2=L1.pop();x1=L1.pop();L1.push(x1/x2);break;
							}
						}catch(ArithmeticException e) {
							area.append("\r\n"+"\t"+"分母不能为0!!!");
						}
						ch=L2.getTop();
					}while(L1.prior(ch)>=L1.prior(b[i]));
					Character t=b[i];
					L2.push(t);
				}
			}
				if(b[i]=='#') {                            //扫描到#号,运算符栈内的运算符依次出栈直至扫描到的字符为'#'为止
					y=L2.getTop();
					while(y!='#') {
						y=L2.pop();
						try {
							switch(y)                    
							{
							case '+':x2=L1.pop();x1=L1.pop();L1.push(x1+x2);break;
							case '-':x2=L1.pop();x1=L1.pop();L1.push(x1-x2);break;
							case '*':x2=L1.pop();x1=L1.pop();L1.push(x1*x2);break;
							case '/':x2=L1.pop();x1=L1.pop();L1.push(x1/x2);break;
							}
						}catch(ArithmeticException e) {
							area.append("\r\n"+"\t"+"分母不能为0!!!");
						}
						y=L2.getTop();
					}    
				}
		}
		x=L1.pop();                 //操作数栈栈顶数据即为计算结果
		return x;
	}
	public void actionPerformed(ActionEvent e) {
		for(int i=0;i<a.length;i++) {
			if(e.getActionCommand()==a[i]&&i!=0&&i!=5&&i!=11&&i!=17&&i!=19&&i!=20) {
				area.append(a[i]);
			}
			else {
				continue;
			}
		}
		if(e.getActionCommand()=="BackSpace"&&(area.getText()).length()!=0) {
			area.setText(area.getText().substring(0, area.getText().length()-1));
		}
		if(e.getActionCommand()=="C") {
			area.setText("");
		}
		if(e.getActionCommand()=="=") {
			StringBuffer a=new StringBuffer(area.getText());
			a.deleteCharAt(a.length()-1);
			if(this.match(a.toString().toCharArray())) {
				Double m=this.compute(a.toString().toCharArray());
				double result=m;
				area.append("\r\n"+"\t\t\t\t"+String.format("%.3f", result));
			}
			else {
				area.append("\r\n"+"\t"+"括号不匹配!请检查括号输入是否正确!!");
			}
		}
	}
}
public class Calculator {

	public static void main(String[] args) throws IOException {

		new CalculatorClass();

	}

}
;