packagecal;import javax.swing.*;import java.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;public classCalculator {
JFrame frame;
JPanel panel;
JButton[][] buttons;
JTextField resultShow;
JTextField expShow;
String inputStr;
buttonAction Action;
Double num;intbrakets;intleftBraket;intrightBraket ;//以下为输入规则
static String comand = "C="; //不做任何处理的特殊符号
static String chars[] ={"", //第一个输入,前面没有任何字符
"1 2 3 4 5 6 7 8 9 0","+ -","* /", //3
"(",")","%",".", //END
"","" //最后一个必须是空,且不能删除
};static String jump[] = { //需要跳过不输入的字符
"0()/%C=","C=", //1..9
")%C=", //+-
"%)C=", //*/
"%+-*/)C=", //(
"1234567890.C=", //)
"(%.1234567890C=", //天
"(.C=","" //最后一个必须是空,且不能删除
};static String riplsx[] = { //如果前面是chars 对应字符,需要将chars 替换为replace
"","","+-*/","+-*/", //3
"","","","+-*/%)","" //最后一个必须是空,且不能删除
};static String rls2str[][] ={
{".","+","-","*"},
{"("},
{"."},
{"."},
{"."},
{"("},
{""},
{""} };static String rlsstr[][] ={
{"0.","0+","0-","0*"},
{"*("},
{"0."},
{"0."},
{"0."},
{"*("},
{""},
{""},
{""} //最后一个必须是空,且不能删除
};static String charBool = "123456789/*-+.0()";publicCalculator() {//TODO 自动生成的构造函数存根
frame = new JFrame("计算器GUI"); //新建frame 设置标题
panel = new JPanel(); //创建面板
Action = new buttonAction(); //创建监听实例
inputStr = new String(""); //初始显示
resultShow = newJTextField();
expShow= newJTextField();
num= 0.0;
brakets= 0;
leftBraket= 0;
rightBraket= 0;
}public voidshow() {
frame.setSize(480,400); //设置frame大小
frame.setLayout(new GridBagLayout()); //使用 表格包布局
frame.setResizable(false); //frame大小不可改变
frame.setLocationRelativeTo(null);
resultShow.setHorizontalAlignment(SwingConstants.RIGHT);//文字右对齐
resultShow.setColumns(18); //设置文本框的列数是18
resultShow.setBackground(Color.white);
resultShow.setEditable(false); //不可编辑
resultShow.setText("0");
resultShow.setSize(400,100);
resultShow.setFont(new Font("null",Font.BOLD,40));
resultShow.setBorder(null);
GridBagConstraints contains= newGridBagConstraints();
contains.weightx= 1;
contains.weighty= 1;
contains.gridx= 0;
contains.gridy= 1;
contains.gridwidth= 4;
contains.gridheight= 1;
contains.ipadx= 350;
contains.ipady= 80;
contains.fill=GridBagConstraints.HORIZONTAL;this.frame.add(resultShow,contains);this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
expShow.setHorizontalAlignment(SwingConstants.RIGHT);//文字右对齐
expShow.setColumns(18); //设置文本框的列数是18
expShow.setBackground(Color.white);
expShow.setEditable(false); //不可编辑
expShow.setText("");
expShow.setSize(400,60);
expShow.setFont(new Font("null",0,25));
expShow.setBorder(null);
contains.gridy= 0;
contains.ipady= 70;this.frame.add(expShow,contains);int k = 0;
String strtemp= "()%C789/456*123-0.=+";
contains.gridwidth= 1;
contains.gridheight= 1;
contains.ipadx= 350;
contains.ipady= 80;
buttons= new JButton[5][4];for (int i = 0; i < 5;i++) {for (int j = 0;j < 4;j++){
buttons[i][j]= new JButton(strtemp.charAt(k++) + "");
contains.gridx=j;
contains.gridy= i + 2;if (i == 0 || 3 ==j) {
buttons[i][j].setBackground(new Color(245,245,245));
}else{
buttons[i][j].setBackground(Color.white);
}
buttons[i][j].setBorderPainted(false);
buttons[i][j].setFont(new Font("null",Font.ITALIC,30));
buttons[i][j].addActionListener(Action);this.frame.add(buttons[i][j],contains);
}
}this.frame.setVisible(true);
}class buttonAction implementsActionListener{
@Overridepublic voidactionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
String cmd=e.getActionCommand();try{
inputStr=addInput(cmd);
}catch(Exception e2) {//TODO: handle exception
System.out.println(e2.getMessage());return;
}switch(cmd) {case ")":
riteBrakets();
rightBraket++;break;case "(":
leftBraket++;break;case "C":
clear();break;case "=":
funResult();return;default:
}
freshShow(inputStr);
}private voidriteBrakets() {if (leftBraket <= rightBraket) { //如果左括号少,右括号取消
inputStr = inputStr.substring(0,inputStr.length() - 1);
freshShow(inputStr);
}
}public Double getAnser(String s) throws Exception{ //可以改动一点点 把减法变成加负数,但是好像意义不大,
s = s.replace("%","/100");int index = s.indexOf("("); //检测括号 优先计算 重复,直到计算完所有括号内容
while ( index != -1) {
String braStr=getFirstBraStr(s);
Double braDou;try{
braDou= this.getAnser(braStr);
}catch(Exception e) {throwe;
}
braStr= "(" + braStr + ")";
s= s.replace(braStr,String.valueOf(braDou)); //将结果补回去
index = s.indexOf("(");
}
index= s.indexOf('*'); //乘除法优先
while (index != -1) {
String leftNumStr;
String riteNumStr;
Double leftNumDou;
Double riteNumDou;
leftNumStr= getLeftStr(s,index); //获取左操作数
try{
leftNumDou= newDouble(leftNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("left含有非法字符",e);
}
riteNumStr= getRiteStr(s,index); //获取右操作数
try{
riteNumDou= newDouble(riteNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("含有非法字符",e);
}
String resultString= String.valueOf(leftNumDou *riteNumDou);
s= s.replace(leftNumStr + "*" +riteNumStr,resultString);
index= s.indexOf('*');
}
index= s.indexOf('/'); //乘除法优先
while (index != -1) {
String leftNumStr;
String riteNumStr;
Double leftNumDou;
Double riteNumDou;
leftNumStr= getLeftStr(s,index); //获取左操作数
try{
leftNumDou=Double.valueOf(leftNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("left含有非法字符",e);
}
riteNumStr= getRiteStr(s,index); //获取右操作数
try{
riteNumDou=Double.valueOf(riteNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("含有非法字符",e);
}
String resultString= String.valueOf(leftNumDou/riteNumDou);
s= s.replace(leftNumStr + "/" +riteNumStr,resultString);
index= s.indexOf("/");
}
index= s.indexOf("+"); //加减
while (index != -1) {
String leftNumStr;
String riteNumStr;
Double leftNumDou;
Double riteNumDou;
leftNumStr= getLeftStr(s,index); //获取左操作数
try{
leftNumDou=Double.valueOf(leftNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("left含有非法字符",e);
}
riteNumStr= getRiteStr(s,index); //获取右操作数
try{
riteNumDou=Double.valueOf(riteNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("含有非法字符",e);
}
String resultString= String.valueOf(leftNumDou +riteNumDou);
s= s.replace(leftNumStr + "+" +riteNumStr,resultString);
index= s.indexOf("+");
}
index= s.indexOf("-",1); //乘除法优先
while (index != -1 && index != 0) {
String leftNumStr;
String riteNumStr;
Double leftNumDou;
Double riteNumDou;
leftNumStr= getLeftStr(s,index); //获取左操作数
try{
leftNumDou= newDouble(leftNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("left含有非法字符",e);
}
riteNumStr= getRiteStr(s,index); //获取右操作数
try{
riteNumDou= newDouble(riteNumStr);
}catch(Exception e) {
System.out.println(e.getMessage());throw new Exception("含有非法字符",e);
}
String resultString= String.valueOf(leftNumDou -riteNumDou);
s= s.replace(leftNumStr + "-" +riteNumStr,resultString);
s= s.replace("--","-");
System.out.println("-value:" +s);
index= s.indexOf('-', 1);
}returnDouble.valueOf(s);
}public String getRiteStr(String s,intindex) {char chk[] = "+-*/()".toCharArray();int retVal =s.length();for (charval:chk) {int valIndex = s.indexOf(val,index + 1);if (valIndex != -1 && valIndex
retVal=valIndex;
}
}
System.out.println("sub:" + s.substring(index + 1,retVal));return s.substring(index + 1,retVal);
}public String getLeftStr(String s,intindex) {char chk[] = "+-*/()".toCharArray();int retVal = -1;for (charval:chk) {int valIndex = s.lastIndexOf(val,index - 1);if (valIndex >retVal) {
retVal=valIndex;
}
}return s.substring(retVal + 1,index);
}public String getFirstBraStr(String s) { //返回第一个最外层匹配括号之间的字符串 如果右括号不全。返回到末尾
if (s.indexOf("(") == -1) { //没有括号;
return "";
}int leftBra = 1;int riteBra = 0;int left = s.indexOf("(");int len =left;int strLen = s.length() - 1;while (leftBra > riteBra && len
System.out.println("NO:" + leftBra + riteBra + len +strLen);char ch = s.charAt(++len);if (ch == '(') {
leftBra++;
}else if (ch == ')') {
riteBra++;
}
}if (leftBra ==riteBra) {return s.substring(left + 1,len);
}return s.substring(left + 1,strLen + 1);
}private voidfunResult() {
String s=inputStr;
inputStr= "";if (s.length() == 0) {return;
}if (indexOfLastFunc(s) == s.length() - 1) {
s= s.substring(0,s.length() - 1);
}
s= tabBrakets(s); //补全括号
if (s.indexOf("=") == -1) {
expShow.setText(s+ "=");
}else{
expShow.setText(s);
}try{
System.out.print(s);
s=getAnser(s).toString();
}catch(Exception e) {
freshShow("ERROR");
}
freshShow(s);
}privateString chkFuncZore(String s) {int index =indexOfLastFunc(s);int dotIndex = s.indexOf('.',index + 1);if ( dotIndex == -1) { //没有小数点,当然可以输入啦
returns;
}while (s.lastIndexOf('0') == (s.length()- 1) ) {
s= s.substring(0,s.length() - 1);
}if (s.lastIndexOf('.') == (s.length() - 1)) {
s= s.substring(0,s.length() - 1);
}returns;
}private intindexOfLastFunc(String s) {
String chk= "+-*/(";int funIndex = -1;for (charch:chk.toCharArray()) {int index =s.lastIndexOf(ch);if (index >funIndex) {
funIndex=index;
}
}returnfunIndex;
}privateBoolean enableZore(String s) {int index =indexOfLastFunc(s);if (s.indexOf(index + 1,'.') != -1) { //有小数点,当然可以输入多个0啦
return true;
}
String str= s.substring(index + 1,s.length());try{
index=Integer.parseInt(str);
}catch(Exception e) {//TODO: handle exception
System.out.print(e.getMessage());
}if (index == 0) {return false;
}return true;
}privateBoolean enableDot(String s){int index =indexOfLastFunc(s);
System.out.print("Dot index:" +index);
System.out.print("Dot index:" + s.indexOf(index + 1,'.'));if (s.indexOf('.',index + 1) != -1) {return false;
}return true;
}private String tabBrakets(String s) { //自动补全右括号
while (rightBraket
s= s + ")";
rightBraket++;
}returns;
}private voidclear() {
inputStr= "";
leftBraket= 0;
rightBraket= 0;
expShow.setText("");
freshShow(inputStr);
}private String addInput(String in) throws Exception { //如果触碰规则,则抛出异常。没有将in 输入到input就不能返回字符串,必须抛出异常
System.out.println("输入字符是:" +in);
String s=inputStr;//START 这里是一些不好描述的特殊规则 应该只拦截非法输入 放行正确输入
if (in.equals("0") && !enableZore(s)) { //0 判断是否可用
throw new Exception("0不可输入");
}if (in.equals(".") && !enableDot(s)) {throw new Exception(".不可输入");
}if ("+-*/%=".indexOf(in) != -1) { //纠正操作副前面的小鼠点后多余的0
s =chkFuncZore(s);
}//END 这里是一些不好描述的特殊规则
if (comand.indexOf(in) != -1) { //comand里面的字符跳过不处理 也不能抛出异常
returns;
}int len = s.length(); //START 开始确定处理规则
int flag = 0;if(len == 0) {
;
}else{char ch = s.charAt(len - 1);
System.out.println("最后一个字符是:" +ch);for(String val:chars) {if (val.indexOf(ch) != -1) {
System.out.println("找到上一个字符规则" + ch + "falg:" +flag);break;
}
flag++;
}
}//一下是规则处理
if (flag == -1 || flag == chars.length - 1) { //如果有这一段,输入规则字符串最后一组就可以删除
return s + in; //如果没有找到对应规则
}//忽略规则
int index =jump[flag].indexOf(in);if (index != -1){throw new Exception("非法字符忽略");
}//替换规则
index =riplsx[flag].indexOf(in);if (index != -1) {
s= s.substring(0,s.length() - 1);return s +in;
}//变换规则
index = 0;for(String val:rls2str[flag]) {if(val.equals(in)) {return s +rlsstr[flag][index];
}
index++;
}return s +in;
}private voidfreshShow(String s) {if (s.length() == 0) {
resultShow.setText("0");
}else{
resultShow.setText(s);
}
System.out.println("当前:" +s);
}
}public static voidmain(String[] args) {//TODO 自动生成的方法存根
Calculator cal = newCalculator();
cal.show();
}
}