📄 calculator.java
字号:
}
/*********************************************/
/*********************************************************/
// 对运算符的计算+jb[49].-jb[43].*jb[37]./jb[31]
if(e.getSource()==jb[49]&&(("+-*/=^.(").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//"+"呵呵有点长。可设一个变量来判断
{
textField1.setText(textField1.getText()+"+");
}
if(e.getSource()==jb[43]&&(("+-*/=^.(").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//"-"
{
textField1.setText(textField1.getText()+"-");
}
if(e.getSource()==jb[37]&&(("+-*/=^.(").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//"*"
{
textField1.setText(textField1.getText()+"*");
}
if(e.getSource()==jb[31]&&(("+-*/=^.(").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//"/"
{
textField1.setText(textField1.getText()+"/");
}
/***_________________________________________位运算~!|&>><<________________________________________________________________*******/
if(e.getSource()==jb[51]&&(("+-*/=^.()<>sEng").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//Int
{
textField1.setText(""+(int)(Double.parseDouble(textField1.getText()))+"");
}
if(e.getSource()==jb[45])//Not
{
if(textField1.getText().equals("0."))//如果文本框中最初为”0.“这直接清零后再向其输入~
{
textField1.setText("");
textField1.setText(textField1.getText()+"~");
}
else if(!textField1.getText().equals("0.")&&("0123456789).!").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)//如果文本框中的内容不是“0.”且保证~符合不能直接跟在数字后面,及要让它跟在运算符后面
textField1.setText(textField1.getText()+"~");
}
if(e.getSource()==jb[33]&&(("+-*/=^.(<>sEng").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//And
{
textField1.setText(textField1.getText()+"&");
}
if(e.getSource()==jb[32]&&(("+-*/=^.(<>sEng").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//Mod
{
textField1.setText(textField1.getText()+"%");
}
if(e.getSource()==jb[38]&&(("+-*/=^.(<>sEng").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//Or
{
textField1.setText(textField1.getText()+"|");
}
if(e.getSource()==jb[44]&&(("123456789").indexOf(textField1.getText().charAt(textField1.getText().length()-1))!=-1)&&!textField1.getText().equals("0."))//Lsh
{
if(!jc1.isSelected())
textField1.setText(textField1.getText()+"<");
else
{
textField1.setText(textField1.getText()+">");
}
}
if(e.getSource()==jb[39]&&(("+-*/=^.(<>sEng").indexOf(textField1.getText().charAt(textField1.getText().length()-1))==-1)&&!textField1.getText().equals("0."))//异或
{
textField1.setText(textField1.getText()+"$");//这里乘方用了异或符号^,这里用$代替;
}
//----------------当用户按等号键以后对文本框中的计算式进行分析------------关键步骤
if(e.getSource()==jb[50])
{
Shiyan4 test = new Shiyan4();
try {
textField1.setText(""+test.evaluate(textField1.getText()));
} catch (Exception e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(this,"请输入正确格式的计算式!","出错啦",0);
// e1.printStackTrace();
}
}
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
for(int i=0;i<=57;i++)
if(arg0.getSource()==jb[i]&&jb[i].isEnabled())
jb[i].setBorder(BorderFactory.createBevelBorder(1));
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
for(int i=0;i<=57;i++)
if(arg0.getSource()==jb[i]&&jb[i].isEnabled())
jb[i].setBorder(BorderFactory.createBevelBorder(0));
}
//-----------三个内部类---------三个内部类---------------三个内部类---------三个内部类--------三个内部类----------三个内部类--------三个内部类--------三个内部类---------------------------//
//按Sta键后弹出的窗口
class MyDialog extends JFrame implements ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
static final int RETURN=1,LOAD=2,CLEAR=3,ALLCLEAR=4,CLOSE=-1;
int message=10;
Button returnback,load,clear,allclear;
JTextArea jta;
JLabel jl1;
JPanel jp00,jp0;
MyDialog()
{
jp00 = new JPanel();
jp0 = new JPanel();
jta = new JTextArea(4,21);
// jta.setText("由于在文本框中直接输入的是表达式,\n所以统计框在这里失去其存在的意义");
jta.append("由于在文本框中直接输入的是表达式,\n所以统计框在这里失去其存在的意义。\n这里只是形式上的存在~!");
returnback = new Button("返回(R)");
load = new Button("加载(L)");
clear = new Button("清零(C)");
allclear = new Button("全清(A)");
jl1 = new JLabel("n=0");
jp00.add(jta);
jp0.add(returnback);
jp0.add(load);
jp0.add(clear);
jp0.add(allclear);
returnback.addActionListener(this);
load.addActionListener(this);
clear.addActionListener(this);
allclear.addActionListener(this);
this.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
message=CLOSE;
setVisible(false);
}
});
this.setLayout(new FlowLayout());
this.setFont(new Font("宋体",Font.PLAIN,12));
this.setTitle("统计框");
this.add(jp00);
this.add(jp0);
this.add(jl1);
this.setVisible(false);
this.setResizable(false);
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getSource()==returnback)
{
message=RETURN;
}
if(arg0.getSource()==load)
{
message=LOAD;
}
if(arg0.getSource()==clear)
{
message=CLEAR;
}
if(arg0.getSource()==allclear)
{
message=ALLCLEAR;
}
}
public int getMessage()
{
return message;
}
}
//----------------------------内部类-进制转换类--------------------
class objConversion
{//本进制类参考了CSMD类转换例子
//public void objConversion ()
//{
//}
public String decDec (int decNum)
{//10
String strDecNum = Integer.toString(decNum);
for (int i = strDecNum.length(); i < 3; i++)
{
strDecNum = "0" + strDecNum;
}
// return strDecNum;
return invert (strDecNum, 5);
}
public String decHex (int decNum)
{//10 to 16
String strHexNum = "";
int currentNum = 0;
while (decNum != 0)
{
if (decNum > 15)
{
currentNum = decNum % 16;
decNum /= 16;
}
else
{
currentNum = decNum;
decNum = 0;
}
switch (currentNum)
{
case 15: strHexNum += "F";
break;
case 14: strHexNum += "E";
break;
case 13: strHexNum += "D";
break;
case 12: strHexNum += "C";
break;
case 11: strHexNum += "B";
break;
case 10: strHexNum += "A";
break;
default: strHexNum += Integer.toString(currentNum);
break;
}
}
return invert (strHexNum, 2);
}
public String decOct (int decNum)
{//10 to 8
String strOctNum = "";
while (decNum != 0)
{
if (decNum > 7)
{
strOctNum += Integer.toString(decNum % 8);
decNum /= 8;
}
else
{
strOctNum += Integer.toString(decNum);
decNum = 0;
}
}
return invert (strOctNum, 3);
}
public String decBin (int decNum)
{//10 to 2
String strBinNum = "";
while (decNum != 0)
{
if (decNum > 1)
{
strBinNum += Integer.toString(decNum % 2);
decNum /= 2;
}
else
{
strBinNum += Integer.toString(decNum);
decNum = 0;
}
}
return invert (strBinNum, 8);
}
private String invert (String strNum, int minLength) //转换长度
{
String answer = "";
int length = strNum.length();
if (length < minLength)
{
for (int padding = (minLength - length); padding > 0; padding--)
{
answer += "0";
}
}
for (int i = length; i > 0; i--)
{
answer += strNum.charAt (i - 1);
}
return answer;
}
}
///---------------------------------------最关键的一个内部类----字符串转表达式并进行计算---------------------------------------------------------------
/*一、表达式的组成
1、数字
2、运算符:+ - / * ^ % =
3、圆括号
4、变量
二、运算符优先级
由高到低分别为:+-(正负号)、^、%、+-、=
优先级相等的运算符按照从左到右的顺序计算
三、关键技术点
1、确定运算的优先级,从高到低分别为:原子元素表达式,包括数字和变量;括号表达式;一元表达式,取数的负数;指数表达式;乘、除、取模表达式;加、减表达式;赋值表达式。
2、对于每一级别的运算,都由一个方法实现,在方法中先完成比自己高一级别的运算,再处理本级别的运算。因此,在计算整个表达式的主方法中,只需要调用最低级别的运算的实现方法即可。
3、确定表达式中的分隔符,(+、-、*、/、%、^、=、(、)、)。利用这些分隔符将表达式分成多段,每一段叫做一个token,分隔符也算token。
4、用长度为26的int数组vars存储变量的值。
5、Character的isWhitespace方法判断字符是否为空白符,用于去掉表达式中的空白符。
6、Character的isLetter方法判断字符是否为字母,用于提取表达式中的变量
7、Character的isDigit方法判断字符是否为数字,用于获取表达式中的数字
*/
public class Shiyan4 {
// 4种标记类型
public static final int NONE_TOKEN = 0; //标记为空或者结束符
public static final int DELIMITER_TOKEN = 1; //标记为分隔符
public static final int VARIABLE_TOKEN = 2; //标记为变量
public static final int NUMBER_TOKEN = 3; //标记为数字
// 4种错误类型
public static final int SYNTAX_ERROR = 0; //语法错误
public static final int UNBALPARENS_ERROR = 1; //括号没有结束错误
public static final int NOEXP_ERROR = 2; //表达式为空错误
public static final int DIVBYZERO_ERROR = 3; //被0除错误
// private static final double PI = 3.1415926535897932384626433832795;//给pi赋值
// 针对4种错误类型定义的4个错误提示
public final String[] ERROR_MESSAGES ={"Syntax Error", "Unbalanced ", "No Expression Present", "Division by Zero"};
// 表达式的结束标记
public static final String EOE = "\0";
private String exp; //表达式字符串
private int expIndex; //解析器当前指针在表达式中的位置
private String token; //解析器当前处理的标记
private int tokenType; //解析器当前处理的标记类型
private double[] vars = new double[26]; //变量数组
/**
*
*/
public Shiyan4() {
}
/**
* 判断一个字符是否为分隔符
* 表达式中的字符包括:
* 加“+”、减“-”、乘“*”、除“/”、取模“%”、指数“^”、赋值“=”、左括号“(”、右括号“)”......
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -