因为是新手(很纯的那种),所以有点凌乱,代码很渣很冗余(后面会精简),命名规则请无视。当然这个计算器还只是能跑起来的程度,估计会有莫名其妙的错误,比如我的指数运算的指数只支持整数等。毕竟是第一次自己独立写一个小东西,还是很开心的。
1.主要部分(布局以及点击事件ActionEvent监听)
package 计算器;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class JiSuanQi {
//三个基础布局组件
Frame f = new Frame("计算器");
TextField t = new TextField("0",40);
Panel p = new Panel(new GridLayout(5,4,10,10)); //panel是网格布局
//加载业务逻辑
YeWuLuoJi ywlj = new YeWuLuoJi();
//button String
String strNum = "0123456789";
String strToken = "+-*/";
String strEqual = "=";
String strPoint = ".";
String strClear = "c";
String[] buttonStr = {"c","+/-","x^2","x^y","1","2","3","+","4","5","6","-","7","8","9","*","0",".","=","/"};
//监听事件
ActionListener al = null;
//创建并添加Button,并加入监听事件
public void init() {
for(String i : buttonStr) {
Button b = new Button(i);
b.addActionListener(getAL());
p.add(b);
}
f.addWindowListener(new windowL());
f.add(t,BorderLayout.NORTH);
f.add(p); //默认是BorderLayout.CENTER布局
f.pack(); //自适应合适大小
f.setVisible(true); //f设置为可见
}
//获取监听事件,注意匿名内部类不要使用局部变量,因为一个在内存堆中,一个在栈中,生命周期不同
public ActionListener getAL() {
if(al==null) {
al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String buttonStr1 = e.getActionCommand(); //返回与事件向关联的组件的名称
String textStr = t.getText();
result = ywlj.yewuMethod(buttonStr1,textStr); //运行业务逻辑
t.setText(textStr);
}
}; //这只是一条语句,分号结尾
}
return al;
}
//窗口关闭事件
class windowL extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
new JiSuanQi().init();
}
}
2.运算规则部分(运用了BigDecimal,不是很熟悉)
package 计算器;
import java.math.BigDecimal;
public class YunSuan {
//--------------------------加法
public static String plus(String a,String b) {
BigDecimal bigA = new BigDecimal(a); //最好用String来构造BigDecimal
BigDecimal bigB = new BigDecimal(b);
return bigA.add(bigB).toString();
}
//---------------------------减法
public static String minus(String a,String b) {
BigDecimal bigA = new BigDecimal(a+""); //最好用String来构造BigDecimal
BigDecimal bigB = new BigDecimal(b+"");
return bigA.subtract(bigB).toString();
}
//--------------------------乘法
public static String multi(String a,String b) {
BigDecimal bigA = new BigDecimal(a+""); //最好用String来构造BigDecimal
BigDecimal bigB = new BigDecimal(b+"");
return bigA.multiply(bigB).toString();
}
//------------------------除法
public static String divide(String a,String b) {
BigDecimal bigA = new BigDecimal(a+""); //最好用String来构造BigDecimal
BigDecimal bigB = new BigDecimal(b+"");
return bigA.divide(bigB).toString();
}
//-------------------------平方运算
public static String square(String a ) {
BigDecimal bigA = new BigDecimal(a);
return bigA.multiply(bigA).toString();
}
//------------------------x^y的幂指数运算
public static String zhishu(String a ,int b){
BigDecimal bigA = new BigDecimal(a);
BigDecimal bigZ = bigA;
for(int i=1;i<b;i++) {
bigZ = bigA.multiply(bigZ);
}
return bigZ.toString();
}
}
3.主要的业务逻辑(主要是各种按键的切换点击逻辑)
package 计算器;
public class YeWuLuoJi {
//Button标签
private String strNum = "0123456789";
private String strZF = "+/-";
private String[] strToken = {"+","-","*","/","x^y"};
private String strSquare = "x^2";
private String strEqual = "=";
private String strPoint = ".";
private String strClear = "c"; //clear键,复位
//状态记录码
String fInt = null; boolean f = false; //第一个数字,如果第一个数字也为0呢(联合刻画记录第一次点击的数字),如果获取的是double类型呢,怎么复制
String sInt = null; boolean s = false; //第二个数字,s刻画记录第二次点击的数字
String token = ""; boolean tokenClickIf = false; //是否点击运算符号
boolean equalClickIf = false; //是否点击等于号
boolean zfClickIf = false; //是否点击正负号 +/-
//返回的应该是是设置textField的string-》textStr
public String yewuMethod(String buttonStr,String textStr ) {
//获取的button字符,如果没点击数字button,事件监听监听到的(还要分int和double)
//如果第一个数字没有初始化,那么将第一个数字初始化(分int和double)
if(f==false && isNum(buttonStr)) {
//初始化第一位数字, 并且f->true
fInt = buttonStr;
f=true;
//将textStr设置为该数字对应的String
textStr = String.valueOf(fInt);
}
//已经点击下第一位数字,但没有点击运算符号而是继续点击第二个数字,比如点击12这样的数字
else if(f==true && isNum(buttonStr) && tokenClickIf==false) {
textStr = textStr + buttonStr;
fInt = textStr;
}
//设置了第一个数字后,点击运算符号
else if(f==true && isToken(buttonStr) && tokenClickIf == false) {
tokenClickIf = true;
token = buttonStr; //记录点击的运算符号
zfClickIf = false; // 复位正负号状态
}
//点击的第二个数字
else if(f==true && s==false && tokenClickIf==true && isNum(buttonStr)) {
textStr = buttonStr;
sInt = textStr;
s= true;
}
//第二个数字的连续点击输入
else if(f==true && s==true && tokenClickIf==true && isNum(buttonStr)) {
textStr = textStr + buttonStr;
sInt = textStr;
}
//已经点击过运算符号,且设置过第一和第二个数字,继续点击运算符号,关键是如果结果是double怎么赋予第一个数值
else if(f==true && s==true && tokenClickIf==true && isToken(buttonStr)) {
//更新文本框中的计算结果
textStr = jisuan(buttonStr);
//将计算所得的结果赋予第一个数字
fInt = textStr;
}
//如果点击的是点point
else if (isPoint(buttonStr)) {
if(hasPoint(textStr)==false) {
textStr = textStr+buttonStr;
if(f==true) {
if(s==false)
fInt = textStr;
else
sInt = textStr;
}
}
}
//如果点击的是正负号
else if(f==true && isZF(buttonStr)) {
if(s==false && zfClickIf==false) { //第二个数字没有赋值,或者已经运算结束被初始化了
textStr = "-"+textStr;
fInt = textStr;
zfClickIf=true;
}
else if (s==true && zfClickIf==false) {
textStr = "-"+textStr;
sInt = textStr;
zfClickIf=true;
}
//连续点击正负号
else if (s==false && zfClickIf == true) {
textStr = textStr.split("-")[1];
fInt = textStr;
zfClickIf = false;
}
else if (s==true && zfClickIf==true) {
textStr = textStr.split("-")[1];
sInt = textStr;
zfClickIf = false;
}
}
//如果点击的是等于号“=”
else if(f==true && s==true && tokenClickIf==true && isEqual(buttonStr)) {
textStr = jisuan(token);
fInt = textStr;
//更新状态
s=false;
zfClickIf = false;
//pointClickIf = false; 浮点运算的话,还是不要清除point的状态,要不然结果还能继续加point
tokenClickIf=false;
token="";
sInt = null;
}
//点击的是平方符号
else if (f==true && isSquare(buttonStr)) {
textStr = YunSuan.square(fInt);
fInt = textStr;
//复位正负号
zfClickIf=false;
}
//点击复位键,clear
else if(isClear(buttonStr)) {
//复位全部状态
fInt = null; f = false; //第一个数字,如果第一个数字也为0呢(联合刻画记录第一次点击的数字),如果获取的是double类型呢,怎么复制
sInt = null; s = false; //第二个数字,s刻画记录第二次点击的数字
token = ""; tokenClickIf = false; //是否点击运算符号
equalClickIf = false; //是否点击等于号
zfClickIf = false;
textStr = "0";
}
return textStr;
}
//判断点击的是否为数字,strNum.split("")返回的是一个按界定符切割后的String数组
public boolean isNum(String buttonStr) {
for(String i:strNum.split("")) {
if(buttonStr.equals(i))
return true;
}
return false;
}
//判断按键是否为运算符号token
public boolean isToken(String buttonStr) {
for(String i:strToken) {
if (buttonStr.equals(i))
return true;
}
return false;
}
//是否正负号
public boolean isZF(String buttonStr) {
if(buttonStr.equals(strZF))
return true;
return false;
}
//是否是平方
public boolean isSquare(String buttonStr) {
if(buttonStr.equals(strSquare))
return true;
return false;
}
//判断按键是否为等于号
public boolean isEqual(String buttonStr) {
if(buttonStr.equals(strEqual))
return true;
return false;
}
//判断是否为点point
public boolean isPoint(String buttonStr) {
if(buttonStr.equals(strPoint))
return true;
return false;
}
//判断是否为复位键
public boolean isClear(String buttonStr) {
if(buttonStr.equals(strClear))
return true;
return false;
}
//用于判断文本中是否有point
public boolean hasPoint(String textStr) {
for(String i : textStr.split("")) {
if(i.equals("."))
return true;
}
return false;
}
//计算
public String jisuan(String buttonStr) {
if(buttonStr.equals("+"))
return YunSuan.plus(fInt,sInt);
else if(buttonStr.equals("-"))
return YunSuan.minus(fInt,sInt);
else if(buttonStr.equals("*"))
return YunSuan.multi(fInt,sInt);
else if(buttonStr.equals("/"))
return YunSuan.divide(fInt,sInt);
else if(buttonStr.equals("x^y"))
return YunSuan.zhishu(fInt,Integer.parseInt(sInt));
return "";
}
}