要求
利用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: 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;elsereturn 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();}elseflag=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]=='-') {//如果第一个字符为减号,在前面加0for(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]=='-') {//如果左括号之后为减号,在左括号之后加0for(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=pute(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();}}