您的位置:首页 > 编程语言 > Java开发

Java简单计算器

2014-12-09 23:33 417 查看
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class CalculatorFrame extends JFrame implements ActionListener // throws NullPointerException
{
private static final long serialVersionUID = -2769614160013503222L;
private JTextField tf = new JTextField(); // 创建文本框tf
private Calculator calculator = new Calculator();

public CalculatorFrame() throws HeadlessException {
JPanel pan = new JPanel(); // 创建一个面板对象pan
GridLayout grid = new GridLayout(5, 4); // 创建6行4列的页面布局
// 对面板pan和文本框tf的一些设置
pan.setLayout(grid);
tf.setBounds(35, 15, 250, 25);
pan.setBounds(35, 50, 250, 150);
tf.setBackground(Color.CYAN);
tf.setHorizontalAlignment(JTextField.RIGHT);

String[][] btnArray = { { "1", "2", "3", "+" }, { "4", "5", "6", "-" }, { "7", "8", "9", "*" },
{ "0", ".", "", "/" }, { "AC", "%", "←", "=" } };
for (int i = 0; i < btnArray.length; i++) {
for (int j = 0; j < btnArray[i].length; j++) {
JButton btn = new JButton(btnArray[i][j]);
// 编辑bp的监听事件源为本窗口
btn.addActionListener(this);
// 将按钮添加到面板pan中
pan.add(btn);
}
}

// 添加面板pan和文本框tf到窗口frm
this.add(tf);
this.add(pan);
// 关于窗口frm的一些设置
this.setTitle("计算器");
this.setLayout(null); // 取消窗口的布局管理
this.setSize(325, 250);
this.setResizable(false); // 设置窗口的大小为不可变
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);

}

public static void main(String[] args) throws NullPointerException {
new CalculatorFrame();
}

@Override
public void actionPerformed(ActionEvent e) {
JButton but = (JButton) e.getSource();
String text = but.getText();
String content = tf.getText();
if ("←".equals(text)) {
if (content != null && content.length() >= 1) {
tf.setText(content.substring(0, content.length() - 1));
}
} else if ("=".equals(text)) {
Double value = calculator.calculator(content);
if (value != null)
tf.setText(String.valueOf(value));
} else if ("AC".equals(text)) {
tf.setText("");
} else {
tf.setText(content + text);
}
}

private class Calculator {
// 定义操作符的优先级别
private Map<String, Integer> operatorPriority = new HashMap<String, Integer>();

public Calculator() {
super();
// 设置操作符优先级,数越大优先级越高
operatorPriority.put("+", 1);
operatorPriority.put("-", 1);
operatorPriority.put("*", 2);
operatorPriority.put("/", 2);
operatorPriority.put("%", 2);
operatorPriority.put("(", 3);
operatorPriority.put(")", 3);
}

/**
* 计算算术表达式
*
* @param str
*            算术表达式
* @return 结果
*/
public Double calculator(String str)// 科学计算
{
if (str == null || "".equals(str))
return null;

List<String> numList = getStringList(str);// 拆分操作符与操作数
numList = getPostOrder(numList); // 中缀变后缀
Stack<Double> stack = new Stack<Double>();// 结果栈
for (int i = 0; i < numList.size(); i++) {
String temp = numList.get(i);
if (Character.isDigit(temp.charAt(0))) {// 如果是数字
stack.push(Double.valueOf(temp));
} else {
Double back = stack.pop();
Double front = stack.pop();
Double res = 0d;
switch (temp.charAt(0)) {
case '+':
res = front + back;
break;
case '-':
res = front - back;
break;
case '*':
res = front * back;
break;
case '/':
res = front / back;
break;
case '%':
res = front % back;
break;
}
stack.push(res);
}
}
return stack.pop();
}

/**
* 将中缀表达式转换到后缀表达式
*
* <pre>
* 	平时所用的标准四则运算表达式,即"9+(3-1)*3+10/2"叫做中缀表达式。因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化;
*  中缀表达式“9+(3-1)*3+10/2”转化为后缀表达式“9 3 1-3*+ 10 2/+”
*
*  规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;
*  	若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,
*  	一直到最终输出后缀表达式为止。
* </pre>
*
* 参见链接:<a
* href="http://www.nowamagic.net/librarys/veda/detail/2307">http://www.nowamagic.net/librarys/veda/detail
* /2307</a>
*
* @param postOrder
* @return
*/
public List<String> getPostOrder(List<String> inOrderList) {

ArrayList<String> result = new ArrayList<String>();// 结果列表
Stack<String> stack = new Stack<String>();// 操作符栈
for (int i = 0; i < inOrderList.size(); i++) {
String str = inOrderList.get(i);
// 判断当前是不是数字
if (Character.isDigit(str.charAt(0))) {
result.add(inOrderList.get(i));// 是数字直接添加
} else {
// 如果是操作符
switch (str.charAt(0)) {
case '(':
stack.push(str);// 往操作符栈中添加
break;
case ')':
while (!stack.peek().equals("(")) {
result.add(stack.pop());
}
stack.pop();
break;
default:
// 其他操作符
while (!stack.isEmpty() && compare(stack.peek(), str) >= 0) {
result.add(stack.pop());
}
stack.push(inOrderList.get(i));
break;
}
}
}
while (!stack.isEmpty()) {
result.add(stack.pop());
}
return result;
}

/**
* 将字符串转换成由操作符和操作数组成的字符串数组
*
* @param str
*            算数运算表达式
* @return
*/
private List<String> getStringList(String str) {
// 数字临时变量
StringBuffer sb = new StringBuffer();
// 将字符串转成操作数与操作符数组
List<String> numList = new ArrayList<String>();
for (char c : str.toCharArray()) {
// 空白字符 继续循环
if (Character.isWhitespace(c)) {
continue;
}
// 如果是数字或者点号
if (Character.isDigit(c) || '.' == c) {
sb.append(c);
} else {
numList.add(sb.toString());// 将数字添加到列表中
sb.setLength(0);// 清空数字临时变量
numList.add(String.valueOf(c));// 将操作符添加到列表中
}
}
numList.add(sb.toString());
return numList;
}

/**
* 比较运算符等级 ,
*
* <pre>
*  如果operator1 > operator2 返回 正数,
*  如果operator1 < operator2 返回 负数,
*  如果operator1 = operator2 返回 零
* </pre>
*
* @param operator1
*            操作符
* @param operator2
*            操作符
* @return
*/

public int compare(String operator1, String operator2) {
return operatorPriority.get(operator1) - operatorPriority.get(operator2);
}
}

}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 计算器 布局