使用JavaScript解析算术表达式(通过ScriptEngine)
以下是我的完整代码供参考,以防错误与所讨论的块无关:使用JavaScript解析算术表达式(通过ScriptEngine),java,javascript,swing,parsing,jbutton,Java,Javascript,Swing,Parsing,Jbutton,以下是我的完整代码供参考,以防错误与所讨论的块无关: import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import javax.script.*; //Previously while debugging this, I was writing my own exception in case of an arithmetic //error. I'm trying t
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.script.*;
//Previously while debugging this, I was writing my own exception in case of an arithmetic
//error. I'm trying to get it to work so my evaluation method has a catch block, which is
//necessary because the ScriptEngineManager requires it.
public class Calculator
{
JButton button0;
JButton button1;
JButton button2;
JButton button3;
JButton button4;
JButton button5;
JButton button6;
JButton button7;
JButton button8;
JButton button9;
JButton buttonCE;
JButton buttonC;
JButton buttonPlus;
JButton buttonMinus;
JButton buttonTimes;
JButton buttonDivide;
JTextField expr;
JButton buttonEquals;
JTextField result;
public Calculator()
{
ActionListener listener = new MyButtonListener(); //Use for ALL buttons.
JFrame window = new JFrame("Calculator");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content;
content = window.getContentPane();
content.setLayout( new BorderLayout() );
JPanel bottomPanel = new JPanel();
JPanel topPanel = new JPanel();
JPanel ops = new JPanel();
ops.setLayout(new GridLayout(4,3));
JPanel digits = new JPanel();
digits.setLayout(new GridLayout(4,1));
button0 = new JButton("0"); //Generate and add buttons and listeners for bottomPanel
digits.add(button0);
button0.addActionListener(listener);
button1 = new JButton("1");
digits.add(button1);
button1.addActionListener(listener);
button2 = new JButton("2");
digits.add(button2);
button2.addActionListener(listener);
button3 = new JButton("3");
digits.add(button3);
button3.addActionListener(listener);
button4 = new JButton("4");
digits.add(button4);
button4.addActionListener(listener);
button5 = new JButton("5");
digits.add(button5);
button5.addActionListener(listener);
button6 = new JButton("6");
digits.add(button6);
button6.addActionListener(listener);
button7 = new JButton("7");
digits.add(button7);
button7.addActionListener(listener);
button8 = new JButton("8");
digits.add(button8);
button8.addActionListener(listener);
button9 = new JButton("9");
digits.add(button9);
button9.addActionListener(listener);
buttonCE = new JButton("CE");
digits.add(buttonCE);
buttonCE.addActionListener(listener);
buttonC = new JButton("C");
digits.add(buttonC);
buttonC.addActionListener(listener);
buttonPlus = new JButton("+"); //Generate operations buttons and add them
ops.add(buttonPlus);
buttonPlus.addActionListener(listener);
buttonMinus = new JButton("-");
ops.add(buttonMinus);
buttonMinus.addActionListener(listener);
buttonTimes = new JButton("*");
ops.add(buttonTimes);
buttonTimes.addActionListener(listener);
buttonDivide = new JButton("/");
ops.add(buttonDivide);
buttonDivide.addActionListener(listener);
expr = new JTextField(10); //These will go on topPanel
topPanel.add(expr);
buttonEquals = new JButton("=");
topPanel.add(buttonEquals);
result = new JTextField(6);
topPanel.add(result);
bottomPanel.add(digits);
bottomPanel.add(ops);
content.add(bottomPanel, BorderLayout.SOUTH); //Is this why it won't put them in a frame?
content.add(topPanel, BorderLayout.NORTH);
window.pack();
window.setVisible(true);
}
public class MyButtonListener implements ActionListener
{
//Random bunch of if-else if statements for what happens when you
//push each button.
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == button0)
{
expr.setText(expr.getText() + "0");
}
else if (e.getSource() == button1)
{
expr.setText(expr.getText() + "1");
}
else if (e.getSource() == button2)
{
expr.setText(expr.getText() + "2");
}
else if (e.getSource() == button3)
{
expr.setText(expr.getText() + "3");
}
else if (e.getSource() == button4)
{
expr.setText(expr.getText() + "4");
}
else if (e.getSource() == button5)
{
expr.setText(expr.getText() + "5");
}
else if (e.getSource() == button6)
{
expr.setText(expr.getText() + "6");
}
else if (e.getSource() == button7)
{
expr.setText(expr.getText() + "7");
}
else if (e.getSource() == button8)
{
expr.setText(expr.getText() + "8");
}
else if (e.getSource() == button9)
{
expr.setText(expr.getText() + "9");
}
else if (e.getSource() == buttonC)
{
expr.setText("");
result.setText("");
}
else if (e.getSource() == buttonCE)
{
//clearLastEntry();
}
else if (e.getSource() == buttonPlus)
{
expr.setText(expr.getText() + "+");
}
else if (e.getSource() == buttonMinus)
{
expr.setText(expr.getText() + "-");
}
else if (e.getSource() == buttonTimes)
{
expr.setText(expr.getText() + "*");
}
else if (e.getSource() == buttonDivide)
{
expr.setText(expr.getText() + "/");
}
else if (e.getSource() == buttonEquals)
{
evaluate(expr, result);
}
}
}
/*private JTextField clearLastEntry(JTextField textbox)
{
textbox.setText(textbox.getText().substring(0, text.length()-1)); //Delete the last character.
String text = textbox.getText();
if (!(text.charAt(text.length()-1) == '+' ||
text.charAt(text.length()-1) == '-' ||
text.charAt(text.length()-1) == '*' ||
text.charAt(text.length()-1) == '/')) return textbox;
return clearLastEntry(textbox);
}*/
private void evaluate(JTextField expr, JTextField result)
{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//~~~Below is JavaScript code that will be run in Java.~~~~~
//~~~It must be stored as a pure Object and manually ~~~~~~~
//~~~converted to a String so it can be stored. It ~~~~~~~~
//~~~parses the arithmetic automatically, vastly ~~~~~~~~~~~
//~~~simplifying the amount of code needed to be written. ~~
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
try
{
Object textboxText = engine.eval(expr.getText()); //Store text as a pure object
result.setText(textboxText.toString());
expr.setText(""); //Blank out the text box.
}
catch (ScriptException e)
{
result.setText("Err");
expr.setText("");
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//~The parsing method will throw the following~~//
//~custom exception if the user does not input~~//
//~~~~~~~~~~~valid calculator input.~~~~~~~~~~~~//
/*private class TextNotArithmetic extends Exception
{
private TextNotArithmetic(JTextField textbox)
{
char testChar;
for (int i=0; i<textbox.getText().length()-1; i++)
{
testChar=textbox.getText().charAt(i);
if (!(Character.isDigit(testChar) || testChar=='+' || testChar=='-' ||
testChar=='*' || testChar=='/')) //if the character isn't valid
{
throw new TextNotArithmetic();
}
}
}
}*/
public static void main(String[] args)
{
new Calculator();
}
你可以忽略我的大部分评论,因为其中一些已经过时了,但是现在,我的代码已经编译了,但是我的结果框中没有任何内容。另外,由于我以电子方式提交此文件,并且将在服务器上对其进行评估,因此请不要对安装其他软件包提出任何建议。我觉得Rhino应该足够了,尽管我讨厌eval,但这似乎是唯一的方法,除非你们有其他建议。谢谢大家! 我现在还不清楚问题出在哪里。但是有一件事你肯定做错了,那就是让问题更难解决。。。除非你改变它
catch (ScriptException e)
{
result.setText("Err");
expr.setText("");
}
这是没有帮助的。如果发生脚本异常,您将捕获它,并丢弃所有有关出错原因的信息。至少,您应该在某个地方打印或记录异常stacktrace。我不清楚问题出在哪里。但是有一件事你肯定做错了,那就是让问题更难解决。。。除非你改变它
catch (ScriptException e)
{
result.setText("Err");
expr.setText("");
}
buttonEquals = new JButton("=");
topPanel.add(buttonEquals);
这是没有帮助的。如果发生脚本异常,您将捕获它,并丢弃所有有关出错原因的信息。至少,您应该在某处打印或记录异常stacktrace
buttonEquals = new JButton("=");
topPanel.add(buttonEquals);
应该是:
buttonEquals = new JButton("=");
buttonEquals.addActionListener(listener); // add the listener!
topPanel.add(buttonEquals);
其他提示
更改以下内容的所有实例:
如果e.getSource==按钮9,则为else
到
否则,如果e.getSource.equalsbutton9//最好使用该方法进行比较
另请参阅使用的工作,它使用一些技巧将260 LOC压缩到约260 LOC,例如,提供的代码仅为141 LOC。它通过使用循环来创建按钮来实现这一点,主要是通过直接使用按钮的动作命令来添加到输入中
应该是:
buttonEquals = new JButton("=");
buttonEquals.addActionListener(listener); // add the listener!
topPanel.add(buttonEquals);
其他提示
更改以下内容的所有实例:
如果e.getSource==按钮9,则为else
到
否则,如果e.getSource.equalsbutton9//最好使用该方法进行比较
另请参阅使用的工作,它使用一些技巧将260 LOC压缩到约260 LOC,例如,提供的代码仅为141 LOC。它通过使用循环来创建按钮来实现这一点,主要是通过直接使用按钮的动作命令来添加到输入中
使用。谢谢!唯一的问题是,这似乎正是我所拥有的,只是他在别处声明了ScriptEngine和ScriptEngineManager。。正如StephenC所建议的,将catch Exception e{..形式的代码更改为catch Exception e{e.printStackTrace;//非常有用!。安德鲁,你的代码运行得很好,我得到了一个函数计算器应用程序。现在,我的结果字段是空的。我更改了捕获,但仍然没有得到任何输出。使用。e.G..谢谢!唯一的问题是,这似乎正是我拥有的,只是他声明了脚本引擎和脚本“他”是“我”…正如StephenC所建议的那样-将形式为catch Exception e{..的代码更改为catch Exception e{e.printStackTrace;//非常有用!。Andrew,你的代码运行得很好,我得到了一个函数计算器应用程序。现在,我的结果字段为空。我更改了捕获,但仍然没有得到任何输出。谢谢!我刚刚将捕获块更改为:catch scripte{e.printStackTrace;//result.settexter;//expr.setText;}但是我还是遇到了同样的错误。//result.settexter;除了调用printStackTrace之外,做这些事情没有什么坏处,或者日志记录只是对任何现有用户反馈的一个很好的补充。尽管您可以尝试使用setTexte.getMessage来快速警告除法0错误……谢谢!我刚刚更改了catch块到:捕获脚本异常e{e.printStackTrace;//result.settexter;//expr.setText;}但是我还是遇到了同样的错误。//result.settexter;除了调用printStackTrace之外,执行这些操作并没有什么坏处,日志记录只是对任何现有用户反馈的一个很好的补充。尽管您可以尝试使用setTexte.getMessage来快速警告除数为0的错误……这就是问题所在。它总是看起来很明显是这样的。谢谢!它现在运行良好。另请参阅编辑。其中包括有关为什么您的代码(本质上与我的代码相同)可以从260->140位置缩减的提示。这就是问题所在。它似乎总是很明显。谢谢!它现在运行良好。另请参阅编辑。其中包括关于为什么的提示您的代码基本上与我的代码相同,可以从260->140位置缩小: