package javaBasic;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.math.*;
import java.text.NumberFormat;
public class Calculator1 extends JFrame{
/**
*
*/
private static final long maxRange = 1l;
private final static int SettledWidth = 500;
private final static int SettledHigh = 400;
private JPanel panel;//显示区
private JPanel panel1;//功能键包装区
private JMenuBar mb;//参考笔记本上的计算器有版本选择
private JMenu m1,m2,m3;
private JMenuItem mi1,mi2,mi3;
private JLabel show;//参考笔记本计算器,最终结果的显示加上特殊效果以突出
private String result = " ";
private JLabel input;
private JLabel error;
private String[] fun = {"MC","M+","M-","MR","AC","back","(",")","7","8","9","÷","4","5","6","x","1","2","3","-",".","0","=","+"};
private JButton[] funb = new JButton[fun.length];
public static void main(String[] args) {
new Calculator1();
}
public Calculator1() {
this.setTitle("夏夏计算器");
this.setSize(SettledWidth, SettledWidth);
this.setLocationRelativeTo(null);
this.setResizable(false);
panel = new JPanel();
panel1 = new JPanel();
//panel.setLayout(new BorderLayout(10,1));
//panel.add(getTextField(), BorderLayout.NORTH);
//panel.setPreferredSize(new Dimension(SettledWidth, SettledWidth));
show = new JLabel();
error = new JLabel();
input = new JLabel();
//菜单1.0版本
mb = new JMenuBar();
m1 = new JMenu("版本选择");
m2 = new JMenu("帮助");
m3 = new JMenu("关于");
mi1 = new JMenuItem("标准");
mi2 = new JMenuItem("程序员");
mi3 = new JMenuItem("科学");
m1.add(mi1);
m1.add(mi2);
m1.add(mi3);
mb.add(m1);
mb.add(m2);
mb.add(m3);
//突出显示结果
show.setText("0");
show.setHorizontalAlignment(JLabel.RIGHT);
show.setFont(new Font("arial", Font.BOLD, 22));
show.setForeground(Color.CYAN);
//显示信息 同笔记本计算器版本右对齐字体
input.setText(" ");
input.setHorizontalAlignment(JLabel.RIGHT);
input.setFont(new Font("",Font.ROMAN_BASELINE,10));
//输入信息有误时提示
error.setText(" ");
error.setHorizontalAlignment(JLabel.RIGHT);
error.setFont(new Font("arial",Font.ROMAN_BASELINE,10));
error.setForeground(Color.YELLOW);
panel.setLayout(new BorderLayout());
//将显示部分装到窗口载体
panel.add(show,BorderLayout.SOUTH);
panel.add(input,BorderLayout.CENTER);
panel.add(error,BorderLayout.NORTH);
panel.setBorder(new BevelBorder(BevelBorder.RAISED,Color.LIGHT_GRAY,null,SystemColor.scrollbar, null));
//功能键布局设置为网格布局
panel1.setLayout(new GridLayout(6,6,4,4));
panel1.setBorder(new BevelBorder(BevelBorder.RAISED,Color.PINK, null, SystemColor.scrollbar, null));
//功能键
for(int i=0;icountsOfSubstringInString(result,")")){
error.setText("')'少了哦~");
result = result.substring(0,result.length() - 1);
}
else if(input.getText().indexOf("/")!=-1) {
String s = " ";
int indexOfDiv = indexOfNumberEnd(temp,temp.indexOf("/"));
s = temp.substring(temp.indexOf("/")+1,indexOfDiv);
if(parse(s) == Double.parseDouble("0")) {
error.setText("0不能做被除数!");
result = result.substring(0,result.length()-1);
}
else {
calculate();
}
}
else {
calculate();
}
}
}
}
private void calculate() {
result = String.valueOf(parse(result.substring(0,result.length()-1)));
show.setText(formatResult(result));
}
private String formatResult(String result) {//显示结果部分
String finalResult = "";
Double d = Double.valueOf(result);
NumberFormat f = NumberFormat.getInstance();
f.setGroupingUsed(false);
if(Math.abs(d) >= 1 || Math.abs(d) == 0) {
finalResult = f.format(d);
}
else {
finalResult = d.toString();
}
return finalResult;
}
//back功能
private void backSpace() {
if(result.length() == 1 || result.equals("")) {
result = " ";
input.setText(result);
}
else {
result = result.substring(0,result.length()-1);
if(result.endsWith(" ")) {
result = result.substring(0,result.length()-1);
}
input.setText(result);
}
error.setText(" ");
}
//清屏功能
private void clear() {
error.setText(" ");
input.setText(" ");
show.setText(" ");
result = " ";
}
private static String parseInputStr(String result,String content) {
if(result.equals(" ") || result.equals("")) {
if(content.matches("\\d+|\\-|\\(*")) {//利用正则表达式限制输入的首元素
result = "".concat(content);
}
}
else if(content.equals(")")) {//只有当左括号大于右括号数量时才能输入右括号
boolean flag = result.matches(".*\\d$|.*\\)$");
if(countsOfSubstringInString(result, "(") > countsOfSubstringInString(result, ")") && flag) {
result = result.concat(content);
}
else {
result = result.concat("");
}
}
else if(Pattern.matches(".*\\d$",result)) {//以数字结尾
if(lastNumberOfStr(result).matches("^0+") && !content.matches("\\+|\\-|\\*|÷|\\.|=")) {
result = result + "";
}
else if(content.matches("1/x")) {
result = parseDigitEndWithFuncthion(result,content);
}
else if(Pattern.matches(".*\\.\\d+$", result)) {//小数点后不能再出现小数点
result = result.concat(content.matches("\\d*|\\+|\\-|\\*|÷|\\)|=")?content:"");
}
else if(content.matches("\\d|\\.")) {//数字或者小数点
result = result.concat(content);
}
else
result = result.concat(content.matches("\\+|\\-|\\*|÷|\\)|=") ? " " + content : "");
}
else if(Pattern.matches(".*\\.$", result) && Pattern.matches("^\\d", content)) {//小数点结尾
result = result.concat(content);
}
else if ((result).matches(".*\\($")) {//左括号作结的情况
result = result.concat(content.matches("\\d*|π|\\-|\\(") ? content : "");
}
else if(Pattern.matches(".*\\)$", result)) {//右括号作结的情况
if(content.matches("\\+|\\-|\\*|÷|=")) {
result = result + " " + content;
}
if(content.matches("\\)")) {
result = result + content;
}
if(content.matches("1/x")) {
result = parseBrackets(result,content);
}
}
else if(result.matches(".*\\+$|.*\\-$|.*\\*$|.*÷$|.*/$")) {//以加减乘除作结的情况
result = result.replaceAll("÷", "/");
if(result.matches(".*\\/$|.*\\+$|.*\\*$")) {
result = result + content;
}
if(result.matches(".*\\-$")) {//减号作结的情况
if(result.length() == 1) {
result = result + (content.matches("\\(|\\d")?content:"");
}
else if(result.length()>1) {
boolean b = result.charAt(result.length()-2) == ')';
if(b) {
result = result + (content.matches("\\(|\\d")?content:"");
}
else {
result = result +(content.matches("\\(|\\d")?" "+content : "");
}
}
else {
result = result + (content.matches("\\(|\\d")?" "+content : "");
}
}
}
return result;
}
private static double parse(String content) {
if(content.contains("1/x")) {
content = content.replace("1/x","rec");
}
if (content.contains("*-") || content.matches(".*(\\*\\s\\-).*")) {
content = content.replaceAll("\\*\\s\\-", "*-");
content = multiplicationAndDivisionOfNegative(content,"/");
}
if(content.contains("--")||content.matches(".*(\\-\\s\\-).*")) {//负负得正
content = content.replaceAll("\\-\\s\\-", "+");
content = content.replaceAll("\\-\\-", "+");
}
int index = content.indexOf("rec");//倒数
if(index != -1) {
int endindex = indexOfOpecifiedMirrorBacket(content,'(',index +3);
double d = parse("1/" + content.substring(index + 3,endindex + 1));
return parse(content.substring(0,index) + d + content.substring(endindex + 1));
}
int startindex = content.indexOf("(");//处理括号
boolean b = countsOfSubstringInString(content,"(") == countsOfSubstringInString(content,"(");
if(startindex != -1 && b) {
int endindex = indexOfFirstMirrorBracket(content,'(');
double d = parse(content.substring(startindex + 1,endindex));
return parse(content.substring(0,startindex) + d + content.substring(endindex+1));
}
index = content.indexOf("+");
if(index != -1) {
return parse(content.substring(0,index))+parse(content.substring(index + 1));
}
index = content.indexOf("-");
if(index != -1) {
return parse(content.substring(0,index))-parse(content.substring(index + 1));
}
index = content.indexOf("*");
if(index != -1) {
return parse(content.substring(0,index))*parse(content.substring(index + 1));
}
index = content.indexOf("/");
if(index != -1) {
return parse(content.substring(0,index))/parse(content.substring(index + 1));
}
if(content.equals("")||content.equals(" ")) {
content = "0";
}
return Double.parseDouble(content);
}
private static int countsOfSubstringInString(String str,String sub) {//求子串数量
int sum = 0;
String subHead = "";
String subTrail = "";
while(str.contains(sub)) {
sum ++;
subHead = str.substring(0,str.indexOf(sub));
subTrail = str.substring(subHead.length() + sub.length());
str = subHead + subTrail;
}
return sum;
}
private static int indexOfFirstMirrorBracket(String str,char ch) {
int indexResult = -1;
int sum = 0;
if(countsOfSubstringInString(str,"(") == countsOfSubstringInString(str,")")) {
if(ch == '(') {
int index = str.indexOf(ch) - 1;
do {
index ++;
if(str.charAt(index) == '(') {
sum ++;
}
if(str.charAt(index) == ')') {
sum --;
}
}while(sum !=0 && index < str.length());
indexResult = index -1;
}
if(ch == ')') {
int index = str.lastIndexOf(ch);
do {
if(str.charAt(index) == ')') {
sum ++;
}
if(str.charAt(index) == '(') {
sum --;
}
}while(sum !=0 && index >= 0);
}
}
return indexResult + 1;
}
private static int indexOfOpecifiedMirrorBacket(String str,char c,int index) {
int indexResult = -1;
int sum = 0;
int startIndex = -1;
int endIndex = -1;
StringBuffer sb = new StringBuffer(str);
if(countsOfSubstringInString(str,"(") == countsOfSubstringInString(str,"(")) {
if(index == 0 || index == str.length() - 1) {
return indexOfFirstMirrorBracket(str,c);
}
else if(c == '(') {
sum = countsOfSubstringInString(str.substring(0,index),String.valueOf(c));
while(sum != 0) {
startIndex = sb.indexOf("(");
endIndex = indexOfFirstMirrorBracket(sb.toString(),c);
sb = sb.replace(startIndex, startIndex + 1, "a").replace(endIndex,endIndex + 1, "a");
sum --;
}
indexResult = indexOfFirstMirrorBracket(sb.toString(), c);
}
else if(c == ')') {
sum = countsOfSubstringInString(str.substring(index + 1),String.valueOf(c));
while(sum != 0) {
startIndex = sb.indexOf(")");
endIndex = indexOfFirstMirrorBracket(sb.toString(),c);
sb = sb.replace(startIndex, startIndex + 1, "a").replace(endIndex,endIndex + 1, "a");
sum --;
}
indexResult = indexOfFirstMirrorBracket(sb.toString(), c);
}
}
return indexResult;
}
private static int indexOfLeftOperator(String str,int sfi) {//在具体位置前最近的一个算术运算符位置
int t = -1;
if(sfi >= 1 && str.substring(0,sfi).matches(".*(\\-|\\+|\\*|/).*")) {
do {
sfi --;
}while(!String.valueOf(str.charAt(sfi)).matches("\\+|\\-|\\*|/"));
t = sfi;
}
return t;
}
private static int indexOfRightOperator(String str,int sfi) {//在具体位置前最远的一个算术运算符位置
int t = -1;
boolean b = sfi >= 0 && sfi <= str.length() - 1 && str.substring(sfi + 1).matches(".*(\\+|\\-|\\*|/).*");
if(b) {
while(!String.valueOf(str.charAt(sfi + 1)).matches("\\+|\\*|/")) {
sfi ++;
}
t = sfi + 1;
}
return t;
}
private static String multiplicationAndDivisionOfNegative(String content, String operator) {
int indexfun = content.indexOf(operator); int startindex = indexOfLeftOperator(content, indexfun);// indexfun左边最近的运算符+-*/的位置
if (startindex == -1) {
content = "-" + content.substring(0, content.indexOf(operator) + 1) + content.substring(content.indexOf(operator) + 2);
}
if (startindex != -1) {
if (content.substring(indexfun, indexfun + 2).equals(operator + "-")) {
String tempstr = "-" + content.substring(startindex + 1, indexfun + 1);
content = content.substring(0, startindex + 1) + tempstr + content.substring(indexfun + 2);
}
}
return content;
}
private static int indexOfNumberStart(String result) {//找到数字结尾的字符串结尾位置开始往前的一个完整数字的位置
int resultIndex = -1;
int indexOfOperator = indexOfLeftOperator(result, result.length() - 1);// 该位置前面第一个运算符位置
if (indexOfOperator == -1) {//前面没有运算符
indexOfOperator = result.lastIndexOf('(');
if (indexOfOperator == -1)
resultIndex = 0;
else resultIndex = indexOfOperator + 1;
}
else {
if(result.charAt(indexOfOperator) == '-' && result.charAt(indexOfOperator + 1) != ' ') resultIndex = indexOfOperator;
else{
while (result.charAt(indexOfOperator + 1) == '(' || result.charAt(indexOfOperator + 1) == ' ') indexOfOperator++;
resultIndex = indexOfOperator + 1;
}
}
return resultIndex;
}
private static int indexOfNumberEnd(String result, int index) {//找到数字结尾的字符串结尾位置开始往后的一个完整数字的位置
int resultIndex = -1;
int indexOfOperator = indexOfRightOperator(result, index + 1);
String subStrStart = result.substring(0, index + 1);
String subStrEnd = result.substring(index + 1); if (indexOfOperator == -1) {// 没有运算符
if (result.substring(index + 1).contains("(")) {
int startIndex = subStrStart.length() + subStrEnd.indexOf('(');
int endIndex = indexOfOpecifiedMirrorBacket(result, '(', startIndex); resultIndex = endIndex + 1;
}
else if (indexOfOperator == -1) {
while (index < result.length() && String.valueOf(result.charAt(index + 1)).matches("\\s|\\d|\\.")) index++;
resultIndex = index + 1;
}
}
else {
if (result.substring(index + 1, indexOfOperator).contains("(")) { int startIndex = subStrStart.length() + subStrEnd.indexOf('(');
int endIndex = indexOfOpecifiedMirrorBacket(result, '(', startIndex); resultIndex = endIndex + 1;
}
else resultIndex = indexOfOperator;
}
return resultIndex;
}
private static String lastNumberOfStr(String result) {
int indext = indexOfLeftOperator(result,result.length() - 1);
boolean b = String.valueOf(result.charAt(result.length() - 1)).matches("\\d");
if(indext <= result.length() - 1 && b) {
while(!String.valueOf(result.charAt(indext + 1)).matches("\\d")) {
indext ++;
}
return result.substring(indext + 1);
}
else {
return "";
}
}
private static String parseBrackets(String result,String content) {//右括号后面跟着的求倒数
String t = "";
int startIndex = indexOfFirstMirrorBracket(result, ')');
int indexOfOperator = indexOfLeftOperator(result, startIndex);
String substrhead = "";
String substrtrail = "";
if(indexOfOperator == -1) {
substrtrail = result;
}
else {
substrhead = result.substring(0, indexOfOperator + 2);
substrtrail = result.substring(indexOfOperator + 2);
}
if(content.equals("1/x")) {
if (substrtrail.startsWith("(") && substrtrail.endsWith(")") && indexOfFirstMirrorBracket(substrtrail, '(') == substrtrail.length() - 1) {
t = substrhead + "rec" + substrtrail;
}
else {
t = substrhead + "rec(" + substrtrail + ")";
}
}
if (t.startsWith("(") && t.endsWith(")") && indexOfFirstMirrorBracket(t, '(') == t.length() - 1) {
t = t.substring(1, t.length() - 1);
}
return t;
}
private static String parseDigitEndWithFuncthion(String result, String content) {
String t = "";
String tcontent = "";
if(content.equals("1/x")) {
tcontent = "rec";
}
int startIndex = indexOfNumberStart(result);// 数字开头 ~
String substrhead = result.substring(0, startIndex);
String substrtrail = result.substring(startIndex);
if (result.startsWith("-") && startIndex == 1) {
if (tcontent == "!") {
t = "-" + result.substring(startIndex) + "!";
}
else {
t = tcontent + "(" + result + ")";
}
}
else { if (tcontent == "!") {
if (substrtrail.endsWith("π") || substrtrail.matches(".*\\.\\d*[1-9]+$"))
t = result; else t = substrhead + substrtrail + tcontent;
}
else
t = substrhead + tcontent + "(" + substrtrail + ")";
}
return t;
}
}