之前的文本计算器不能提示错误,并且输入错误的时候可能导致程序卡死,之前还不太会异常处理,这个版本加入了异常处理,能简单的分析错误原因,下面是源码,请多指教:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class TxtCalculator implements ActionListener
{
JFrame f;
JPanel pTxt = new JPanel();
JTextField txt;
JPanel pShow = new JPanel();
JTextArea show;
JMenu mEdit;
JMenu mView;
JMenu mHelp;
JMenuItem mSave;
JMenuItem mClear;
JMenuItem mHelpItem;
JMenuItem mAbout;
static JButton start;
String strAll[][]=new String[100][100];
public TxtCalculator()
{
f = new JFrame("文本计算器");
JMenuBar mBar = new JMenuBar();
mBar.setOpaque(true);
mEdit = new JMenu("编辑");
mSave = new JMenuItem("保存历史");
mSave.addActionListener(this);
mEdit.add(mSave);
mClear = new JMenuItem("清空历史");
mClear.addActionListener(this);
mEdit.add(mClear);
mHelp = new JMenu("帮助");
mHelpItem = new JMenuItem("帮助主题");
mHelpItem.addActionListener(this);
mHelp.add(mHelpItem);
mAbout = new JMenuItem("关于计算器");
mAbout.addActionListener(this);
mHelp.add(mAbout);
mBar.add(mEdit);
mBar.add(mHelp);
f.setJMenuBar(mBar);
txt = new JTextField();
pTxt.setLayout(new BorderLayout());
pShow.setLayout(new BorderLayout());
start = new JButton("开始计算");
start.setForeground(Color.blue);
txt.addKeyListener(new KeyListener()
{
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_ENTER)
{
System.out.println("系统管理员:用户按下了回车键");
start.doClick();
}
}
public void keyReleased(KeyEvent args) {}
public void keyTyped(KeyEvent args) {}
});
start.addActionListener(this);
show = new JTextArea("");
show.setLineWrap(true);
show.setEditable(false);
txt.requestFocus();
pTxt.add(txt,BorderLayout.CENTER);
pTxt.add(new JScrollPane(start),BorderLayout.EAST);
pShow.add(pTxt,BorderLayout.NORTH);
JScrollPane show2=new JScrollPane(show);
pShow.add(show2,BorderLayout.CENTER);
f.add(pShow);
f.setSize(new Dimension(300,270));
Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
Dimension fra=f.getSize();
f.setLocation((screenSize.width-fra.width)/2,(screenSize.height-fra.height)/2);
f.setResizable(false);
f.setVisible(true);
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.out.println("系统管理员:用户已经关闭软件!");
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
if(s.equals("保存历史"))
{
System.out.println("系统管理员:用户按下了“保存历史”菜单");
try
{
FileWriter txtWriter=new FileWriter("History.txt");
BufferedWriter writer=new BufferedWriter(txtWriter);
String S=show.getText();
S="/*文本计算器*/\r\n/*制作人:Sqrt5*/\r\n/*欢迎交流使用!*/\r\n/*E-mail:2.236068@gmail.com*/\r\n/*这是文本计算器的保存文件,可以根据您的需要在这里面保存记录*/\r\n\r\n"+S;
writer.write(S);
writer.close();
System.out.println("系统管理员:历史History.txt已经保存到CLASS文件根目录!");
JOptionPane.showMessageDialog(null,"历史History.txt已经保存到CLASS文件根目录!","提示",JOptionPane.WARNING_MESSAGE);
Runtime.getRuntime().exec("cmd /c start .\\");
}catch(IOException ee){}
}
else if(s.equals("清空历史"))
{
show.setText("");
System.out.println("系统管理员:用户按下了“清空历史”菜单");
}
else if(s.equals("帮助主题"))
{
System.out.println("系统管理员:用户按下了“帮助主题”菜单");
JOptionPane.showMessageDialog(null,"输入表达式即可,只支持有理数和括号\"(\"、\")\",输入\"help\"可以查看更多信息","帮助主题",JOptionPane.WARNING_MESSAGE);
}
else if(s.equals("关于计算器"))
{
System.out.println("系统管理员:用户按下了“关于计算器”菜单");
JOptionPane.showMessageDialog(null,"Sqrt5制作,欢迎使用","关于计算器",JOptionPane.WARNING_MESSAGE);
}
else if(s.equals("开始计算"))
{
System.out.println("系统管理员:用户按下了“开始计算”按钮");
String exp=txt.getText().trim();
if(exp.compareTo("clear")==0)
{
txt.setText("");
show.setText("");
System.out.println("系统管理员:高级用户输入了clear命令");
return;
}
if(exp.compareTo("help")==0)
{
txt.setText("");
show.append("此程序为文本计算器,输入一串公式可以根据优先级、括号等顺序计算出结果,暂时只能支持\"+\"、\"-\"、\"*\"、\"/\"四种运算,能识别括号。\r\n");
show.append("作者:\tSqrt5\r\n");
show.append("E-mail:\t2.236068@gmail.com\r\n");
show.append("此产品最终解释权为作者所有!\r\n");
show.append("简单命令提示:\r\n");
show.append("save->保存历史\t");show.append("clear->清空历史\r\n");
show.append("help->帮助\t");show.append("shutdown->关闭文本计算器\r\n");
System.out.println("系统管理员:高级用户输入了help命令");
return;
}
if(exp.compareTo("save")==0)
{
System.out.println("系统管理员:高级用户输入了save命令");
txt.setText("");
try
{
FileWriter txtWriter=new FileWriter("History.txt");
BufferedWriter writer=new BufferedWriter(txtWriter);
String S=show.getText();
S="/*文本计算器*/\r\n/*制作人:Sqrt5*/\r\n/*欢迎交流使用!*/\r\n/*E-mail:2.236068@gmail.com*/\r\n/*这是文本计算器的保存文件,可以根据您的需要在这里面保存记录*/\r\n\r\n"+S;
writer.write(S);
writer.close();
System.out.println("系统管理员:历史History.txt已经保存到CLASS文件根目录!");
show.append("历史History.txt已经保存到CLASS文件根目录!\r\n");
Runtime.getRuntime().exec("cmd /c start .\\");
}catch(IOException ee){}
return;
}
if(exp.compareTo("shutdown")==0)
{
System.out.println("系统管理员:高级用户输入了shutdown命令");
System.exit(0);
}
for(int i=0;i<exp.length()-1;i++)
{
if(exp.charAt(i)=='('&&exp.charAt(i+1)==')')
{
txt.setText("");
show.append("括号中没有内容!请重新输入!\r\n");
System.out.println("系统管理员:括号中没有内容");
return;
}
}
int count=0;
boolean isBlank=false;
for(int i=0;i<exp.length();i++)
{
if(exp.charAt(i)=='(')count++;
if(exp.charAt(i)==')')count--;
if(exp.charAt(i)==' ')
{
count=1;
isBlank=true;
}
}
if(count!=0)
{
txt.setText("");
if(isBlank)
{
show.append("公式中不能出现空格!请重新输入!\r\n");
System.out.println("系统管理员:公式中出现了空格");
}
else
{
show.append("公式中左右括号数要相等!请重新输入!\r\n");
System.out.println("系统管理员:公式中左右括号数不相等");
}
return;
}
int strLength[]=new int[1000];
for(int i=0;i<100;i++)
{
for(int j=0;j<100;j++)
{
strAll[i][j]=null;
}
}
String expBr;
expBr=SeparateAllString("#"+exp+"#",strLength);
SeparateString("#"+expBr+"#",strAll[99]);
for(int k=0;k<100;k++)
{
if(strAll[99][k]==null)
{
strLength[99]=k;
break;
}
}
txt.setText("");
if(exp.compareTo("")!=0)
{
String stemp;
stemp="";
try
{
stemp=doubleTrans(CalculatorAlgorithm(strAll[99],strLength[99]));
}
catch(Exception err)
{
txt.setText("");
show.append("公式输入错误!请重新输入!\r\n");
System.out.println("系统管理员:公式输入错误");
return;
}
if(stemp.compareTo("Infinity")==0)
{
stemp="+∞";
show.append(exp+"="+stemp+"\r\n");
System.out.println(exp+"="+stemp);
}
else if(stemp.compareTo("-Infinity")==0)
{
stemp="-∞";
show.append(exp+"="+stemp+"\r\n");
System.out.println(exp+"="+stemp);
}
else
{
show.append(exp+"="+stemp+"\r\n");
System.out.println(exp+"="+stemp);
}
}
txt.requestFocus();
}
}
String doubleTrans(double d)
{
if(Math.round(d)-d==0)
{
return String.valueOf((long)d);
}
return String.valueOf(d);
}
double CalculatorAlgorithm(String str[],int strLength) throws Exception
{
if(strLength==3)
{
double n;
n=Double.parseDouble(str[1]);
return n;
}
Stack stkNum=new Stack();
Stack stkOp=new Stack();
Stack stkNumTaken=new Stack();
Stack stkOpTaken=new Stack();
double operateNum1=0.0,operateNum2=0.0;
int pOp=0,cOp=0;
boolean LastFirst=false;
String ptempOp,ctempOp;
String FirstOp,EndOp;
int pPriority=0,cPriority=0;
for(int i=strLength-1;i>=0;i--)
{
if(str[i].charAt(str[i].length()-1)>='0'&&str[i].charAt(str[i].length()-1)<='9')
{
double n;
n=Double.parseDouble(str[i]);
stkNum.push(n);
}
else stkOp.push(str[i]+"");
}
FirstOp=(String)stkOp.pop();
while(!stkOp.empty())
{
if(!stkOpTaken.empty()&&!LastFirst)
{
operateNum1=(Double)stkNumTaken.pop();
ptempOp=(String)stkOpTaken.pop();
}
else
{
operateNum1=(Double)stkNum.pop();
ptempOp=(String)stkOp.pop();
}
if(ptempOp.compareTo("+")==0)
{
pPriority=20;
pOp=1;
}
else if(ptempOp.compareTo("-")==0)
{
pPriority=20;
pOp=2;
}
else if(ptempOp.compareTo("*")==0)
{
pPriority=50;
pOp=3;
}
else if(ptempOp.compareTo("/")==0)
{
pPriority=50;
pOp=4;
}
else if(ptempOp.compareTo("#")==0)
{
pPriority=1;
pOp=0;
}
if(!stkOpTaken.empty()&&!LastFirst)
{
operateNum2=(Double)stkNumTaken.pop();
ctempOp=(String)stkOpTaken.pop();
}
else
{
operateNum2=(Double)stkNum.pop();
ctempOp=(String)stkOp.pop();
LastFirst=false;
}
if(ctempOp.compareTo("+")==0)
{
cPriority=20;
cOp=1;
}
else if(ctempOp.compareTo("-")==0)
{
cPriority=20;
cOp=2;
}
else if(ctempOp.compareTo("*")==0)
{
cPriority=50;
cOp=3;
}
else if(ctempOp.compareTo("/")==0)
{
cPriority=50;
cOp=4;
}
else if(ctempOp.compareTo("#")==0)
{
cPriority=1;
cOp=0;
}
if(pPriority>=cPriority)
{
switch(pOp)
{
case 1:
operateNum2=operateNum1+operateNum2;break;
case 2:
operateNum2=operateNum1-operateNum2;break;
case 3:
operateNum2=operateNum1*operateNum2;break;
case 4:
operateNum2=operateNum1/operateNum2;break;
}
}
else
{
stkNumTaken.push(operateNum1);
stkOpTaken.push(ptempOp+"");
LastFirst=true;
}
stkNum.push(operateNum2);
stkOp.push(ctempOp+"");
if(stkOpTaken.empty()&&ctempOp.compareTo("#")==0)break;
}
double m=0.0;
m=(Double)stkNum.pop();
return m;
}
void SeparateString(String s,String str[])
{
int i;
int j;
boolean bSNum;
boolean bSOp;
boolean bSLFunc;
boolean bSRFunc;
boolean bSBra;
boolean bSNumF;
boolean bSOpF;
boolean bSLFuncF;
boolean bSRFuncF;
boolean bSBraF;
boolean bSEnd;
boolean bSEndF;
str[0]=""+s.charAt(0);
j=0;
for(i=1;i<s.length();i++)
{
bSEndF=(s.charAt(i-1)=='#');
bSEnd=(s.charAt(i)=='#');
bSNumF=(s.charAt(i-1)>='0'&&s.charAt(i-1)<='9')||(s.charAt(i-1)=='.')||(s.charAt(i-1)=='-');
bSNum=(s.charAt(i)>='0'&&s.charAt(i)<='9')||(s.charAt(i)=='.')||(s.charAt(i)=='-');
bSOpF=((s.charAt(i-1)=='+')||(s.charAt(i-1)=='*')||(s.charAt(i-1)=='/'));
bSOp=((s.charAt(i)=='+')||(s.charAt(i)=='*')||(s.charAt(i)=='/'));
bSLFuncF=(s.charAt(i-1)>='a'&&s.charAt(i-1)<='z');
bSLFunc=(s.charAt(i)>='a'&&s.charAt(i)<='z');
bSRFuncF=((s.charAt(i-1)=='!'));
bSRFunc=((s.charAt(i)=='!'));
bSBraF=((s.charAt(i-1)=='(')||(s.charAt(i-1)==')'));
bSBra=((s.charAt(i)=='(')||(s.charAt(i)==')'));
if(bSNumF&&bSNum)
{
if(
(s.charAt(i-1)>='0'&&s.charAt(i-1)<='9'||(s.charAt(i-1)=='.')||(s.charAt(i-1)=='-'))
&&
s.charAt(i)=='-'
&&
(s.charAt(i+1)>='0'&&s.charAt(i+1)<='9'||(s.charAt(i+1)=='.')||(s.charAt(i+1)=='-'))
)
j++;
if((s.charAt(i-2)>='0'&&s.charAt(i-2)<='9')&&s.charAt(i-1)=='-'&&(s.charAt(i)>='0'&&s.charAt(i)<='9'))
j++;
}
else if(bSOpF&&bSOp){}
else if(bSLFuncF&&bSLFunc){}
else if(bSRFuncF&&bSRFunc){}
else if(bSBraF&&bSBra){}
else if(bSEndF&&bSEnd){}
else j++;
if(str[j]!=null)str[j]=str[j]+s.charAt(i);
else str[j]=""+s.charAt(i);
}
}
String SeparateAllString(String s,int strLength[])
{
String str[]=new String[1000];
Stack stkString=new Stack();
Stack stkStringTaken=new Stack();
int i=1;
int count=1;
while(s.charAt(i)!='#')
{
stkString.push(s.charAt(i));
i++;
}
i=0;
while(count!=0)
{
count=0;
while(!stkString.empty())
{
char temp;
temp=(Character)stkString.pop();
stkStringTaken.push(temp);
if(temp==')')count++;
if(temp=='(')
{
count--;
stkStringTaken.pop();
while((Character)stkStringTaken.peek()!=')')
{
if(str[i]!=null)str[i]=str[i]+(Character)stkStringTaken.pop();
else str[i]=""+(Character)stkStringTaken.pop();
}
stkStringTaken.pop();
SeparateString("#"+str[i]+"#",strAll[i]);
for(int j=0;j<100;j++)
{
if(strAll[i][j]==null)
{
strLength[i]=j;
break;
}
}
String swap;
swap="";
try
{
swap=""+CalculatorAlgorithm(strAll[i],strLength[i]);
}
catch(Exception err)
{
txt.setText("");
show.append("不可预知错误!请重新输入!\r\n");
System.out.println("系统管理员:不可预知错误");
return "0";
}
for(int iii=swap.length()-1;iii>=0;iii--)
stkStringTaken.push(swap.charAt(iii));
i++;
}
}
while(!stkString.empty())stkString.pop();
while(!stkStringTaken.empty())
{
char swap;
swap=(Character)stkStringTaken.pop();
if(swap=='('&&swap==')')count++;
stkString.push(swap);
}
}
s="";
while(!stkString.empty())
s=(Character)stkString.pop()+s;
return s;
}
public static void main(String[] args)
{
new TxtCalculator();
}
}