这是我的完整代码供参考,以防错误与相关区块无关:
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();
}
以下是我要问的块:
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("");
}
}
你可以忽略我的大多数评论,因为其中一些已经过时了,但是现在,我的代码已编译,但我的结果框中没有任何内容。另外,因为我是以电子方式处理这个并且它将在服务器上进行评估,所以请不要提出任何建议来安装其他软件包。我认为Rhino应该足够了,而且我讨厌eval,它似乎是唯一的方法,除非你们有任何其他的建议。谢谢!
答案 0 :(得分:3)
buttonEquals = new JButton("=");
topPanel.add(buttonEquals);
应该是:
buttonEquals = new JButton("=");
buttonEquals.addActionListener(listener); // add the listener!
topPanel.add(buttonEquals);
更改所有实例:
else if (e.getSource() == button9)
到
else if (e.getSource().equals(button9)) // better compare using the method
另请参阅使用example的ScriptEngine
工作{{3}},{{3}}使用一些技巧将约260 LOC(例如提供的代码)缩小到仅141 LOC。它通过使用循环创建按钮来实现这一点,并且(主要)通过直接使用按钮的动作命令(添加到输入)。
答案 1 :(得分:2)
对我来说,问题是什么并不是很明显。但是有一件事你肯定做错了会让解决问题变得更难......除非你改变它。
catch (ScriptException e)
{
result.setText("Err");
expr.setText("");
}
这没有用。如果发生脚本异常,则会捕获它,丢弃所有出错的信息。至少,您应该在某处打印或记录异常堆栈跟踪。