java-swing编程,实现计算器——支持四则运算

来源:互联网 发布:矩阵二范数计算 编辑:程序博客网 时间:2024/05/18 00:10

这两个星期学习了swing模块的一些内容,学习了java的GUI编程,自己动手写了一个计算器

首先是整个计算器的图形框架类CalFrame类


package Calculator;import java.awt.BorderLayout;import java.awt.Color;import java.awt.FlowLayout;import java.awt.Font;import java.awt.GridBagLayout;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;import javax.swing.JTextField;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() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "0");}});num1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "1");}});num2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "2");}});num3.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "3");}});num4.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "4");}});num5.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "5");}});num6.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "6");}});num7.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "7");}});num8.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "8");}});num9.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "9");}});decimalPoint.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + ".");}});addButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "+");}});minusButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "-");}});mulButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "X");}});divButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "÷");}});leftBracket.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + "(");}});rightBracket.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText(equation.getText() + ")");}});equalButton.addActionListener(new ActionListener() {@Overridepublic 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() {@Overridepublic void actionPerformed(ActionEvent e) {equation.setText("");result.setText("");}});deleteButton.addActionListener(new ActionListener() {@Overridepublic 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-1jp2.add(num7);jp2.add(num8);jp2.add(num9);jp2.add(addButton);jp2.add(leftBracket);// line-2jp2.add(num4);jp2.add(num5);jp2.add(num6);jp2.add(minusButton);jp2.add(rightBracket);// line-3jp2.add(num1);jp2.add(num2);jp2.add(num3);jp2.add(mulButton);jp2.add(clearButton);// line-4jp2.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);}}

然后就是处理算式的类Calculate类,在处理算式的时候利用了某网友提供的算法,之后打算自己用后缀表达式和二叉树结构来重构这部分代码


package Calculator;import java.util.Stack;import java.util.regex.Matcher;import java.util.regex.Pattern;import sun.security.krb5.internal.ccache.CCacheInputStream;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 '(':// '('优先级最高,显然返回truereturn true;case ')':// ')'优先级最低,return false;case '*': {// '*/'优先级只比'+-'高if (last == '+' || last == '-')return true;elsereturn false;}case '/': {if (last == '+' || last == '-')return true;elsereturn false;}// '+-'为最低,一直返回falsecase '+':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();}}


附:版本信息日志

版本v1.0[2016年8月16日 07:01:32]
1.实现了两个数之间的四则运算
2.添加了对除法中除数为0的处理


版本v1.1[2016年8月17日 05:01:18]
优化界面
给按钮添加了颜色


版本v1.2[2016年8月17日 05:02:05]
进一步优化界面
增加异常处理
添加v1分支


版本v2.0[2016年8月25日 06:05:21]
增加了对四则运算的支持
增加了括号和小数点,数据类型改成double
优化了界面,式子和结果分行显示


版本v2.1[2016年8月25日 19:35:08]
增加了对式子格式的检查方法checkFormat
增加了对double类型除法0的判断
优化代码结构,将Calculate类的calResult方法模块化


版本v2.2[2016年8月26日 23:28:49]
增加了对负数的支持
改变了字体,使得界面更加友好


版本v2.3[2016年8月27日 19:25:19]
将异常结果用弹窗的形式来呈现
优化代码结构,将CalFrame类的构造方法的代码进行模块化 

0 0
原创粉丝点击