您的位置:首页 > 编程语言 > Java开发

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



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: