java-swing编程,实现计算器——支持四则运算
package cal; import java.awt.Color; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextArea; public class CalFrame extends JFrame { //配色 private final static Color OP_COLOR = new Color(251, 150, 110); private final static Color NUM_COLOR = new Color(36, 147, 190); private final static Color EQUAL_COLOR = new Color(239, 187, 36); private final static Color CLR_COLOR = new Color(50, 252, 75); private final static Color DEL_COLOR = new Color(0, 152, 120); private final static Font FONT1 = new Font("黑体", Font.BOLD, 20); private final static Font FONT2 = new Font("微软雅黑", Font.PLAIN, 20); private final static Font FONT3 = new Font("微软雅黑", Font.PLAIN, 15); private JButton num0 = new JButton("0"); private JButton num1 = new JButton("1"); private JButton num2 = new JButton("2"); private JButton num3 = new JButton("3"); private JButton num4 = new JButton("4"); private JButton num5 = new JButton("5"); private JButton num6 = new JButton("6"); private JButton num7 = new JButton("7"); private JButton num8 = new JButton("8"); private JButton num9 = new JButton("9"); private JButton decimalPoint = new JButton("."); private JButton addButton = new JButton("+"); private JButton minusButton = new JButton("-"); private JButton mulButton = new JButton("X"); private JButton divButton = new JButton("÷"); private JButton equalButton = new JButton("="); private JButton leftBracket = new JButton("("); private JButton rightBracket = new JButton(")"); private JButton clearButton = new JButton("Clear"); private JButton deleteButton = new JButton("Del"); private JLabel equationLabel = new JLabel("算式"); private JLabel resultLabel = new JLabel("结果"); private JTextArea equation = new JTextArea(2,30); private JTextArea result = new JTextArea(1,30); private JPanel jp1 = new JPanel(); private JPanel jp2 = new JPanel(); public CalFrame () { equation.setEditable(false); result.setEditable(false); //颜色,字体设置 colorAndFontSettings(); //添加动作 actionSettings(); //设置各个组成部分的位置 positionSettings(); //其他设置 setLayout( new GridLayout(2,1)); add(jp1); add(jp2); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); setTitle("QiaoCalculator v2.3"); setSize(500, 400); setLocation(200, 200); setVisible(true); } public static void main ( String[] args ) { new CalFrame(); } private void colorAndFontSettings () { equationLabel.setFont(FONT2); resultLabel.setFont(FONT2); equation.setFont(FONT3); result.setFont(FONT3); num0.setBackground(NUM_COLOR); num1.setBackground(NUM_COLOR); num2.setBackground(NUM_COLOR); num3.setBackground(NUM_COLOR); num4.setBackground(NUM_COLOR); num5.setBackground(NUM_COLOR); num6.setBackground(NUM_COLOR); num7.setBackground(NUM_COLOR); num8.setBackground(NUM_COLOR); num9.setBackground(NUM_COLOR); decimalPoint.setBackground(NUM_COLOR); addButton.setBackground(OP_COLOR); addButton.setFont(FONT1); minusButton.setBackground(OP_COLOR); minusButton.setFont(FONT1); mulButton.setBackground(OP_COLOR); mulButton.setFont(FONT1); divButton.setBackground(OP_COLOR); divButton.setFont(FONT1); leftBracket.setBackground(OP_COLOR); leftBracket.setFont(FONT1); rightBracket.setBackground(OP_COLOR); rightBracket.setFont(FONT1); equalButton.setBackground(EQUAL_COLOR); equalButton.setFont(FONT1); clearButton.setBackground(CLR_COLOR); deleteButton.setBackground(DEL_COLOR); } private void actionSettings () { num0.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "0"); } }); num1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "1"); } }); num2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "2"); } }); num3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "3"); } }); num4.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "4"); } }); num5.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "5"); } }); num6.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "6"); } }); num7.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "7"); } }); num8.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "8"); } }); num9.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "9"); } }); decimalPoint.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "."); } }); addButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "+"); } }); minusButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "-"); } }); mulButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "X"); } }); divButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "÷"); } }); leftBracket.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + "("); } }); rightBracket.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(equation.getText() + ")"); } }); equalButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String cmd = equation.getText(); Calculate cl = new Calculate(); String resultMsg = cl.calResult(cmd); if ( resultMsg.equals("算式格式错误") || resultMsg.equals("除数不能为0") ) { JOptionPane.showMessageDialog(null, resultMsg, "错误", JOptionPane.WARNING_MESSAGE); } else { result.setText(resultMsg); } } }); clearButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { equation.setText(""); result.setText(""); } }); deleteButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if( !( equation.getText().equals("")) ) { StringBuffer sb = new StringBuffer(); sb.append(equation.getText()); sb.delete(sb.length()-1 , sb.length()); equation.setText(sb.toString()); } } }); } private void positionSettings () { jp1.add(equationLabel); jp1.add(equation); jp1.add(resultLabel); jp1.add(result); equationLabel.setBounds(0, 0, 50, 30); equationLabel.setLocation(0, 0); equation.setBounds(50, 0, 150, 30); equation.setLocation(50, 0); resultLabel.setBounds(0, 30, 50, 30); resultLabel.setLocation(0, 30); result.setBounds(50, 30, 150, 30); result.setLocation(50, 30); jp2.setLayout(new GridLayout(4, 5)); // line-1 jp2.add(num7); jp2.add(num8); jp2.add(num9); jp2.add(addButton); jp2.add(leftBracket); // line-2 jp2.add(num4); jp2.add(num5); jp2.add(num6); jp2.add(minusButton); jp2.add(rightBracket); // line-3 jp2.add(num1); jp2.add(num2); jp2.add(num3); jp2.add(mulButton); jp2.add(clearButton); // line-4 jp2.add(num0); jp2.add(decimalPoint); jp2.add(equalButton); jp2.add(divButton); jp2.add(deleteButton); jp1.setLocation(0, 0); jp1.setVisible(true); jp2.setLocation(0, 100); jp2.setVisible(true); } }
package cal; import java.util.Stack; public class Calculate { private Stack<Double> numStack = new Stack<Double>(); private Stack<Character> sybStack = new Stack<Character>(); public String calResult ( String equation ) { //替换乘除号 equation = equation.replace("X", "*"); equation = equation.replace("÷", "/"); //处理负号 equation = negativeNumTransfer(equation); if ( !checkFormat(equation) ) { return "算式格式错误"; } equation += "#"; StringBuffer tempNum = new StringBuffer(); StringBuffer exp = new StringBuffer().append(equation); while ( exp.length() != 0 ) { String temp = exp.substring(0,1); exp.delete(0, 1); if( isNum(temp) ) { // temp是数字 tempNum.append(temp); } else { // temp不是数字 if (!"".equals(tempNum.toString())) { // 当表达式的第一个符号为括号 double num = Double.parseDouble(tempNum.toString()); numStack.push(num); tempNum.delete(0, tempNum.length()); } // 用当前取得的运算符与栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;若等于,因为出现在后面, // 所以会后计算,所以栈顶元素出栈,取出操作数运算;若小于,则同理,取出栈顶元素运算,将结果入操作数栈。 // 判断当前运算符与栈顶元素优先级,取出元素,进行计算(因为优先级可能小于栈顶元素,还小于第二个元素等等,需要用循环判断) while ( !compare(temp.charAt(0)) && (!sybStack.empty()) ) { double a = numStack.pop(); double b = numStack.pop(); char ope = sybStack.pop(); // 进行简单的计算 if( simpleCal(ope, a, b) == false ) { return "除数不能为0"; } } // 判断当前运算符与栈顶元素优先级, 如果高,或者低于平,计算完后,将当前操作符号,放入操作符栈 refreshSybStack(temp); } } return getResultStr(numStack.pop()); } private void refreshSybStack ( String temp) { if (temp.charAt(0) != '#') { sybStack.push(new Character(temp.charAt(0))); if (temp.charAt(0) == ')') {// 当栈顶为'(',而当前元素为')'时,则是括号内以算完,去掉括号 sybStack.pop(); sybStack.pop(); } } } private boolean simpleCal ( char ope, double a, double b ) { double result = 0; switch (ope) { case '+': result = b + a; numStack.push(result); break; case '-': result = b - a; numStack.push(result); break; case '*': result = b * a; numStack.push(result); break; case '/': if ( a == 0.0 ) { return false; } else { result = b / a; numStack.push(result); break; } } return true; } private String negativeNumTransfer( String equation ) { // 处理算式,将表示负数的部分进行改动,转成calResult方法支持的 if( equation.length() <= 1 ) { return equation; } StringBuffer str = new StringBuffer().append(equation); for ( int i = 0; i < str.length()-1; ++i ) { if( !str.substring(i, i+1).equals("-") ) { continue; } if ( i == 0 ) { char temp = str.charAt(1); if( isNumChar(temp) || isDecimalPoint(temp) || isLeftBracket(temp) ) { str.insert(0, "0"); i++; } } else { char last = str.charAt(i-1); char next = str.charAt(i+1); if( isLeftBracket(last) && ( isNumChar(next) || isDecimalPoint(next) || isLeftBracket(next) ) ) { str.insert(i, "0"); i++; } } } return str.toString(); } private boolean checkFormat ( String equation ) { char[] c = equation.toCharArray(); int singleBracket = 0; for( int i = 0; i < c.length; ++i ) { if( isLeftBracket(c[i]) ) { singleBracket++; } if ( isRightBracket(c[i]) ) { singleBracket--; } if ( i == 0 ) { //第1个元素只能是[0-9]或者是左括号 if( !isLeftBracket(c[i]) && !isNumChar(c[i]) ) { return false; } } else if ( isNumChar(c[i]) || isDecimalPoint(c[i]) ) { //数字左边不能是右括号 if ( isRightBracket(c[i-1]) ) { return false; } } else if( isLeftBracket(c[i]) ) { // 左括号的左边不能是数字和右括号 if ( isNumChar(c[i-1]) || isDecimalPoint(c[i-1]) || isRightBracket(c[i-1]) ) { return false; } } else { // 右括号和四则运算符的左边只能是数字或者右括号 if ( !isNumChar(c[i-1]) && !isRightBracket(c[i-1]) ) { return false; } } } return singleBracket == 0; } private static boolean isNum ( String temp ) { return temp.matches("[0-9]") || temp.equals("."); } private static boolean isLeftBracket ( char c ) { return c == '('; } private static boolean isRightBracket ( char c ) { return c == ')'; } private static boolean isDecimalPoint ( char c ) { return c == '.'; } private static boolean isNumChar ( char c ) { return ( c >= '0' && c <= '9' ); } private boolean compare (char str) { if ( sybStack.empty() ) { // 当为空时,显然 当前优先级最低,返回高 return true; } char last = (char) sybStack.lastElement(); // 如果栈顶为'('显然,优先级最低,')'不可能为栈顶。 if (last == '(') { return true; } switch (str) { case '#': return false;// 结束符 case '(': // '('优先级最高,显然返回true return true; case ')': // ')'优先级最低, return false; case '*': { // '*/'优先级只比'+-'高 if (last == '+' || last == '-') return true; else return false; } case '/': { if (last == '+' || last == '-') return true; else return false; } // '+-'为最低,一直返回false case '+': return false; case '-': return false; } return true; } private String getResultStr ( double result ) { StringBuffer s = new StringBuffer().append( result + "" ); if ( s.substring(s.length() - 2).equals(".0") ) { s.delete( s.length()-2 , s.length() ); } return s.toString(); } }