一点感悟
最初看这个代码时,看不懂!
最大的困惑就是运算符这块,当你输入第一个运算数,再输入运算符,这个时候没有第二个运算数,是无法进行运算的,百事不得其解!!
突然想到用System.out.println();来观察程序的运行顺序!!!
然后有了重大发现!!!!
举个例子:当你输入第一个运算数时,再输入+号,而之前声明operator默认为=,所以执行的是=的方法,将第一个运算数赋值给中间变量resultNum;(这个设计很精妙)
再令operator=label,即operator=“+”;
然后再输入第二个运算数,由 getNumBerFromText()方法获取;
接着输入=,但此时operator=“+”;故而执行+的方法,resultNum+=getNumberFrom!!!!!
原程序有些bug,已改进
1、±运算
2、handleBackspace有点小问题
最初看这个代码时,看不懂!
最大的困惑就是运算符这块,当你输入第一个运算数,再输入运算符,这个时候没有第二个运算数,是无法进行运算的,百事不得其解!!
突然想到用System.out.println();来观察程序的运行顺序!!!
然后有了重大发现!!!!
举个例子:当你输入第一个运算数时,再输入+号,而之前声明operator默认为=,所以执行的是=的方法,将第一个运算数赋值给中间变量resultNum;(这个设计很精妙)
再令operator=label,即operator=“+”;
然后再输入第二个运算数,由 getNumBerFromText()方法获取;
接着输入=,但此时operator=“+”;故而执行+的方法,resultNum+=getNumberFrom!!!!!
原程序有些bug,已改进
1、±运算
2、handleBackspace有点小问题
感谢别人的分享,模仿是最好的老师,站在巨人的肩膀上才能看得更远!!!!!!
感谢别人的帮助,并学会去帮助别人!!!!!!!
package cn.bjsxt.swingCalculator;
/**
* 1.继承,super()
* 2.数组的声明,赋值,初始化,方法
* 3.构造器,构造器里可以写哪些方法
* 4.String类好好看看,一些常用方法要熟悉
* 5.学会使用API,不知道的方法百度
* 6.养成写注释的习惯
* 7.方法里可以嵌套方法,独立的方法之间又相互联系
* 8.用假设法,举例法验证自己的猜想,注意程序的顺序,注意细节!!!
* 9。善用System.out.println()进行检查,观察程序的执行顺序
* 10.学会debug进行调试
* 11.抽象方法
* 12.类变量,实例变量;类方法,实例方法
* 13.局部变量和全局变量
* 14.C键的处理方法,与其思考怎么去删除(过程),不如考虑删除后的样子(结果)
* 15.思考任何问题都可以从过程和结果两方面考虑
* 16.举反例帮助理解,如果不这样会怎样!!!
* 17.try,catch语句
* 18.对于各种控制语句学会灵活运用
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;
/*
* 编写一个计算器,与Windows附件计算器标准版的功能、界面相仿,但不支持键盘输入。
*/
public class Calculator extends javax.swing.JFrame implements ActionListener {
//计算器上键的显示名字
private final String KEY[]={"7","8","9","/","√","4","5","6","*","%","1","2","3","-","1/x","0","±",".","+","="};//数组常量,常量名大写
//计算器上的功能键显示的名字
private final String COMMAND[]={"Backspace","CE","C"};
//计算器左边的M的显示名字
private final String M[]={"MC","MR","MS","M+","M-"};
//计算器上键的按钮
private JButton key[]=new JButton[KEY.length];
//计算器上的功能键的按钮
private JButton command[]=new JButton[COMMAND.length];
//计算器左边的M键的按钮
private JButton m[]=new JButton[M.length];
//计算结果文本框
private JTextField resultText=new JTextField("0");
//标志用户按的是否是整个表达式的第一个数字,或是运算符后的第一个数字
private boolean firstDigit=true;
//计算的中间结果
private double resultNum=0.0;
//当前运算的运算符
private String operator="=";
//操作是否合法
private boolean operateValidFlag=true;
//构造函数********************************
public Calculator(){
super();
//初始化计算器
init();
//设置计算器的背景颜色
this.setBackground(Color.LIGHT_GRAY);
//设置计算器的标题
this.setTitle("我是计算器");
//在屏幕(500,300)坐标处显示计算器
this.setLocation(500,300);
//不能修改计算器的大小
this.setResizable(false);
//使计算器各组件大小合适
this.pack();//Causes this Window to be sized to fit the preferred size and layouts of its subcomponents.
}
//初始化计算器**************************
private void init() {
// TODO Auto-generated method stub
//文本框中内容采用右对齐方式
resultText.setHorizontalAlignment(JTextField.RIGHT);
//不允许修改结果文本框
resultText.setEditable(false);
//设置文本框背景颜色为白色
resultText.setBackground(Color.white);
//初始化计算器上键的按钮,将键画在一个面板内
JPanel calkeyPanel=new JPanel();
//用网格布局管理器,创建一个4行5列的网格,网格的水平间距为3个像素,垂直间距为3个像素
calkeyPanel.setLayout(new GridLayout(4,5,3,3));
for(int i=0;i<KEY.length;i++){
key[i]=new JButton(KEY[i]);
calkeyPanel.add(key[i]);
key[i].setForeground(Color.BLUE);
}
//运算符键用红色标示,其他键用蓝色表示
key[3].setForeground(Color.red);
key[8].setForeground(Color.red);
key[13].setForeground(Color.red);
key[18].setForeground(Color.red);
key[19].setForeground(Color.red);
//初始化功能键,都用红色表示,将功能键放在一个画板内
JPanel commandPanel=new JPanel();
//用网格布局器,创建1行3列的网格,水平间距为3个像素,垂直间距为3个像素
commandPanel.setLayout(new GridLayout(1,3,3,3));
for(int i=0;i<COMMAND.length;i++){
command[i]=new JButton(COMMAND[i]);
commandPanel.add(command[i]);
command[i].setForeground(Color.red);
}
//初始化M键,用红色表示,将其放在一个面板内
JPanel calmPanel=new JPanel();
//用网格布局器,创建5行1列的网格,网格之间的水平间距为3个像素,垂直间距为3个像素
calmPanel.setLayout(new GridLayout(5,1,3,3));
for(int i=0;i<M.length;i++){
m[i]=new JButton(M[i]);
calmPanel.add(m[i]);
m[i].setForeground(Color.red);
}
//下面进行计算器的整体布局,将calkeyPanel和commandPanel面板放在计算器的中部
//将文本框放在北部,calmPanel面板放在西部
//新建一个大的画板,将calkeyPanel和commandPanel面板放在其中
JPanel panel1=new JPanel();
//画板采用边框布局管理器,画板里组件之间垂直和水平间距为3像素
panel1.setLayout(new BorderLayout(3,3));
panel1.add("North",calkeyPanel);
panel1.add("West",commandPanel);
//创建一个画板放文本框
JPanel top=new JPanel();
top.setLayout(new BorderLayout());
top.add("Center",resultText);
//整体布局
//public Container getContentPane() {return getRootPane().getContentPane();}
getContentPane().setLayout(new BorderLayout(3,5));
getContentPane().add("North",top);// public Component add(String name, Component comp)
getContentPane().add("West", calmPanel);
getContentPane().add("Center",panel1);
//为各按钮添加事件监听器
//都使用同一个事件监听器,即本对象。本类的声明中有implements ActionListener
for(int i=0;i<KEY.length;i++){
key[i].addActionListener(this);
}
for(int i=0;i<COMMAND.length;i++){
command[i].addActionListener(this);
}
for(int i=0;i<M.length;i++){
m[i].addActionListener(this);
}
}
//处理事件***************************************************
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//获取事件源的标签
String lable=e.getActionCommand();
if(lable.equals(COMMAND[0])){
//用户按了“Backspace”键
handleBackspace();
}else if(lable.equals(COMMAND[1])){
//用户按了“CE”键
resultText.setText("0");
}else if(lable.equals(COMMAND[2])){
//用户按了“C”键
handleC();
}else if("1234567890.".indexOf(lable)>=0){
//用户按了数字键或小数点键
handleNum(lable);
}else{
//用户按了运算符键
handleOperator(lable);
}
}
//处理运算符按下的事件*******************************************
private void handleOperator(String key) {
// TODO Auto-generated method stub
if(operator.equals("/")){
//除法运算
//如果当前文本框中的值为零
if(getNumberFromText()==0.0){
//操作不合法
operateValidFlag=false;
resultText.setText("除数不能为0");
}else{
resultNum=resultNum/getNumberFromText();
}
}else if(operator.equals("1/x")){
//倒数运算
if(resultNum==0.0){
//操作不合法
operateValidFlag=false;
resultText.setText("0没有倒数!");
}else{
resultNum=1/resultNum;
}
}else if(operator.equals("+")){
//加法运算
resultNum=resultNum+getNumberFromText();
System.out.println("计算器");
System.out.println(resultNum);
System.out.println(getNumberFromText());
}else if(operator.equals("-")){
//减法运算
resultNum=resultNum-getNumberFromText();
}else if(operator.equals("*")){
//乘法运算
resultNum=resultNum*getNumberFromText();
}else if(operator.equals("√")){
//平方根运算
resultNum=Math.sqrt(resultNum);
}else if(operator.equals("%")){
//百分号运算
resultNum=resultNum/100;
}else if(operator.equals("±")){
//正负号运算
resultNum=resultNum*(-1);
}else if(operator.equals("=")){
//赋值运算
resultNum=getNumberFromText();
System.out.println(getNumberFromText());
}
if(operateValidFlag){
//双精度浮点数的运算
long t1;
double t2;
t1=(long)resultNum;
t2=resultNum-t1;
if(t2==0){
resultText.setText(String.valueOf(t1));
System.out.println("t1=t2");
}else{
resultText.setText(String.valueOf(resultNum));
System.out.println("t1!!=t2");
}
}
//运算符等于用户按的按钮
operator=key;
firstDigit=true;
operateValidFlag=true;
}
//从结果文本框中获取数字**********************************
private double getNumberFromText() {
// TODO Auto-generated method stub
double result=0;
try{
//public static Double valueOf(String s)
//throws NumberFormatException
//返回保存用参数字符串 s 表示的 double 值的 Double 对象。
//如果 s 为 null,则抛出 NullPointerException 异常。
//public double doubleValue()
//返回此 Double 对象的 double 值。
result=Double.valueOf(resultText.getText()).doubleValue();
}catch(NumberFormatException e){
}
return result;
}
//处理数字键***************************************
private void handleNum(String key) {
// TODO Auto-generated method stub
if(firstDigit){
//输入的第一个数字
resultText.setText(key);
}else if((key.equals("."))&&(resultText.getText().indexOf(".")<0)){
//输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面
resultText.setText(resultText.getText()+".");
}else if(!key.equals(".")){
//如果输入的不是小数点,则将数字附在结果文本框的后面
resultText.setText(resultText.getText()+key);
}
//以后输入的肯定不是第一个数字
firstDigit=false;
}
//处理C键***************************************************
private void handleC() {
// TODO Auto-generated method stub
//初始化计算器的各种值
resultText.setText("0");
firstDigit=true;
operator="=";
}
//处理Backspace键被按下的事件*************************************
private void handleBackspace() {
// TODO Auto-generated method stub
String text=resultText.getText();//获取文本框的内容赋给变量text
int i=text.length();
if(i>0){
//退格,将文本最后一个字符去掉
text=text.substring(0, i-1);
if(text.length()==0){
//如果文本框只有1个字符,按下Backspace键后文本框字符为0
resultText.setText("0");
//如果文本框没有内容,则初始化计算器的各种值
firstDigit=true;
operator="=";
}else{
//显示新的文本
resultText.setText(text);
}
}
}
//主方法,程序的入口***************************************************
public static void main(String[] args){
Calculator calculator1=new Calculator();
calculator1.setVisible(true);
calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}