瘋狂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();
	}
}



發佈了18 篇原創文章 · 獲贊 13 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章