1

这是我的完整代码供参考,以防错误与相关块无关:

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,但这似乎是唯一的方法,除非你们有任何其他建议。谢谢!

4

2 回答 2

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

  • 另请参阅使用 的这个工作示例ScriptEngine它使用一些技巧将 260 LOC(例如提供的代码)缩小到仅 141 LOC。它通过使用循环来创建按钮,并且(主要)通过直接使用按钮的操作命令(添加到输入)来做到这一点。

于 2013-07-05T02:49:11.653 回答
2

对我来说,问题所在并不是很明显。但是有一件事你肯定做错了,这会让解决问题变得更加困难......除非你改变它。

catch (ScriptException e)
    {
        result.setText("Err");
        expr.setText("");
    }

这没有帮助。如果发生脚本异常,您正在捕获它,并丢弃所有有关出错的信息。至少,您应该在某处打印或记录异常堆栈跟踪。

于 2013-07-05T02:25:31.650 回答