Java 计算器

Java上机作业,简单计算器的代码,模仿XP下普通计算器,暂没有优先级区分.

jar包下载,内有源码文件

欢迎指出各种bug,目前不完善的地方:

12-31:

由于没有对乘法精度限制,乘法次数过多后会由于内部位数过多而运行缓慢;

可能是由于字体原因,会造成不同平台上显示条长度不同,影响美观和使用;

import java.awt.*;
import java.awt.event.*;
import java.math.*;
import java.util.*;
import javax.swing.*;

class JCalculator extends JFrame implements ActionListener{
	static final long serialVersionUID = 1L;

	JCalculator(){
		init();
		setLayout(new BorderLayout());
		setText();
		setButton();
		setKey();
	}

	void init(){
		fnum=BigDecimal.ZERO;
		snum=BigDecimal.ZERO;
		buffer="0";
		oprt=0;
		isF=false;
		isV=false;
		isE=true;
	}

	boolean calc(){
		if(oprt==0){
			fnum=snum;
		}else if(oprt==1){
			fnum=fnum.add(snum);
		}else if(oprt==2){
			fnum=fnum.subtract(snum);
		}else if(oprt==3){
			fnum=fnum.multiply(snum);
		}else if(oprt==4){
			try{
				fnum=fnum.divide(snum,200,RoundingMode.HALF_EVEN);
			}catch(ArithmeticException ex){
				init();
				text.setText("Error!");
				return false;
			}
		}else if(oprt==5){
			try{
				fnum=fnum.remainder(snum);
			}catch(ArithmeticException ex){
				init();
				text.setText("Error!");
				return false;
			}
		}
		return true;
	}

	void show(BigDecimal num){
		if(((num.stripTrailingZeros()).toPlainString()).length()<=24){
			text.setText((num.stripTrailingZeros()).toPlainString());
		}else{
			BigDecimal topv=BigDecimal.ONE,tmp=num;
			if(num.signum()<0) tmp=tmp.multiply(BigDecimal.valueOf(-1D));
			if(tmp.compareTo(BigDecimal.ONE)>0){
				while(tmp.compareTo(BigDecimal.ONE)>0){
					tmp=tmp.divide(BigDecimal.TEN);
					topv=topv.multiply(BigDecimal.TEN);
				}
			}else{
				int tcnt=0;
				while(tmp.compareTo(BigDecimal.ONE)<0){
					tmp=tmp.multiply(BigDecimal.TEN);
					topv=topv.divide(BigDecimal.TEN);
					tcnt++;
					if(tcnt>220) break;
				}
			}
			if(num.signum()<0) tmp=tmp.multiply(BigDecimal.valueOf(-1D));
			BigDecimal show=tmp.setScale(20, RoundingMode.HALF_EVEN).multiply(topv);
			String Ans=show.stripTrailingZeros().toString();
			if(Ans.matches("0E[-0-9]+")) Ans="0";
			text.setText(Ans);
		}
	}

	void setText(){
		text=new JTextField(buffer,26);
		text.setFocusable(false);
		text.setHorizontalAlignment(JTextField.RIGHT);
		text.setFont(new Font("Consolas",Font.PLAIN,18));

		JPanel jpTF=new JPanel();
		jpTF.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
		jpTF.add(text);

		add(jpTF,BorderLayout.NORTH);

		isM=new JLabel();
		isM.setHorizontalAlignment(JLabel.CENTER);
	}
 
	void setButton(){
		num=new JButton[10];
		for(int i=0;i<10;i++){
			num[i]=new JButton(""+i);
			num[i].setFocusable(false);
			num[i].addActionListener(this);
		}
		
		ButtonGroup bg=new ButtonGroup();
		bg.add(dot=new JButton("."));
		bg.add(sign=new JButton("±"));
		bg.add(plus=new JButton("+"));
		bg.add(subtract=new JButton("-"));
		bg.add(multiply=new JButton("×"));
		bg.add(divide=new JButton("÷"));
		bg.add(mod=new JButton("mod"));
		bg.add(enter=new JButton("="));
		bg.add(cls=new JButton("C"));
		bg.add(cle=new JButton("CE"));
		bg.add(back=new JButton("←"));
		bg.add(copy=new JButton("copy"));
		bg.add(square=new JButton("x²"));
		bg.add(sqrt=new JButton("√"));
		bg.add(reci=new JButton("1/x"));
		bg.add(ms=new JButton("MS"));
		bg.add(mc=new JButton("MC"));
		bg.add(mr=new JButton("MR"));
		bg.add(ma=new JButton("M+"));
		
		Enumeration<AbstractButton> bgE=bg.getElements();
		while(bgE.hasMoreElements()){
			AbstractButton tb=bgE.nextElement();
			tb.addActionListener(this);
			tb.setFocusable(false);
		}

		JPanel jpMB=new JPanel(new GridLayout(0,1,2,2));
		jpMB.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 2));

		jpMB.add(isM);
		jpMB.add(mc);
		jpMB.add(mr);
		jpMB.add(ms);
		jpMB.add(ma);

		add(jpMB,BorderLayout.WEST);

		JPanel jpNB=new JPanel(new GridLayout(0,5,2,2));
		jpNB.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10));

		jpNB.add(cls);
		jpNB.add(cle);
		jpNB.add(back);
		jpNB.add(mod);
		jpNB.add(copy);

		jpNB.add(num[7]);
		jpNB.add(num[8]);
		jpNB.add(num[9]);
		jpNB.add(divide);
		jpNB.add(sqrt);

		jpNB.add(num[4]);
		jpNB.add(num[5]);
		jpNB.add(num[6]);
		jpNB.add(multiply);
		jpNB.add(square);

		jpNB.add(num[1]);
		jpNB.add(num[2]);
		jpNB.add(num[3]);
		jpNB.add(subtract);
		jpNB.add(reci);

		jpNB.add(num[0]);
		jpNB.add(dot);
		jpNB.add(sign);
		jpNB.add(plus);
		jpNB.add(enter);

		add(jpNB,BorderLayout.CENTER);

	}
	
	void setKey(){
		addKeyListener(new KeyListener(){
			public void keyPressed(KeyEvent e){
				char vk=e.getKeyChar();
				switch(vk){
				case '+': plus.doClick();break;
				case '-': subtract.doClick();break;
				case '*': multiply.doClick();break;
				case '/': divide.doClick();break;
				case '.': dot.doClick();break;
				case '_': sign.doClick();break;
				case KeyEvent.VK_EQUALS: 
				case KeyEvent.VK_ENTER: enter.doClick();break;
				}
				int vkc=e.getKeyCode();
				switch(vkc){
				case KeyEvent.VK_BACK_SPACE: back.doClick();break;
				case KeyEvent.VK_ESCAPE: cls.doClick();break;
				case KeyEvent.VK_C: if(e.isControlDown()) copy.doClick();break;
				}
			}

			public void keyReleased(KeyEvent e) {
			}

			public void keyTyped(KeyEvent e) {
				char vk=e.getKeyChar();
				switch(vk){
				case KeyEvent.VK_0:	num[0].doClick();break;
				case KeyEvent.VK_1: num[1].doClick();break;
				case KeyEvent.VK_2: num[2].doClick();break;
				case KeyEvent.VK_3: num[3].doClick();break;
				case KeyEvent.VK_4: num[4].doClick();break;
				case KeyEvent.VK_5: num[5].doClick();break;
				case KeyEvent.VK_6: num[6].doClick();break;
				case KeyEvent.VK_7: num[7].doClick();break;
				case KeyEvent.VK_8: num[8].doClick();break;
				case KeyEvent.VK_9: num[9].doClick();break;
				}
			}
		});
	}
	
	void oprtInput(String bac){
		for(int i=0;i<10;i++){
			if(bac.equals(num[i].getText())){
				if(isE) oprt=0;
				if(buffer.equals("0")){
					buffer=""+i;
				}else{
					buffer=buffer+i;
				}
				isV=false;
				isE=false;
				snum=new BigDecimal(buffer);
				text.setText(buffer);
				return;
			}
		}

		if(bac.equals(dot.getText())){
			if(isE) oprt=0;
			if(!isF){
				isF=true;
				buffer=buffer+".";
				snum=new BigDecimal(buffer);
				isV=false;
				isE=false;
			}
			text.setText(buffer);

		}else if(bac.equals(sign.getText())){
			if(!isV){
				System.out.println("**");
				if(isE) oprt=0;
				if(buffer.equals("0")) return;
				if(buffer.matches("-[-.0-9]+")){
					buffer=buffer.substring(1);
				}else{
					buffer="-"+buffer;
				}
				isV=false;
				isE=false;
				snum=new BigDecimal(buffer);
				text.setText(buffer);
			}

		}else if(bac.equals(back.getText())){
			if(isV) return;
			if(buffer.equals("0")) return;
			if(buffer.endsWith(".")) isF=false;
			if(buffer.matches("[-]{0,1}[0-9]{1}")) buffer="0";
			else buffer=buffer.substring(0,buffer.length()-1);
			snum=new BigDecimal(buffer);
			text.setText(buffer);

		}
	}
	
	void oprtBinary(String bac){
		if(bac.equals(plus.getText())){
			if(oprt==0) fnum=snum;
			if(!isV) calc();
			oprt=1;
			snum=fnum;
			buffer="0";
			isF=false;
			isV=true;
			isE=false;
			show(snum);

		}else if(bac.equals(subtract.getText())){
			if(oprt==0) fnum=snum;
			if(!isV) calc();
			oprt=2;
			snum=fnum;
			buffer="0";
			isF=false;
			isV=true;
			isE=false;
			show(snum);

		}else if(bac.equals(multiply.getText())){
			if(oprt==0) fnum=snum;
			if(!isV) calc();
			oprt=3;
			snum=fnum;
			buffer="0";
			isF=false;
			isV=true;
			isE=false;
			show(snum);

		}else if(bac.equals(divide.getText())){
			if(oprt==0) fnum=snum;
			if(!isV){
				if(!calc()) return;
			}
			oprt=4;
			snum=fnum;
			buffer="0";
			isF=false;
			isV=true;
			isE=false;
			show(snum);

		}else if(bac.equals(mod.getText())){
			if(oprt==0) fnum=snum;
			if(!isV){
				if(!calc()) return;
			}
			oprt=5;
			snum=fnum;
			buffer="0";
			isF=false;
			isV=true;
			isE=false;
			show(snum);

		}
	}

	void oprtUnary(String bac){
		if(bac.equals(sign.getText())){
			if(isV){
				if(isE){
					snum=fnum.multiply(BigDecimal.valueOf(-1));
				}else{
					snum=snum.multiply(BigDecimal.valueOf(-1));
				}
				show(snum);
			}
		}else if(bac.equals(square.getText())){
			BigDecimal tmp;
			if(isE){
				tmp=fnum; oprt=0;
			}else{
				tmp=snum; buffer="0";
				isF=false;
			}
			snum=tmp.multiply(tmp);
			isE=false;
			isV=true;
			show(snum);

		}else if(bac.equals(reci.getText())){
			BigDecimal tmp;
			if(isE){
				tmp=fnum; oprt=0;
			}else{
				tmp=snum; buffer="0";
				isF=false;
			}
			try{
				snum=BigDecimal.ONE.divide(tmp,180,RoundingMode.HALF_EVEN);
			}catch(ArithmeticException ex){
				init();
				text.setText("Error!");
				return;
			}
			isE=false;
			isV=true;
			show(snum);

		}else if(bac.equals(sqrt.getText())){
			BigDecimal tmp;
			if(isE){
				tmp=fnum; oprt=0;
			}else{
				tmp=snum; buffer="0";
				isF=false;
			}

			if(tmp.compareTo(BigDecimal.ZERO)<0){
				init();
				text.setText("Error!");
				return;
			}

			BigDecimal top,bot;
			if(tmp.compareTo(BigDecimal.ONE)>0){
				top=BigDecimal.ONE; bot=tmp;
			}else{
				top=tmp; bot=BigDecimal.ONE;
			}
			BigDecimal mid=tmp.divide(BigDecimal.valueOf(2),180,RoundingMode.HALF_EVEN);
			while(bot.subtract(top).compareTo(new BigDecimal("1e-150"))>=0){
				if((mid.multiply(mid)).compareTo(tmp)>=0){
					bot=mid;
				}else{
					top=mid;
				}
				mid=(top.add(bot)).divide(BigDecimal.valueOf(2),180,RoundingMode.HALF_EVEN);
			}
			snum=mid;

			isE=false;
			isV=true;
			show(snum);

		}
	}

	void oprtMem(String bac){
		if(bac.equals(ms.getText())){
			isM.setText("M");
			if(isE){
				mem=fnum;
			}else{
				mem=snum;
			}

		}else if(bac.equals(mc.getText())){
			isM.setText("");

		}else if(bac.equals(mr.getText())){
			if(isE) oprt=0;
			if(isM.getText().equals("M")){
				snum=mem;
				buffer="0";
				isV=true;
				isF=false;
				show(snum);
			}

		}else if(bac.equals(ma.getText())){
			if(isM.getText().equals("M")){
				if(isE){
					mem=mem.add(fnum);
				}else{
					mem=mem.add(snum);
				}
			}

		}
	}

	void oprtSys(String bac){
		if(bac.equals(enter.getText())){
			if(!calc()) return;
			isF=false;
			isV=true;
			isE=true;
			buffer="0";
			show(fnum);

		}else if(bac.equals(copy.getText())){
			text.selectAll();
			text.copy();

		}else if(bac.equals(cls.getText())){
			init();
			show(snum);

		}else if(bac.equals(cle.getText())){
			isF=false;
			snum=BigDecimal.ZERO;
			buffer="0";
			show(snum);

		}
	}

	public void actionPerformed(ActionEvent e){
		String bac=e.getActionCommand();

		oprtInput(bac);
		oprtBinary(bac);
		oprtUnary(bac);
		oprtMem(bac);
		oprtSys(bac);

	}

	public static void main(String args[]){
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null,"System UI picked error!","UI Error!",JOptionPane.ERROR_MESSAGE);
		}
		JCalculator frame=new JCalculator();
		frame.setTitle("JCalculator");
		frame.setSize(400,240);
		frame.setResizable(false);
		frame.setVisible(true);
		frame.requestFocus();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

	private JLabel isM;
	private JTextField text;
	private String buffer;
	private int oprt;
	private boolean isF,isV,isE;
	private BigDecimal fnum,snum,mem;

	private JButton[] num;
	private JButton dot,sign,enter;
	private JButton plus,subtract,multiply,divide,mod;
	private JButton square,sqrt,reci;
	private JButton cls,cle,back,copy;
	private JButton ms,mc,mr,ma;
}
原文地址:https://www.cnblogs.com/ambition/p/JCalculator.html