界面不美观,代码很混乱。。。初学者嘛,慢慢改正
2个类:
Calculator-------主类
GetResult-------计算类
界面:
Calculator类:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class Calculator implements ActionListener {
private final int BTN_SIZEX = 50, BTN_SIZEY = 40, FRAME_SIZEX = 270, FRAME_SIZEY = 250;
private final int BTN_NUM = 1, BTN_EQUAL = 2, BTN_OTHER = 3;
private String btnName[] = { "0", ".", "±", "+", "=", "1", "2", "3", "-", "C", "4", "5", "6", "*", ")", "7",
"8", "9", "/", "(" }; // ±共19
private JFrame mainFrame;
private JButton[] btn;
private JLabel showLabel1, showLabel2;
private Queue<Object> queue;
private double result;
private String in_num = "", strLabel1;
private int lastPressed = 0;
public Calculator() {
mainFrame = new JFrame("不能再简单的Calculator"); //主体
mainFrame.setLocation((1366 - FRAME_SIZEX) / 2, (768 - FRAME_SIZEY) / 2);
mainFrame.setSize(FRAME_SIZEX, FRAME_SIZEY);
// mainFrame.setResizable(false);
mainFrame.setLayout(null);
showLabel1 = new JLabel(); //显示表达式
showLabel1.setFont(new Font(showLabel1.getFont().getName(), showLabel1.getFont().getStyle(), 16));
showLabel1.setSize(FRAME_SIZEX - 16, 20);
showLabel1.setLocation(0, 0);
mainFrame.add(showLabel1);
showLabel2 = new JLabel("0", SwingConstants.RIGHT);//显示输入
showLabel2.setFont(new Font(showLabel2.getFont().getName(), showLabel2.getFont().getStyle(), 20));
showLabel2.setSize(FRAME_SIZEX - 20, 20);
showLabel2.setLocation(0, 20);
mainFrame.add(showLabel2);
btn = new JButton[btnName.length];
for (int i = 0, y = 0; i < btnName.length; i++) {
y = i / 5 + 2;
btn[i] = new JButton(btnName[i]);
btn[i].setSize(BTN_SIZEX, BTN_SIZEY);
btn[i].setLocation(BTN_SIZEX * (i % 5), FRAME_SIZEY - BTN_SIZEY * y);
mainFrame.add(btn[i]);
btn[i].addActionListener(this);
}
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
queue = new LinkedList<Object>(); //用队列储存输入的表达式,包含double和string
}
public void actionPerformed(ActionEvent e) {
if (lastPressed == BTN_EQUAL){
//queue.removeAll(queue);
while (!queue.isEmpty())
queue.poll();
showLabel1.setText("");
}
Object o = e.getSource();
if (o == btn[0] || o == btn[5] || o == btn[6] || o == btn[7] || o == btn[10] || o == btn[11] || o == btn[12]
|| o == btn[15] || o == btn[16] || o == btn[17]) { //数字
if (lastPressed != BTN_NUM)
in_num = "";
in_num = in_num + ((JButton) o).getText();
showLabel2.setText(in_num);
lastPressed = BTN_NUM;
} else if (o == btn[1]) { //小数点
if (!in_num.contains(".")){
if (lastPressed != BTN_NUM)
in_num = "0";
in_num += '.';
showLabel2.setText(in_num);
lastPressed = BTN_NUM;
}
} else if (o == btn[2]) { //符号
if (lastPressed != BTN_NUM)
in_num = "0";
if (in_num.charAt(0) == '-')
in_num = in_num.substring(1);
else
in_num = '-' + in_num;
showLabel2.setText(in_num);
lastPressed = BTN_NUM;
} else if (o == btn[3] || o == btn[8] || o == btn[13] || o == btn[18]) { //运算符
strLabel1 = ((JButton) o).getText();
if (lastPressed == BTN_NUM) {
showLabel1.setText(showLabel1.getText() + in_num);
queue.add(Double.valueOf(in_num));
}
showLabel1.setText(showLabel1.getText() + strLabel1);
queue.add(strLabel1);
lastPressed = BTN_OTHER;
} else if (o == btn[4]) { //等号
if (lastPressed == BTN_NUM) {
showLabel1.setText(showLabel1.getText() + in_num);
queue.add(Double.valueOf(in_num));
}
GetResult gr = new GetResult(queue);
result = gr.getResult();
if (gr.hasError()){
showLabel2.setText("表达式有误!");
} else {
if (Math.round(result) - result == 0)
showLabel2.setText(String.valueOf((long) result));
else
showLabel2.setText(String.valueOf(result));
}
lastPressed = BTN_EQUAL;
} else if (o == btn[9]) { //清除
while (!queue.isEmpty())
queue.poll();
in_num = "0";
showLabel1.setText("");
showLabel2.setText("0");
lastPressed = BTN_OTHER;
} else if (o == btn[14]) { //右括号
strLabel1 = ((JButton) o).getText();
if (lastPressed == BTN_NUM) {
showLabel1.setText(showLabel1.getText() + in_num);
queue.add(Double.valueOf(in_num));
}
showLabel1.setText(showLabel1.getText() + strLabel1);
queue.add(strLabel1);
lastPressed = BTN_OTHER;
} else if (o == btn[19]) { //左括号
strLabel1 = ((JButton) o).getText();
showLabel1.setText(showLabel1.getText() + strLabel1);
queue.add(strLabel1);
lastPressed = BTN_OTHER;
}
}
public static void main(String args[]) {
// 使用Windows的界面风格
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
new Calculator();
}
}
GetResult类:
import java.util.*;
public class GetResult {
private Stack<Double> stk_num;
private Stack<Character> stk_ch;
private Queue<Object> queue;
private Queue<Object> tmpqueue;
private Object object;
private char ch;
private double num1, num2;
private boolean haserror = false;
public GetResult() {
}
public GetResult(Queue<Object> q) {
this.tmpqueue = q;
haserror = false;
stk_num = new Stack<Double>();
stk_ch = new Stack<Character>();
queue = new LinkedList<Object>();
}
public void translate() { //将中缀表达式转为后缀表达式, 存入队列queue
while (!tmpqueue.isEmpty()) {
object = tmpqueue.poll();
if (object instanceof Double) { //如果是double直接存入队列
queue.add((Double) object);
} else {
ch = ((String) object).charAt(0);
if (ch == '(') { //如果是'('存入符号栈中
stk_ch.push(ch);
} else if (ch == ')') { //如果是')'将符号栈中的元素取出存入队列,直到遇到'('
if (stk_ch.isEmpty() || !stk_ch.contains('(')){
haserror = true;
return;
}
while (stk_ch.peek().charValue() != '(') {
queue.add(stk_ch.pop());
}
stk_ch.pop();
} else { //如果是运算符
if (!stk_ch.isEmpty()) {
if (getPriority(ch) <= getPriority(stk_ch.peek().charValue())) {
while (!stk_ch.isEmpty() && getPriority(ch) <= getPriority(stk_ch.peek().charValue())) {
if (stk_ch.peek() == '(') {
break;
}
queue.add(stk_ch.pop());
}
}
}
stk_ch.push(ch);
}
}
}
while (!stk_ch.isEmpty()) { //符号栈中剩余符号加入队列
queue.add(stk_ch.pop());
}
}
public Double getResult() { //计算后缀表达式的值
Object o;
translate();
while (!queue.isEmpty() && !haserror) {
o = queue.poll();
if (o instanceof Double) {
stk_num.push((Double) o);
} else {
if ((char) o == '(' || (char) o == ')') //后缀表达式中有括号,说明表达式有误
haserror = true;
else
calculate((char) o);
}
}
if (!haserror && stk_num.size() >= 2) //数字栈中还有元素
haserror = true;
if (stk_num.isEmpty())
return 0.0;
return stk_num.peek();
}
public void calculate(char c) { //一次计算
if (stk_num.size() < 2) { //队列中有运算符,数字栈少于2个数字,说明表达式有误
haserror = true;
return;
}
num2 = stk_num.pop();
num1 = stk_num.pop();
switch (c) {
case '+':
num1 += num2;
break;
case '-':
num1 -= num2;
break;
case '*':
num1 *= num2;
break;
case '/':
num1 /= num2;
break;
}
stk_num.push(num1); //计算完成存入数字栈
}
public int getPriority(char c) { //获取运算符的优先级
if (c == ')')
return 0;
else if (c == '+' || c == '-')
return 1;
else if (c == '*' || c == '/')
return 2;
else if (c == '(')
return 3;
else
return 4;
}
public boolean hasError(){
return haserror;
}
public void printQueue() { //打印当前队列,测试用
System.out.print("the queue: ");
while (!queue.isEmpty()) {
System.out.print(queue.poll() + " ");
}
System.out.println();
}
}