早晨起来没事,打开mac突然想写个小程序,就写来个简易的计算器,可以实现基本的运算,测试目前无bug,下面分享下自己的代码。 首先写了个简单的界面如下: 整个面板用了BorderLayout布局,分为北,左和中。中部采用网格布局。定义这个类为CalFrame.java: package calframe;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Arrays;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextField;public class CalFrame extends JFrame { /** * 计算器的外观设计 */ private static final long serialVersionUID = 1L; private final static int PRE_WIDTH = 500; private final static int PRE_HEIGHT = 400; private JTextField text = null; private JButton button = null; //存储标记 private String[] nOp = {'7','8','9','/','sqrt','4','5','6','*','%','1','2','3','-','1/x','0','+/-','.','+','='}; private String[] mOp = {'MC','MR','MS','M+'}; private String[] rOp = {'Back','CE','C'}; private CalService service = new CalService(); public CalFrame(){ this.setTitle('计算器'); this.setSize(PRE_WIDTH, PRE_HEIGHT); this.setLocationRelativeTo(null); this.setResizable(false); //添加底层 JPanel panel = new JPanel(); panel.setLayout(new BorderLayout(10,1)); panel.add(getTextField(), BorderLayout.NORTH); panel.setPreferredSize(new Dimension(PRE_WIDTH, PRE_HEIGHT)); //WEST JButton[] mButton = getMButton(); JPanel panel1 = new JPanel(); panel1.setLayout(new GridLayout(5,1,0,5)); for(JButton b : mButton ){ panel1.add(b); } panel.add(panel1,BorderLayout.WEST); // JButton[] rButton = getRButton(); JPanel panel2 = new JPanel(); panel2.setLayout(new BorderLayout(1,5)); JPanel panel21 = new JPanel(); panel21.setLayout(new GridLayout(1,3,3,3)); for(JButton b : rButton){ panel21.add(b); } panel2.add(panel21,BorderLayout.NORTH); JButton[] nButton = getNButton(); JPanel panel22 = new JPanel(); panel22.setLayout(new GridLayout(4,5,3,5)); for(JButton b : nButton){ panel22.add(b); } panel2.add(panel22,BorderLayout.CENTER); panel.add(panel2,BorderLayout.CENTER); this.add(panel); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.setVisible(true); } //返回显示框 private JTextField getTextField(){ text = new JTextField('0',10); //text.setSize(480, 50); return text; } //返回数字键 private JButton[] getNButton(){ String[] redButton = {'/','*','-','+','='}; JButton[] nbutton = new JButton[nOp.length]; for(int i = 0; i < this.nop.length;="" i++){="" jbutton="" b="new" jbutton(this.nop[i]);="" b.addactionlistener(getactionlistener());="" arrays.sort(redbutton);="" if(arrays.binarysearch(redbutton,="" nop[i])="">= 0){ b.setForeground(Color.red); }else{ b.setForeground(Color.blue); } nbutton[i] = b; } return nbutton; } //返回操作健 private JButton[] getMButton(){ JButton[] mbutton = new JButton[mOp.length + 1]; mbutton[0] = getButton(); for(int i = 0; i < this.mop.length;="" i++){="" jbutton="" b="new" jbutton(this.mop[i]);="" b.addactionlistener(getactionlistener());="" b.setforeground(color.red);="" mbutton[i+1]="b;" }="" return="" mbutton;="" }="" private="" jbutton[]="" getrbutton(){="" jbutton[]="" rbutton="new" jbutton[rop.length];="" for(int="" i="0;" i="">< this.rop.length;="" i++){="" jbutton="" b="new" jbutton(this.rop[i]);="" b.addactionlistener(getactionlistener());="" b.setforeground(color.red);="" rbutton[i]="b;" }="" return="" rbutton;="" }="" private="" jbutton="" getbutton(){="" button="new" jbutton();="" return="" button;="" }="" private="" actionlistener="" getactionlistener(){="" actionlistener="" actionlistener="new" actionlistener()="" {="" @override="" public="" void="" actionperformed(actionevent="" e)="" {="" string="" cmd="e.getActionCommand();" string="" result="null;" try="" {="" result="service.callMethod(cmd," text.gettext());="" }="" catch="" (exception="" e2)="" {="" system.out.println(e2.getmessage());="" }="" if(cmd.indexof('mc')="=" 0){="" button.settext('');="" }else="" if(cmd.indexof('m')="=" 0){="" button.settext('m');="" }="" 显示计算结果="" if(result="" !="null){" text.settext(result);="" }="" }="" };="" return="" actionlistener;="" }="" public="" static="" void="" main(string[]="" args)="" {="" new="" calframe();=""> 接着实现几个基本的操作,加,减,乘,除。考虑到精度和范围的问题,我们定义了一个MyMath类,数据格式都使用BigDecimal对象进行计算。MyMath.java: package calframe;import java.math.BigDecimal;public class MyMath { /** * 为一个double类型创建BigDecimal对象 */ private static BigDecimal getBigDecimal(double number){ return new BigDecimal(number); } public static double add(double num1, double num2) { BigDecimal first = getBigDecimal(num1); BigDecimal second = getBigDecimal(num2); return first.add(second).doubleValue(); } public static double subtract(double num1, double num2) { BigDecimal first = getBigDecimal(num1); BigDecimal second = getBigDecimal(num2); return first.subtract(second).doubleValue(); } public static double multiply(double num1, double num2) { BigDecimal first = getBigDecimal(num1); BigDecimal second = getBigDecimal(num2); return first.multiply(second).doubleValue(); } public static double divide(double num1, double num2) { BigDecimal first = getBigDecimal(num1); BigDecimal second = getBigDecimal(num2); return first.divide(second,3,BigDecimal.ROUND_HALF_UP).doubleValue(); }} 最后处理按钮的事件,我们定义了一个CalService类处理业务逻辑: package calframe;public class CalService { private boolean isSecondNum = false; private String lastOp; private String firstNum = '0'; private String secondNum = 'null'; private double store; private String numString = '0123456789.'; private String opString = '+-*/'; public String catNum(String cmd, String text) { String result = cmd; // 如果text不等于0 if (!'0'.equals(text)) { if (isSecondNum) { isSecondNum = false; } else { result = text + cmd; } } if (result.indexOf('.') == 0) { result = '0' + result; } return result; } public String setOp(String cmd, String text) { this.lastOp = cmd; this.firstNum = text; this.secondNum = null; this.isSecondNum = true; return null; } public String cal(String text, boolean isPercent) { double secondResult = secondNum == null ? Double.valueOf(text) .doubleValue() : Double.valueOf(secondNum).doubleValue(); //除数为0 if(secondResult == 0 && this.lastOp.equals('/')){ return '0'; } //有% if(isPercent){ secondResult = MyMath.multiply(Double.valueOf(firstNum), MyMath.divide(secondResult, 100)); } if(this.lastOp.equals('+')){ firstNum = String.valueOf(MyMath.add(Double.valueOf(firstNum),secondResult)); }else if (this.lastOp.equals('-')) { firstNum = String.valueOf(MyMath.subtract(Double.valueOf(firstNum),secondResult)); }else if (this.lastOp.equals('*')) { firstNum = String.valueOf(MyMath.multiply(Double.valueOf(firstNum),secondResult)); }else if (this.lastOp.equals('/')) { firstNum = String.valueOf(MyMath.divide(Double.valueOf(firstNum),secondResult)); } secondNum = secondNum == null ? text :secondNum; this.isSecondNum = true; return firstNum; } //求开方 public String sqrt(String text){ this.isSecondNum = true; return String.valueOf(Math.sqrt(Double.valueOf(text))); } //求倒数 public String setReciprocal(String text){ if (text.equals('0')){ return text; }else{ this.isSecondNum = true; return String.valueOf(MyMath.divide(1, Double.valueOf(text))); } } //存储 public String mCmd(String cmd,String text){ if(cmd.equals('M+')){ store = MyMath.add(store, Double.valueOf(text)); }else if (cmd.equals('MC')) { store = 0; }else if (cmd.equals('MR')) { isSecondNum = true; return String.valueOf(store); }else if (cmd.equals('MS')) { store = Double.valueOf(text).doubleValue(); } return null; } public String backSpace(String text){ return text.equals('0') || text.equals('') ? '0' :text.substring(0,text.length()-1); } public String setNegative(String text){ if(text.indexOf('-') == 0){ return text.substring(1,text.length()); }else{ return '-' + text; } } public String clearAll(){ this.firstNum = '0'; this.secondNum = null; return this.firstNum; } public String clear(String text){ return '0'; } public String callMethod(String cmd, String text){ if(cmd.equals('C')){ return clearAll(); }else if(cmd.equals('CE')){ return clear(text); }else if (cmd.equals('Back')) { return backSpace(text); }else if (numString.indexOf(cmd) != -1) { return catNum(cmd, text); }else if (opString.indexOf(cmd) != -1) { return setOp(cmd, text); }else if (cmd.equals('+/-')) { return setNegative(text); //设置正负号 }else if(cmd.equals('1/x')){ return setReciprocal(text); }else if (cmd.equals('sqrt')) { return sqrt(text); }else if(cmd.equals('%')){ return cal(text, true); }else if(cmd.equals('=')){ return cal(text, false); }else { return mCmd(cmd, text); } }} 最后的calMethod方法大量使用if else判断不是好的实现方法,感兴趣的可以看看java的设计模式,消除这样的判断。至此,一个简易的计算器就完成了。欢迎大家给为留言,共同学习,共同进步。 |
|