刚学Java,想写个东西练练,觉得一开始写个不太复杂的计算器练练应该还行,没有系统地学习swing,用的是eclipse里的插件WindowBuilder,可以直接通过拉拽组件的方式来构造页面,像是之前用Android Studio的感觉。
我先构造了这样的一个页面,功能一部分一部分地来实现。还有就是对于布局没去怎样学,用的是绝对定位,即Absolute layout,然后将页面设置成固定大小,不可拉伸。
现在已经实现的有+,-,×,÷,括号还没有,这几天事有点多,先把这一块放上来,等接下来逐步完善了再放上来。
把面板代码贴上来吧,回去看了下代码,还是算了吧,面板代码是自动生成的,除了按钮的触发事件,这种也没必要。
弄点主要一点的代码。
这是目前运算过程中定义的变量。
//输入、输出显示结果
private String input="";
private String output[]={"计算结果为:","输入存在错误!","超出计算范围!"};
private char inputData[]=null; //记录输入字符串转换成的字符数组
private char fu[]; //记录输入运算式的运算符
private double answer[]; //作为栈进行计算
private String fianswer; //最后输出的答案
private String resultStr[]=null; //运算式按运算符拆分后的String数组
private double result[]; //将String数组内容转换为double数组,可进行运算
思路很简单,就是面板的构造函数中,按钮触发事件后,将输入的内容存到String input中,然后在等号按下,即触发后,开始对input的内容进行处理。
主要函数有:
//正常运算,不出现问题
public void normalCal(){
//初始化栈用于运算
answer=new double[2];
answer[0]=result[0];
answer[1]=0;
boolean flag=false; //作为标志,先计算“+-”为true,先计算“*/”为false
//遍历fu[]数组,取得对应result[]数组中的运算方式
for(int i=0;i<fu.length;i++){
if(fu[i]=='+'){
answer[0]=answer[0]+answer[1];
answer[1]=0;
answer[1]+=result[i+1];
flag=true;
}
if(fu[i]=='-'){
answer[0]=answer[0]+answer[1];
answer[1]=0;
answer[1]-=result[i+1];
flag=true;
}
if(fu[i]=='×'){
if(flag){ //第一个运算符为“+-"
answer[1]=answer[1]*result[i+1];
}else{ //第一个运算符为“*/"
answer[0]=answer[0]*result[i+1];
}
}
if(fu[i]=='÷'){
if(flag){ //第一个运算符为“+-"
answer[1]=answer[1]/result[i+1];
}else{ //第一个运算符为“*/"
answer[0]=answer[0]/result[i+1];
}
}
}
answer[0]=answer[0]+answer[1]; //为计算结果
//判断答案小数点后几位,当小数位过多导致出现double精度问题时,四舍五进
//如2.1*3,double型答案为6.300000000000001,将其四舍五进为6.3000000000000
String strTemp=answer[0]+""; //将double型转换为String
if(strTemp.length()-strTemp.indexOf('.')-1>=15){
DecimalFormat df = new DecimalFormat("0.0000000000000");
fianswer=df.format(answer[0]);
}else{
fianswer=strTemp;
}
forResult(0);
}
//将输入字符串按符号拆分,及将所有运算符号放置在一个char数组中
public void splitIn(){
//拆分字符串
resultStr=input.split("\\+|-|×|÷");
result=new double[resultStr.length];
for(int i=0;i<resultStr.length;i++){
result[i]=Double.parseDouble(resultStr[i]);
}
//将运算式的所以运算符放在一个char数组中
fu=new char[resultStr.length-1];
int num=0;
for(int i=0;i<inputData.length;i++){
switch(inputData[i]){
case '+':fu[num]='+';num++;break;
case '-':fu[num]='-';num++;break;
case '×':fu[num]='×';num++;break;
case '÷':fu[num]='÷';num++;break;
}
}
}
//输出结果
public void forResult(int choice){
switch(choice){
case 0:textOutput.setText(output[0]+fianswer);break;
case 1:textOutput.setText(output[1]);break;
}
}
//重置
public void reset(){
textInput.setText("");
textOutput.setText("");
input="";
}
基本就是这样,即在“=”按下前,只会对input的内容进行增加或减少,并将其显示在计算器面板上,当按下“=”后才会对input的内容进行拆分、转型、运算等,然后再将结果输出。
接下来或许会将函数改成带参数形式的,现在考虑得太不周全了,试试能不能将带括号的运算式写成递归的方式,每个括号里的字符串递归下去,知道不包含括号了,也就是现在这样的,将现在的运算函数写成带参数的应该比较容易实现递归。
还有foreach,还不是很习惯用成这种。
还有就是现在所有的数据都是double类型,等往后逐步完善的时候看看能不能用成泛型的形式。