疯狂java讲义中的习题,设计一个简单的计算器。
2015-07-24 21:42
621 查看
这是一个模仿xp下的计算器的标准版,当然bug是肯定存在的,代码里都有详细批注,望大家指正。 /** * 课后习题1:做一个计算器,这里我们以windows-XP中的calc计算器的标准型为目标来做 * 程序分解: * 1、GUI界面: * 菜单栏:编辑(复制,粘贴)、查看、帮助 * 单行文本框: * 回退键:Backspace、CE、C * 数字键:1-9 、“0”、“.” 、“+/-” * 计算键:+ 、- 、* 、/ ;sqrt 、% 、1/x 、 = * * 2、计算核心: * 数字button监听类 * 计算方法button监听类 * 回退button监听类 * * 3、总结: * 计算器的大部分功能都得到了实现,比如:最基本的四则运算、3个特殊运算、3个不同的回退方法、 * 文本框只允许出现数字和运算符、运算时不能以运算符开头、一次运算自能输入一个运算符、特殊运算符只有一个数字、 * 菜单栏中只实现了编辑菜单中的复制、粘贴两个功能、 * * 4、已知bug: * 1、在键盘输入的时候,不能保证输入的运算符总是在末尾 * * 5、联系方式: * QQ:1037784758 * * 6、最后一次修改日期: * 2015.7.19 * * */ 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(); } }
相关文章推荐
- org.springframework.web.util.NestedServletException:
- Java 注解
- Spring(九)让Spring自动扫描和管理Bean
- Java Type VS Hibernate Type
- hadoop开发:eclipse运行wordcount实例
- How to Compile Java DBus
- java 命令行参数输入法的应用
- JAVA中的String连接性能
- Java设计模式之单例模式
- 设计模式第一讲:单例模式(IBM开发者论坛已经发表的文章)
- Java学习篇------Java文本框
- netBeans调试时不进入java内部类(jdk源码)的方法
- java.util.Random.nextInt(int n)方法实例
- MyEclipse常见错误汇总,中英注释版(长期更新)
- JDK开发WebService
- struts ognl表达式底层执行原理
- Java常用知识(长期更新)
- java多线程学习笔记(1)——基本概念介绍
- struts2 模型分配问题和延迟加载问题
- JavaWeb实现登录注册与验证码。