要求
利用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();
}
}