java实现简易计算器完整代码

早晨起来没事,打开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的设计模式,消除这样的判断。
至此,一个简易的计算器就完成了。欢迎大家给为留言,共同学习,共同进步。


©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页