疯狂java讲义中的习题,设计一个简单的计算器。

这是一个模仿xp下的计算器的标准版
/**
 * 做一个计算器,这里我们以windows-XP中的calc计算器的标准型为目标来做
 * 程序分解:
 * 1、GUI界面:
 * 		菜单栏:编辑(复制,粘贴)、查看、帮助
 * 		单行文本框:
 * 		回退键:Backspace、CE、C
 * 		数字键:1-9 、“0”、“.” 、“+/-”
 * 		计算键:+ 、- 、* 、/ ;sqrt 、% 、1/x 、 =
 * 
 * 2、计算核心:
 * 		数字button监听类
 * 		计算方法button监听类
 * 		回退button监听类
 * 
 * 3、描述:
 * 		计算器的大部分功能都得到了实现,比如:最基本的四则运算、3个特殊运算、3个不同的回退方法、
 * 文本框只允许出现数字和运算符、运算时不能以运算符开头、一次运算自能输入一个运算符、特殊运算符只有一个数字、
 * 菜单栏中只实现了编辑菜单中的复制、粘贴两个功能、
 * 
 * 
 * 
 * */

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.Box;

public class Calculator{
	Frame f = new Frame("计算器");//窗体
	MenuBar mb = new MenuBar();//菜单
	Box bMod = Box.createHorizontalBox();//水平盒子,用来盛放三个修改按钮
	Box bTop = Box.createVerticalBox();//垂直盒子,用来盛放文本行+水平盒子
	//利用Toolkit工具包类取得系统工具包,在系统工具包中取得系统剪贴板
	Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
	
	TextField tf = new TextField(20);//文本行
	Panel p = new Panel();//用来盛放数字键+运算符
	
	Panel numPan = new Panel();//定义数字键盘
	Panel mathPan1 = new Panel();//定义加减乘除
	Panel mathPan2 = new Panel();//定义开方、求模、求倒数、等于
	
	Menu edit = new Menu("编辑");
	Menu select = new Menu("查看");
	Menu help = new Menu("帮助");
	
	MenuItem copyItem = new MenuItem("复制",new MenuShortcut(KeyEvent.VK_C));
	MenuItem patseItem = new MenuItem("粘贴",new MenuShortcut(KeyEvent.VK_P));
	
	MenuItem standard = new MenuItem("标准型");
	MenuItem science = new MenuItem("科学型");
	MenuItem group = new MenuItem("数字分组");
	
	MenuItem item = new MenuItem("帮助主题");
	MenuItem about = new MenuItem("关于计算器");
	Button but1 = new Button("1");
	Button but2 = new Button("2");
	Button but3 = new Button("3");
	Button but4 = new Button("4");
	Button but5 = new Button("5");
	Button but6 = new Button("6");
	Button but7 = new Button("7");
	Button but8 = new Button("8");
	Button but9 = new Button("9");
	Button but0 = new Button("0");
	Button butFuhao = new Button("+/-");
	Button butDian = new Button(".");
	
	Button butAdd = new Button("+");
	Button butSub = new Button("-");
	Button butMul = new Button("*");
	Button butDiv = new Button("/");
	
	Button butSqr = new Button("sqr");
	Button butDao = new Button("1/x");
	Button butMo = new Button("%");
	Button butEqu = new Button("=");
	
	Button butBackspace = new Button("Backspace");
	Button butCE = new Button("CE");
	Button butC = new Button("C");
	
	public void init(){
		//为运输符号按钮设置颜色
		butAdd.setForeground(Color.RED);
		butSub.setForeground(Color.RED);	
		butMul.setForeground(Color.RED);	
		butDiv.setForeground(Color.RED);	
		butSqr.setForeground(Color.RED);			
		butMo.setForeground(Color.RED);	
		butDao.setForeground(Color.RED);	
		butEqu.setForeground(Color.RED);	
		butBackspace.setForeground(Color.RED);	
		butCE.setForeground(Color.RED);	
		butC.setForeground(Color.RED);	
		//添加按钮
		edit.add(copyItem);
		edit.add(patseItem);
		select.add(standard);
		select.add(science);
		select.add(group);
		help.add(item);
		help.add(about);
		mb.add(edit);
		mb.add(select);
		mb.add(help);
		bMod.add(butBackspace);
		bMod.add(butCE);
		bMod.add(butC);
		bTop.add(tf,BorderLayout.NORTH);
		bTop.add(bMod);
		// 设置Panel使用GridLayout布局管理器
		numPan.setLayout(new GridLayout(4, 4 , 4, 4));
		mathPan1.setLayout(new GridLayout(4, 2 , 4, 4));
		mathPan2.setLayout(new GridLayout(4, 2 , 4, 4));
		//将生成的按钮添加到组件上
		numPan.add(but1);
		numPan.add(but2);
		numPan.add(but3);
		numPan.add(but4);
		numPan.add(but5);
		numPan.add(but6);
		numPan.add(but7);
		numPan.add(but8);
		numPan.add(but9);
		numPan.add(but0);
		numPan.add(butFuhao);
		numPan.add(butDian);
		mathPan1.add(butAdd);
		mathPan1.add(butSub);
		mathPan1.add(butMul);
		mathPan1.add(butDiv);
		mathPan2.add(butSqr);
		mathPan2.add(butDao);
		mathPan2.add(butMo);
		mathPan2.add(butEqu);
		//为关闭窗体添加监听事件
		f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(1);
			}
		});
		
		//为单行文本框添加键盘监听,只允许输入数字和运算符号,其他的输入一律无效
		tf.addKeyListener(new KeyAdapter(){
			public void keyReleased(KeyEvent e){
				char c = e.getKeyChar();
				byte b = (byte)c;
				if(b==10){
					String temp = tf.getText();
					if(temp.matches("\\S+\\+\\S+")){
						String num[] = temp.split("\\+");
						double result = Double.parseDouble(num[0])+Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
					//求两个数的差值
					if(temp.matches("\\S+\\-\\S+")){
						String num[] = temp.split("\\-");
						double result = 0.0;
						if(num.length==2){
							result = Double.parseDouble(num[0])-Double.parseDouble(num[1]);
						}
						if(num.length==3){
							result = -Double.parseDouble(num[1])-Double.parseDouble(num[2]);
						}
						tf.setText(result+"");
						return;
					}
					//求两个数的积
					if(temp.matches("\\S+\\*\\S+")){
						String num[] = temp.split("\\*");
						double result = Double.parseDouble(num[0])*Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
					//求一个数的倒数,求倒数应该在求商的前面,避免发生混淆
					if(temp.matches("\\S+[1/x]\\S+")){
						String num[] = temp.split("1/x");
						double result = 1/Double.parseDouble(num[0]);
						tf.setText(result+"");
						return;
					}
					//求两个数的商,这里的求商要和求倒数区分开来
					if(temp.matches("\\d+\\/\\d+")){
						String num[] = temp.split("\\/");
						double result = Double.parseDouble(num[0])/Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
					//求一个数的平方根
					if(temp.matches("\\S+sqr")){
						String num[] = temp.split("sqr");
						double result = Math.sqrt(Double.parseDouble(num[0]));
						tf.setText(result+"");
						return;
					}
					//求两个数相除的模(即余数)
					if(temp.matches("\\S+\\%\\S+")){
						String num[] = temp.split("\\%");
						double result = Double.parseDouble(num[0])%Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
				}
				if(!(b>=42&&b<=57)){
					tf.setText("");
				}
			}
		});
		
		//将组件添加到窗体中
		p.add(numPan);
		p.add(mathPan1);
		p.add(mathPan2);
		f.setMenuBar(mb);
		f.add(bTop,BorderLayout.NORTH);
		f.add(p);
		//设置用户不能调整窗体大小
		f.setResizable(false); 
		//设置窗口为最佳大小
		f.pack();
		//将窗口显示出来(Frame对象默认处于隐藏状态)
		f.setVisible(true);
		//添加数字按钮和运算按钮的监听事件
		Operate();
		//添加复制、粘贴的监听方法
		editMethod();
	}
	
	//定义操作方法,包括了数字和计算方法的监听
	public void  Operate(){
		//定义数字按钮的监听事件
		ActionListener numListener = new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(e.getActionCommand().equals("1")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"1");
				}
				if(e.getActionCommand().equals("2")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"2");
				}
				if(e.getActionCommand().equals("3")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"3");
				}
				if(e.getActionCommand().equals("4")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"4");
				}
				if(e.getActionCommand().equals("5")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"5");
				}
				if(e.getActionCommand().equals("6")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"6");
				}
				if(e.getActionCommand().equals("7")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"7");
				}
				if(e.getActionCommand().equals("8")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"8");
				}
				if(e.getActionCommand().equals("9")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"9");
				}
				if(e.getActionCommand().equals("0")){
					if(isOver(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"0");
				}
				if(e.getActionCommand().equals(".")){
					String str = tf.getText();
					if(isEnd(str)){//如果程序以运输符号结尾则无法再输入任何运输符
						return;
					}
					if(str.matches("\\d+\\.\\d+")){
						return;
					}
					tf.setText(tf.getText()+".");
				}
				if(e.getActionCommand().equals("+/-")){
					String str = tf.getText();
					if(isEnd(str)){//如果程序以运输符号结尾则无法再输入任何运输符
						return;
					}
					if(str.matches("-\\d+")){
						char[] c = str.toCharArray();
						tf.setText(new String(c,1,c.length-1));
					}else{
						tf.setText("-"+str);
					}
				}
			}
		};
		//定义计算按钮的监听事件
		ActionListener mathListener = new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(e.getActionCommand().equals("+")){
					if(isEnd(tf.getText())){//如果程序以运输符号结尾则无法再输入任何运输符
						return;
					}
					tf.setText(tf.getText()+"+");
				}
				if(e.getActionCommand().equals("-")){
					if(isEnd(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"-");
				}
				if(e.getActionCommand().equals("*")){
					if(isEnd(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"*");
				}
				if(e.getActionCommand().equals("/")){
					if(isEnd(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"/");
				}
				if(e.getActionCommand().equals("sqr")){
					if(isEnd(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"sqr");
				}
				if(e.getActionCommand().equals("1/x")){
					if(isEnd(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"1/x");
				}
				if(e.getActionCommand().equals("%")){
					if(isEnd(tf.getText())){
						return;
					}
					tf.setText(tf.getText()+"%");
				}
				if(e.getActionCommand().equals("Backspace")){
					String temp = tf.getText();
					if(temp.length()==0){
						return;
					}
					char[] c = temp.toCharArray();
					tf.setText(new String(c,0,c.length-1));
				}
				if(e.getActionCommand().equals("CE")){
					String temp = tf.getText();
					String[] num = temp.split("\\D");
					if(num.length==1){
						tf.setText("");
					}
					if(num.length==2){
						tf.setText(num[0]);
					}
				}
				if(e.getActionCommand().equals("C")){
					tf.setText("");
				}
				//输入等号的时候,对TextField中输入的文字进行运算
				if(e.getActionCommand().equals("=")){
					String temp = tf.getText();
					if(temp.matches("\\S+\\+\\S+")){
						String num[] = temp.split("\\+");
						double result = Double.parseDouble(num[0])+Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
					//求两个数的差值
					if(temp.matches("\\S+\\-\\S+")){
						String num[] = temp.split("\\-");
						double result = 0.0;
						if(num.length==2){
							result = Double.parseDouble(num[0])-Double.parseDouble(num[1]);
						}
						if(num.length==3){
							result = -Double.parseDouble(num[1])-Double.parseDouble(num[2]);
						}
						tf.setText(result+"");
						return;
					}
					//求两个数的积
					if(temp.matches("\\S+\\*\\S+")){
						String num[] = temp.split("\\*");
						double result = Double.parseDouble(num[0])*Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
					//求一个数的倒数,求倒数应该在求商的前面,避免发生混淆
					if(temp.matches("\\S+[1/x]\\S+")){
						String num[] = temp.split("1/x");
						double result = 1/Double.parseDouble(num[0]);
						tf.setText(result+"");
						return;
					}
					//求两个数的商,这里的求商要和求倒数区分开来
					if(temp.matches("\\d+\\/\\d+")){
						String num[] = temp.split("\\/");
						double result = Double.parseDouble(num[0])/Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
					//求一个数的平方根
					if(temp.matches("\\S+sqr")){
						String num[] = temp.split("sqr");
						double result = Math.sqrt(Double.parseDouble(num[0]));
						tf.setText(result+"");
						return;
					}
					//求两个数相除的模(即余数)
					if(temp.matches("\\S+\\%\\S+")){
						String num[] = temp.split("\\%");
						double result = Double.parseDouble(num[0])%Double.parseDouble(num[1]);
						tf.setText(result+"");
						return;
					}
				}
			}
		};
		//为所有的按钮添加监听事件
		but1.addActionListener(numListener);
		but2.addActionListener(numListener);
		but3.addActionListener(numListener);
		but4.addActionListener(numListener);
		but5.addActionListener(numListener);
		but6.addActionListener(numListener);
		but7.addActionListener(numListener);
		but8.addActionListener(numListener);
		but9.addActionListener(numListener);
		but0.addActionListener(numListener);
		butDian.addActionListener(numListener);
		butFuhao.addActionListener(numListener);
		butAdd.addActionListener(mathListener);
		butSub.addActionListener(mathListener);
		butMul.addActionListener(mathListener);
		butDiv.addActionListener(mathListener);
		butSqr.addActionListener(mathListener);
		butMo.addActionListener(mathListener);
		butDao.addActionListener(mathListener);
		butEqu.addActionListener(mathListener);
		butBackspace.addActionListener(mathListener);
		butCE.addActionListener(mathListener);
		butC.addActionListener(mathListener);
	}
	
	//以下的几种情况如果成立,则返回true,否则返回false。
	public boolean isEnd(String str){
		boolean temp = false;
		//不允许以运算符开头
		if(str.matches("")){
			temp = true;
		}
		//如果一个数字以运算结尾,后面不得再次输入运算符
		if(str.endsWith("+")||str.endsWith("-")||str.endsWith("*")||
				str.endsWith("/")||str.endsWith("sqr")||str.endsWith("1/x")||
				str.endsWith("%")||str.endsWith(".")){
			temp = true;
		}
		//如果两个数字中间出现过运算符,后面不得再次输入运算符
		if(str.matches("\\d+\\+\\d+")||str.matches("\\d+\\-\\d+")
				||str.matches("\\d+\\*\\d+")||str.matches("\\d+\\/\\d+")){
			temp = true;
		}
		return temp;
	}
	
	//如果运算符是求平方根、求倒数这两种情况,则不允许后面出现数字
	public boolean isOver(String str){
		boolean temp = false;
		if(str.endsWith("sqr")){
			temp = true;
		}
		if(str.endsWith("1/x")){
			temp = true;
		}
		return temp;
	}
	
	//添加菜单中的复制,粘贴功能
	public void editMethod(){
		copyItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				StringSelection contents = new StringSelection(tf.getText());
				clipboard.setContents(contents,null);
			}
		});
		patseItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				//首选要判断剪贴板中是否包含可以剪贴的内容
				if(clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)){
					String str = null;
					try {
						str = (String)clipboard.getData(DataFlavor.stringFlavor);
						tf.setText(str);
					} catch (UnsupportedFlavorException e1) {
						e1.printStackTrace();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
	}
	
	//构造方法
	public Calculator(){}
	
	public static void main(String[] args) {
		new Calculator().init();
	}
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值