新写的一个计算器,里面还有部分bug,望大家指正

  1 package org.xn.chapter11.practice;
  2 /**
  3  * 课后习题1:做一个计算器,这里我们以windows-XP中的calc计算器的标准型为目标来做
  4  * 程序分解:
  5  * 1、GUI界面:
  6  *         菜单栏:编辑(复制,粘贴)、查看、帮助
  7  *         单行文本框:
  8  *         回退键:Backspace、CE、C
  9  *         数字键:1-9 、“0”、“.” 、“+/-”
 10  *         计算键:+ 、- 、* 、/ ;sqrt 、% 、1/x 、 =
 11  * 
 12  * 2、计算核心:
 13  *         数字button监听类
 14  *         计算方法button监听类
 15  *         回退button监听类
 16  * 
 17  * 总结:
 18  *         计算器的大部分功能都得到了实现,比如:最基本的四则运算、3个特殊运算、3个不同的回退方法、
 19  * 文本框只允许出现数字和运算符、运算时不能以运算符开头、一次运算自能输入一个运算符、特殊运算符只有一个数字、
 20  * 菜单栏中只实现了编辑菜单中的复制、粘贴两个功能、
 21  * 
 22  * 已知bug:
 23  *         1、在键盘输入的时候,不能保证输入的运算符总是在末尾
 24  *         2、
 25  * 
 26  * 
 27  * */
 28 
 29 import java.awt.BorderLayout;
 30 import java.awt.Button;
 31 import java.awt.Color;
 32 import java.awt.Frame;
 33 import java.awt.GridLayout;
 34 import java.awt.Menu;
 35 import java.awt.MenuBar;
 36 import java.awt.MenuItem;
 37 import java.awt.MenuShortcut;
 38 import java.awt.Panel;
 39 import java.awt.TextField;
 40 import java.awt.Toolkit;
 41 import java.awt.datatransfer.Clipboard;
 42 import java.awt.datatransfer.DataFlavor;
 43 import java.awt.datatransfer.StringSelection;
 44 import java.awt.datatransfer.UnsupportedFlavorException;
 45 import java.awt.event.ActionEvent;
 46 import java.awt.event.ActionListener;
 47 import java.awt.event.KeyAdapter;
 48 import java.awt.event.KeyEvent;
 49 import java.awt.event.WindowAdapter;
 50 import java.awt.event.WindowEvent;
 51 import java.io.IOException;
 52 
 53 import javax.swing.Box;
 54 
 55 public class Calculator{
 56     Frame f = new Frame("计算器");//窗体
 57     MenuBar mb = new MenuBar();//菜单
 58     Box bMod = Box.createHorizontalBox();//水平盒子,用来盛放三个修改按钮
 59     Box bTop = Box.createVerticalBox();//垂直盒子,用来盛放文本行+水平盒子
 60     //利用Toolkit工具包类取得系统工具包,在系统工具包中取得系统剪贴板
 61     Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
 62     
 63     TextField tf = new TextField(20);//文本行
 64     Panel p = new Panel();//用来盛放数字键+运算符
 65     
 66     Panel numPan = new Panel();//定义数字键盘
 67     Panel mathPan1 = new Panel();//定义加减乘除
 68     Panel mathPan2 = new Panel();//定义开方、求模、求倒数、等于
 69     
 70     Menu edit = new Menu("编辑");
 71     Menu select = new Menu("查看");
 72     Menu help = new Menu("帮助");
 73     
 74     MenuItem copyItem = new MenuItem("复制",new MenuShortcut(KeyEvent.VK_C));
 75     MenuItem patseItem = new MenuItem("粘贴",new MenuShortcut(KeyEvent.VK_P));
 76     
 77     MenuItem standard = new MenuItem("标准型");
 78     MenuItem science = new MenuItem("科学型");
 79     MenuItem group = new MenuItem("数字分组");
 80     
 81     MenuItem item = new MenuItem("帮助主题");
 82     MenuItem about = new MenuItem("关于计算器");
 83     Button but1 = new Button("1");
 84     Button but2 = new Button("2");
 85     Button but3 = new Button("3");
 86     Button but4 = new Button("4");
 87     Button but5 = new Button("5");
 88     Button but6 = new Button("6");
 89     Button but7 = new Button("7");
 90     Button but8 = new Button("8");
 91     Button but9 = new Button("9");
 92     Button but0 = new Button("0");
 93     Button butFuhao = new Button("+/-");
 94     Button butDian = new Button(".");
 95     
 96     Button butAdd = new Button("+");
 97     Button butSub = new Button("-");
 98     Button butMul = new Button("*");
 99     Button butDiv = new Button("/");
100     
101     Button butSqr = new Button("sqr");
102     Button butDao = new Button("1/x");
103     Button butMo = new Button("%");
104     Button butEqu = new Button("=");
105     
106     Button butBackspace = new Button("Backspace");
107     Button butCE = new Button("CE");
108     Button butC = new Button("C");
109     
110     public void init(){
111         //为运输符号按钮设置颜色
112         butAdd.setForeground(Color.RED);
113         butSub.setForeground(Color.RED);    
114         butMul.setForeground(Color.RED);    
115         butDiv.setForeground(Color.RED);    
116         butSqr.setForeground(Color.RED);            
117         butMo.setForeground(Color.RED);    
118         butDao.setForeground(Color.RED);    
119         butEqu.setForeground(Color.RED);    
120         butBackspace.setForeground(Color.RED);    
121         butCE.setForeground(Color.RED);    
122         butC.setForeground(Color.RED);    
123         //添加按钮
124         edit.add(copyItem);
125         edit.add(patseItem);
126         select.add(standard);
127         select.add(science);
128         select.add(group);
129         help.add(item);
130         help.add(about);
131         mb.add(edit);
132         mb.add(select);
133         mb.add(help);
134         bMod.add(butBackspace);
135         bMod.add(butCE);
136         bMod.add(butC);
137         bTop.add(tf,BorderLayout.NORTH);
138         bTop.add(bMod);
139         // 设置Panel使用GridLayout布局管理器
140         numPan.setLayout(new GridLayout(4, 4 , 4, 4));
141         mathPan1.setLayout(new GridLayout(4, 2 , 4, 4));
142         mathPan2.setLayout(new GridLayout(4, 2 , 4, 4));
143         //将生成的按钮添加到组件上
144         numPan.add(but1);
145         numPan.add(but2);
146         numPan.add(but3);
147         numPan.add(but4);
148         numPan.add(but5);
149         numPan.add(but6);
150         numPan.add(but7);
151         numPan.add(but8);
152         numPan.add(but9);
153         numPan.add(but0);
154         numPan.add(butFuhao);
155         numPan.add(butDian);
156         mathPan1.add(butAdd);
157         mathPan1.add(butSub);
158         mathPan1.add(butMul);
159         mathPan1.add(butDiv);
160         mathPan2.add(butSqr);
161         mathPan2.add(butDao);
162         mathPan2.add(butMo);
163         mathPan2.add(butEqu);
164         //为关闭窗体添加监听事件
165         f.addWindowListener(new WindowAdapter(){
166             public void windowClosing(WindowEvent e){
167                 System.exit(1);
168             }
169         });
170         
171         //为单行文本框添加键盘监听,只允许输入数字和运算符号,其他的输入一律无效
172         tf.addKeyListener(new KeyAdapter(){
173             public void keyReleased(KeyEvent e){
174                 char c = e.getKeyChar();
175                 byte b = (byte)c;
176                 if(b==10){
177                     String temp = tf.getText();
178                     if(temp.matches("\\S+\\+\\S+")){
179                         String num[] = temp.split("\\+");
180                         double result = Double.parseDouble(num[0])+Double.parseDouble(num[1]);
181                         tf.setText(result+"");
182                         return;
183                     }
184                     //求两个数的差值
185                     if(temp.matches("\\S+\\-\\S+")){
186                         String num[] = temp.split("\\-");
187                         double result = 0.0;
188                         if(num.length==2){
189                             result = Double.parseDouble(num[0])-Double.parseDouble(num[1]);
190                         }
191                         if(num.length==3){
192                             result = -Double.parseDouble(num[1])-Double.parseDouble(num[2]);
193                         }
194                         tf.setText(result+"");
195                         return;
196                     }
197                     //求两个数的积
198                     if(temp.matches("\\S+\\*\\S+")){
199                         String num[] = temp.split("\\*");
200                         double result = Double.parseDouble(num[0])*Double.parseDouble(num[1]);
201                         tf.setText(result+"");
202                         return;
203                     }
204                     //求一个数的倒数,求倒数应该在求商的前面,避免发生混淆
205                     if(temp.matches("\\S+[1/x]\\S+")){
206                         String num[] = temp.split("1/x");
207                         double result = 1/Double.parseDouble(num[0]);
208                         tf.setText(result+"");
209                         return;
210                     }
211                     //求两个数的商,这里的求商要和求倒数区分开来
212                     if(temp.matches("\\d+\\/\\d+")){
213                         String num[] = temp.split("\\/");
214                         double result = Double.parseDouble(num[0])/Double.parseDouble(num[1]);
215                         tf.setText(result+"");
216                         return;
217                     }
218                     //求一个数的平方根
219                     if(temp.matches("\\S+sqr")){
220                         String num[] = temp.split("sqr");
221                         double result = Math.sqrt(Double.parseDouble(num[0]));
222                         tf.setText(result+"");
223                         return;
224                     }
225                     //求两个数相除的模(即余数)
226                     if(temp.matches("\\S+\\%\\S+")){
227                         String num[] = temp.split("\\%");
228                         double result = Double.parseDouble(num[0])%Double.parseDouble(num[1]);
229                         tf.setText(result+"");
230                         return;
231                     }
232                 }
233                 if(!(b>=42&&b<=57)){
234                     tf.setText("");
235                 }
236             }
237         });
238         
239         //将组件添加到窗体中
240         p.add(numPan);
241         p.add(mathPan1);
242         p.add(mathPan2);
243         f.setMenuBar(mb);
244         f.add(bTop,BorderLayout.NORTH);
245         f.add(p);
246         //设置用户不能调整窗体大小
247         f.setResizable(false); 
248         //设置窗口为最佳大小
249         f.pack();
250         //将窗口显示出来(Frame对象默认处于隐藏状态)
251         f.setVisible(true);
252         //添加数字按钮和运算按钮的监听事件
253         Operate();
254         //添加复制、粘贴的监听方法
255         editMethod();
256     }
257     
258     //定义操作方法,包括了数字和计算方法的监听
259     public void  Operate(){
260         //定义数字按钮的监听事件
261         ActionListener numListener = new ActionListener(){
262             public void actionPerformed(ActionEvent e){
263                 if(e.getActionCommand().equals("1")){
264                     if(isOver(tf.getText())){
265                         return;
266                     }
267                     tf.setText(tf.getText()+"1");
268                 }
269                 if(e.getActionCommand().equals("2")){
270                     if(isOver(tf.getText())){
271                         return;
272                     }
273                     tf.setText(tf.getText()+"2");
274                 }
275                 if(e.getActionCommand().equals("3")){
276                     if(isOver(tf.getText())){
277                         return;
278                     }
279                     tf.setText(tf.getText()+"3");
280                 }
281                 if(e.getActionCommand().equals("4")){
282                     if(isOver(tf.getText())){
283                         return;
284                     }
285                     tf.setText(tf.getText()+"4");
286                 }
287                 if(e.getActionCommand().equals("5")){
288                     if(isOver(tf.getText())){
289                         return;
290                     }
291                     tf.setText(tf.getText()+"5");
292                 }
293                 if(e.getActionCommand().equals("6")){
294                     if(isOver(tf.getText())){
295                         return;
296                     }
297                     tf.setText(tf.getText()+"6");
298                 }
299                 if(e.getActionCommand().equals("7")){
300                     if(isOver(tf.getText())){
301                         return;
302                     }
303                     tf.setText(tf.getText()+"7");
304                 }
305                 if(e.getActionCommand().equals("8")){
306                     if(isOver(tf.getText())){
307                         return;
308                     }
309                     tf.setText(tf.getText()+"8");
310                 }
311                 if(e.getActionCommand().equals("9")){
312                     if(isOver(tf.getText())){
313                         return;
314                     }
315                     tf.setText(tf.getText()+"9");
316                 }
317                 if(e.getActionCommand().equals("0")){
318                     if(isOver(tf.getText())){
319                         return;
320                     }
321                     tf.setText(tf.getText()+"0");
322                 }
323                 if(e.getActionCommand().equals(".")){
324                     String str = tf.getText();
325                     if(isEnd(str)){//如果程序以运输符号结尾则无法再输入任何运输符
326                         return;
327                     }
328                     if(str.matches("\\d+\\.\\d+")){
329                         return;
330                     }
331                     tf.setText(tf.getText()+".");
332                 }
333                 if(e.getActionCommand().equals("+/-")){
334                     String str = tf.getText();
335                     if(isEnd(str)){//如果程序以运输符号结尾则无法再输入任何运输符
336                         return;
337                     }
338                     if(str.matches("-\\d+")){
339                         char[] c = str.toCharArray();
340                         tf.setText(new String(c,1,c.length-1));
341                     }else{
342                         tf.setText("-"+str);
343                     }
344                 }
345             }
346         };
347         //定义计算按钮的监听事件
348         ActionListener mathListener = new ActionListener(){
349             public void actionPerformed(ActionEvent e){
350                 if(e.getActionCommand().equals("+")){
351                     if(isEnd(tf.getText())){//如果程序以运输符号结尾则无法再输入任何运输符
352                         return;
353                     }
354                     tf.setText(tf.getText()+"+");
355                 }
356                 if(e.getActionCommand().equals("-")){
357                     if(isEnd(tf.getText())){
358                         return;
359                     }
360                     tf.setText(tf.getText()+"-");
361                 }
362                 if(e.getActionCommand().equals("*")){
363                     if(isEnd(tf.getText())){
364                         return;
365                     }
366                     tf.setText(tf.getText()+"*");
367                 }
368                 if(e.getActionCommand().equals("/")){
369                     if(isEnd(tf.getText())){
370                         return;
371                     }
372                     tf.setText(tf.getText()+"/");
373                 }
374                 if(e.getActionCommand().equals("sqr")){
375                     if(isEnd(tf.getText())){
376                         return;
377                     }
378                     tf.setText(tf.getText()+"sqr");
379                 }
380                 if(e.getActionCommand().equals("1/x")){
381                     if(isEnd(tf.getText())){
382                         return;
383                     }
384                     tf.setText(tf.getText()+"1/x");
385                 }
386                 if(e.getActionCommand().equals("%")){
387                     if(isEnd(tf.getText())){
388                         return;
389                     }
390                     tf.setText(tf.getText()+"%");
391                 }
392                 if(e.getActionCommand().equals("Backspace")){
393                     String temp = tf.getText();
394                     if(temp.length()==0){
395                         return;
396                     }
397                     char[] c = temp.toCharArray();
398                     tf.setText(new String(c,0,c.length-1));
399                 }
400                 if(e.getActionCommand().equals("CE")){
401                     String temp = tf.getText();
402                     String[] num = temp.split("\\D");
403                     if(num.length==1){
404                         tf.setText("");
405                     }
406                     if(num.length==2){
407                         tf.setText(num[0]);
408                     }
409                 }
410                 if(e.getActionCommand().equals("C")){
411                     tf.setText("");
412                 }
413                 //输入等号的时候,对TextField中输入的文字进行运算
414                 if(e.getActionCommand().equals("=")){
415                     String temp = tf.getText();
416                     if(temp.matches("\\S+\\+\\S+")){
417                         String num[] = temp.split("\\+");
418                         double result = Double.parseDouble(num[0])+Double.parseDouble(num[1]);
419                         tf.setText(result+"");
420                         return;
421                     }
422                     //求两个数的差值
423                     if(temp.matches("\\S+\\-\\S+")){
424                         String num[] = temp.split("\\-");
425                         double result = 0.0;
426                         if(num.length==2){
427                             result = Double.parseDouble(num[0])-Double.parseDouble(num[1]);
428                         }
429                         if(num.length==3){
430                             result = -Double.parseDouble(num[1])-Double.parseDouble(num[2]);
431                         }
432                         tf.setText(result+"");
433                         return;
434                     }
435                     //求两个数的积
436                     if(temp.matches("\\S+\\*\\S+")){
437                         String num[] = temp.split("\\*");
438                         double result = Double.parseDouble(num[0])*Double.parseDouble(num[1]);
439                         tf.setText(result+"");
440                         return;
441                     }
442                     //求一个数的倒数,求倒数应该在求商的前面,避免发生混淆
443                     if(temp.matches("\\S+[1/x]\\S+")){
444                         String num[] = temp.split("1/x");
445                         double result = 1/Double.parseDouble(num[0]);
446                         tf.setText(result+"");
447                         return;
448                     }
449                     //求两个数的商,这里的求商要和求倒数区分开来
450                     if(temp.matches("\\d+\\/\\d+")){
451                         String num[] = temp.split("\\/");
452                         double result = Double.parseDouble(num[0])/Double.parseDouble(num[1]);
453                         tf.setText(result+"");
454                         return;
455                     }
456                     //求一个数的平方根
457                     if(temp.matches("\\S+sqr")){
458                         String num[] = temp.split("sqr");
459                         double result = Math.sqrt(Double.parseDouble(num[0]));
460                         tf.setText(result+"");
461                         return;
462                     }
463                     //求两个数相除的模(即余数)
464                     if(temp.matches("\\S+\\%\\S+")){
465                         String num[] = temp.split("\\%");
466                         double result = Double.parseDouble(num[0])%Double.parseDouble(num[1]);
467                         tf.setText(result+"");
468                         return;
469                     }
470                 }
471             }
472         };
473         //为所有的按钮添加监听事件
474         but1.addActionListener(numListener);
475         but2.addActionListener(numListener);
476         but3.addActionListener(numListener);
477         but4.addActionListener(numListener);
478         but5.addActionListener(numListener);
479         but6.addActionListener(numListener);
480         but7.addActionListener(numListener);
481         but8.addActionListener(numListener);
482         but9.addActionListener(numListener);
483         but0.addActionListener(numListener);
484         butDian.addActionListener(numListener);
485         butFuhao.addActionListener(numListener);
486         butAdd.addActionListener(mathListener);
487         butSub.addActionListener(mathListener);
488         butMul.addActionListener(mathListener);
489         butDiv.addActionListener(mathListener);
490         butSqr.addActionListener(mathListener);
491         butMo.addActionListener(mathListener);
492         butDao.addActionListener(mathListener);
493         butEqu.addActionListener(mathListener);
494         butBackspace.addActionListener(mathListener);
495         butCE.addActionListener(mathListener);
496         butC.addActionListener(mathListener);
497     }
498     
499     //以下的几种情况如果成立,则返回true,否则返回false。
500     public boolean isEnd(String str){
501         boolean temp = false;
502         //不允许以运算符开头
503         if(str.matches("")){
504             temp = true;
505         }
506         //如果一个数字以运算结尾,后面不得再次输入运算符
507         if(str.endsWith("+")||str.endsWith("-")||str.endsWith("*")||
508                 str.endsWith("/")||str.endsWith("sqr")||str.endsWith("1/x")||
509                 str.endsWith("%")||str.endsWith(".")){
510             temp = true;
511         }
512         //如果两个数字中间出现过运算符,后面不得再次输入运算符
513         if(str.matches("\\d+\\+\\d+")||str.matches("\\d+\\-\\d+")
514                 ||str.matches("\\d+\\*\\d+")||str.matches("\\d+\\/\\d+")){
515             temp = true;
516         }
517         return temp;
518     }
519     
520     //如果运算符是求平方根、求倒数这两种情况,则不允许后面出现数字
521     public boolean isOver(String str){
522         boolean temp = false;
523         if(str.endsWith("sqr")){
524             temp = true;
525         }
526         if(str.endsWith("1/x")){
527             temp = true;
528         }
529         return temp;
530     }
531     
532     //添加菜单中的复制,粘贴功能
533     public void editMethod(){
534         copyItem.addActionListener(new ActionListener(){
535             public void actionPerformed(ActionEvent e) {
536                 StringSelection contents = new StringSelection(tf.getText());
537                 clipboard.setContents(contents,null);
538             }
539         });
540         patseItem.addActionListener(new ActionListener(){
541             public void actionPerformed(ActionEvent e) {
542                 //首选要判断剪贴板中是否包含可以剪贴的内容
543                 if(clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)){
544                     String str = null;
545                     try {
546                         str = (String)clipboard.getData(DataFlavor.stringFlavor);
547                         tf.setText(str);
548                     } catch (UnsupportedFlavorException e1) {
549                         e1.printStackTrace();
550                     } catch (IOException e1) {
551                         e1.printStackTrace();
552                     }
553                 }
554             }
555         });
556     }
557     
558     //构造方法
559     public Calculator(){}
560     
561     public static void main(String[] args) {
562         new Calculator().init();
563     }
564 }
View Code

 

转载于:https://www.cnblogs.com/xn6517/p/4660990.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值