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(); } }