zoukankan      html  css  js  c++  java
  • java-swing编程,实现计算器——支持四则运算

    摘自:Ecqiao

    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();
        }
        
    }
    
    
    
    
    
  • 相关阅读:
    DirectX SDK版本与Visual Studio版本
    String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别
    LocalDateTime与字符串互转/Date互转/LocalDate互转/指定日期/时间比较
    MySQL触发器的正确使用与案例分析
    一篇很棒的 MySQL 触发器学习教程
    Java消息队列三道面试题详解!
    到底什么时候该使用MQ?
    mq使用场景、不丢不重、时序性
    Java 8时间和日期API 20例
    eclipse插件之Findbugs、Checkstyle、PMD安装及使用
  • 原文地址:https://www.cnblogs.com/springcloud/p/9084485.html
Copyright © 2011-2022 走看看