import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.math.BigDecimal;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
abstract class CalculatorMachine{
static int priority(char c){
switch(c){
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case '^':
return 3;
case '=':
default:
return 0;
}
}
static private String toSuffix(String str) throws
Exception{
StringBuffer strBuf = new StringBuffer();
Stack stack = new
Stack();
stack.push('=');
int i = 0;
char ch = str.charAt(i);
if(str==null||str==""||("=").equals(str))
throw new Exception("输入不正确");
if(str.charAt(str.length()-1) != '=')
throw new Exception("不能以=号结尾");
if(ch=='.')
throw new Exception("不能以.开头");
while(ch != '='){
if(ch == ' ')
ch = str.charAt(++i);
else if(ch == '+'|| ch == '-'|| ch =='*'|| ch == '/'|| ch ==
'%'|| ch == '^'){
char temp = stack.peek();
while(priority(temp) >= priority(ch)){
strBuf.append(temp);
stack.pop();
temp = stack.peek();
}
stack.push(ch);
ch = str.charAt(++i);
// if(ch == '+'|| ch == '-'|| ch =='*'|| ch == '/'|| ch ==
'%'|| ch == '^'||ch == '.')
// throw new Exception("输入字符不正确");
//
}else{
if(!((ch >=
'0'&& ch <= '9')||
ch == '.'))
throw new Exception("非法字符");
while((ch >=
'0'&& ch <= '9')||
ch == '.'){
strBuf.append(ch);
ch = str.charAt(++i);
}
strBuf.append(' ');
}
}
ch = stack.pop();
while(ch != '='){
strBuf.append(ch);
ch = stack.pop();
}
strBuf.append('=');
return strBuf.toString();
}
static private BigDecimal runSuffix(String str) throws
Exception{
// System.out.println(str);
Stack stack = new
Stack();
BigDecimal num1,num2;
StringBuffer strBuf;
int i = 0;
while(str.charAt(i) != '='){
strBuf = new StringBuffer();
if(str.charAt(i) >=
'0'&& str.charAt(i)
<= '9'){
while((str.charAt(i) >=
'0'&& str.charAt(i)
<= '9')|| str.charAt(i) == '.'){
strBuf.append(str.charAt(i++));
}
try{
stack.push(new BigDecimal(strBuf.toString()));
}catch(Exception e){
throw new Exception("计算出错");
}
}else if(str.charAt(i) == ' '){
i++;
}else if(str.charAt(i) == '+'){
if(stack.size()<2)
throw new Exception("缺少计算数");
num1 = stack.pop();
num2 = stack.pop();
stack.push(num1.add(num2));
i++;
}else if(str.charAt(i) == '-'){
if(stack.size()<2)
throw new Exception("缺少计算数");
num1 = stack.pop();
num2 = stack.pop();
stack.push(num2.subtract(num1));
i++;
}else if(str.charAt(i) == '*'){
if(stack.size()<2)
throw new Exception("缺少计算数");
num1 = stack.pop();
num2 = stack.pop();
stack.push(num1.multiply(num2));
i++;
}else if(str.charAt(i) == '/'){
if(stack.size()<2)
throw new Exception("缺少计算数");
num1 = stack.pop();
num2 = stack.pop();
stack.push(num2.divide(num1));
i++;
}else if(str.charAt(i) == '%'){
if(stack.size()<2)
throw new Exception("缺少计算数");
num1 = stack.pop();
num2 = stack.pop();
stack.push(num2.remainder(num1));
i++;
}else if(str.charAt(i) == '^'){
if(stack.size()<2)
throw new Exception("缺少计算数");
num1 = stack.pop();
num2 = stack.pop();
stack.push(num2.pow(num1.intValue()));
i++;
}
}
if(stack.size() != 1)
throw new Exception("缺少计算数");
// System.out.println("++++++++++++++++");
// System.out.println(stack.pop());
return stack.pop();
}
static public BigDecimal run(String str) throws
Exception{
String ss = toSuffix(str);
// System.out.println(ss);
// System.out.println(runSuffix(str));
return runSuffix(ss);
}
}
public class Calculator implements
ActionListener,KeyListener{
private JFrame jf;
private JTextField jtf;
private JButton[] jb;
private JPanel jp;
private StringBuffer strBuf;
public Calculator(){
jf = new JFrame("计算器");
jtf = new JTextField("0");
jb = new JButton[20];
jp = new JPanel();
strBuf = new StringBuffer();
GridLayout gl = new GridLayout(5,4,2,2);
jp.setLayout(gl);
jtf.setEditable(false);
jtf.setHorizontalAlignment(jtf.RIGHT);
gl.setHgap(5);
gl.setVgap(5);
init();
}
public void init(){
String str = "7 8 9 + 4 5 6 - 1 2 3 * 0 % .
/ ^ DEL CLR =";
StringTokenizer strt = new StringTokenizer(str," ");
for (int i = 0; i < 20; i++) {
jb[i] = new JButton(strt.nextToken());
jp.add(jb[i]);
}
for (int i = 0; i < 20; i++) {
jb[i].addActionListener(this);
jb[i].addKeyListener(this);
}
jtf.addKeyListener(this);
jf.add(jtf,BorderLayout.NORTH);
jf.add(jp,BorderLayout.CENTER);
}
public void showMe(){
jf.setVisible(true);
jf.setResizable(false);
jf.setSize(350, 300);
jf.setLocation(350, 300);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void run() throws Exception{
strBuf.append('=');
try {
String stemp = strBuf.toString();
jtf.setText(strBuf.append(stemp=(CalculatorMachine.run(strBuf.toString())).toString()).toString());
strBuf.setLength(0);
strBuf.append(stemp);
System.out.println(stemp);
} catch (Exception e) {
if(e.getMessage() == null || e.getMessage().equals(""))
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == jb[19]){//计算=
try {
run();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else if(e.getSource() == jb[17]){//DEL
strBuf.setLength(strBuf.length()>0?strBuf.length()-1:0);
jtf.setText(strBuf.toString());
}else if(e.getSource() == jb[18]){//CLR
strBuf.setLength(0);
jtf.setText("0.");
}else{
jtf.setText(strBuf.append(((JButton)e.getSource()).getText()).toString());
}
}
@Override
public void keyPressed(KeyEvent e) {
if((e.getKeyChar() >=
'0'&&e.getKeyChar()
<= '9')|| e.getKeyChar() == '.'||e.getKeyChar() ==
'+'
||e.getKeyChar() == '-'||e.getKeyChar() == '*'||e.getKeyChar()
== '/'||e.getKeyChar() == '%'
|| e.getKeyChar() == '^'){
jtf.setText(strBuf.append(e.getKeyChar()).toString());
}else if(e.getKeyChar() == KeyEvent.VK_ENTER || e.getKeyChar()
== '='){
try {
run();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else if(e.getKeyChar() == KeyEvent.VK_SPACE){
strBuf.setLength(strBuf.length()>0?strBuf.length()-1:0);
jtf.setText(strBuf.toString());
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
new Calculator().showMe();
}
}