Im trying to make a calculator and I thought of using the ScriptEngine class to evaluate expressions. So I designed the following code:

CalculatorFrame.java :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.Math;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

	public class CalculatorFrame extends JFrame {
		
		public CalculatorFrame()
		{
			setTitle("My Scientific Calculator");
			
			CalculatorPanel calcPanel=new CalculatorPanel();
			add(calcPanel);
			pack();
		}
	}
	
	class CalculatorPanel extends JPanel
	{
		private JTextField display1;
		private JTextField display2;
		private JPanel buttonPanel;
		private JPanel displayPanel;
		
		public CalculatorPanel()
		{
			ActionListener listener=new CalculatorListener();
			ActionListener displayListener=new DisplayListener();
			
			
			setLayout(new BorderLayout());
			
			//Display
			displayPanel=new JPanel();
			displayPanel.setLayout(new GridLayout(2,1));
			
			display1=new JTextField("");
			displayPanel.add(display1);
			display2=new JTextField("");
			displayPanel.add(display2);
			
			add(displayPanel,BorderLayout.NORTH);
			
			
			buttonPanel=new JPanel();
			//ButtonLayout
			buttonPanel.setLayout(new GridLayout(7,4));
			
			//Button Creation
			JLabel empty=new JLabel("");
			JLabel empty1=new JLabel("");
			buttonPanel.add(empty);
			buttonPanel.add(empty1);
			
			JButton AC=new JButton("AC");
			AC.addActionListener(displayListener);
			buttonPanel.add(AC);
			
			JButton OFF=new JButton("OFF");
			OFF.addActionListener(displayListener);
			buttonPanel.add(OFF);
			
			JButton log=new JButton("log");
			log.addActionListener(listener);
			buttonPanel.add(log);
			
			JButton sin=new JButton("sin");
			sin.addActionListener(listener);
			buttonPanel.add(sin);
			
			JButton tan=new JButton("tan");
			tan.addActionListener(listener);
			buttonPanel.add(tan);
			
			JButton cos=new JButton("cos");
			cos.addActionListener(listener);
			buttonPanel.add(cos);
			
			JButton e=new JButton("e");
			e.addActionListener(listener);
			buttonPanel.add(e);
			
			JButton x_2=new JButton("x^2");
			x_2.addActionListener(listener);
			buttonPanel.add(x_2);
			
			JButton x_3=new JButton("x^3");
			x_3.addActionListener(listener);
			buttonPanel.add(x_3);
			
			JButton sqrt=new JButton("sqrt");
			sqrt.addActionListener(listener);
			buttonPanel.add(sqrt);
			
			JButton seven=new JButton("7");
			seven.addActionListener(listener);
			buttonPanel.add(seven);
			
			JButton eight=new JButton("8");
			eight.addActionListener(listener);
			buttonPanel.add(eight);
			
			JButton nine=new JButton("9");
			nine.addActionListener(listener);
			buttonPanel.add(nine);
			
			JButton add=new JButton("+");
			add.addActionListener(listener);
			buttonPanel.add(add);
			
			JButton four=new JButton("4");
			four.addActionListener(listener);
			buttonPanel.add(four);
			
			JButton five=new JButton("5");
			five.addActionListener(listener);
			buttonPanel.add(five);
			
			JButton six=new JButton("6");
			six.addActionListener(listener);
			buttonPanel.add(six);
			
			JButton minus=new JButton("-");
			minus.addActionListener(listener);
			buttonPanel.add(minus);
			
			JButton one=new JButton("1");
			one.addActionListener(listener);
			buttonPanel.add(one);
			
			JButton two=new JButton("2");
			two.addActionListener(listener);
			buttonPanel.add(two);
			
			JButton three=new JButton("3");
			three.addActionListener(listener);
			buttonPanel.add(three);
			
			JButton divide=new JButton("/");
			divide.addActionListener(listener);
			buttonPanel.add(divide);
			
			JButton zero=new JButton("0");
			zero.addActionListener(listener);
			buttonPanel.add(zero);
			
			JButton decimal=new JButton(".");
			decimal.addActionListener(listener);
			buttonPanel.add(decimal);
			
			JButton equal=new JButton("=");
			equal.addActionListener(listener);
			buttonPanel.add(equal);
			
			JButton multiply=new JButton("*");
			multiply.addActionListener(listener);
			buttonPanel.add(multiply);
			
			add(buttonPanel,BorderLayout.CENTER);
			
			
		}
		
		ScriptEngineManager manager=new ScriptEngineManager();
		ScriptEngine engine=manager.getEngineByName("Java Script");
		
		
		private class DisplayListener implements ActionListener
		{
			public void actionPerformed(ActionEvent event)
			{
				String command=event.getActionCommand();
				
				if(command.equals("AC"))
				{
					display1.setText("");
					display2.setText("");

				}
				else
				{
					System.exit(0);
				}
			}
		}
		
		private class CalculatorListener implements ActionListener
		{
			public void actionPerformed (ActionEvent event)
			{
				String command=event.getActionCommand();
				//double oprOneVal = 0;
				//double oprTwoVal=0;
				//String operator="";
				//boolean operand1=true;
				//boolean operand2=false;

				
				if(command.equals("log"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(Math.log(input)));
				}
				
				else if(command.equals("sin"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(Math.sin(input)));
				}
				
				
				else if(command.equals("tan"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(Math.tan(input)));
				}
				
				
				else if(command.equals("cos"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(Math.cos(input)));
				}
				
				else if(command.equals("e"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(Math.exp((input))));
				}
				
				else if(command.equals("x^2"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(input*input));
				}
				
				else if(command.equals("x^3"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(input*input*input));
				}
				
				else if(command.equals("sqrt"))
				{
					double input=Double.parseDouble(display1.getText());
					display2.setText(Double.toString(Math.sqrt((input))));
				}
				else if(command.equals("="))
				{
					String input=display1.getText();
					System.out.println(input); //debugging purpose
						try {
							display2.setText(Double.toString(evaluateExpression(input)));
						} catch(Exception e)
						{e.printStackTrace();
						
						}
					
				}
				else if(command.equals("ANS"))
				{
					display1.setText(display1.getText()+display2.getText());
				}
				else
				{
					display1.setText(display1.getText()+command);
				}
				

				
			}
			
			Double evaluateExpression (String expression) throws Exception
			{	
				System.out.println(expression);  //debugging purpose
				return (Double) engine.eval(expression); //Throwing Exception
			}
		}
		
		
		
}

Calculator.java

import java.awt.EventQueue;

import javax.swing.JFrame;


public class Calculator {

	public static void main(String arg[])
	{
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				CalculatorFrame calculator=new CalculatorFrame();
				calculator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				calculator.setVisible(true);
			}
		});
	}
	
}

But When I execute it and when I press "8" + "9" and then "="

The string from display1 is getting stored in the String input.
And it is being passed on to evaluateExpression method. But still engine.eval() throws NullPointerException. But Javadoc clearly states that this method throws nullexception iff the argument is null.

Please help me. Am I missing something.

Here is the GUI.
[IMG]http://lulzimg.com/i23/3de3b0.jpg[/IMG]

Please help me. BTW please ignore the operations for log, sin, tan etc. I haven't worked on them yet. Current implementation is logically wrong.

Recommended Answers

All 8 Replies

Please post the full text of the error message that shows which line the NullPointerException occurs on.

Spelling counts in service provider look-ups. Try

ScriptEngine engine=manager.getEngineByName("JavaScript");

You've just saved the OP the trouble of finding the problem himself.
He was making assumptions about the contents of the engine variable.
He needed to print it out to see that it was null. And then backtrack to why.

Yes, but the docs on using that service are very thin. I chose to point out the spelling difference because String-keyed locators like that do not provide much feedback for minor errors such as a key misspelling.

Yes that is true. But the OP didn't know what was causing the NPE.
He assumed it was somewhere else. He should have tracked it down to see that the value of engine was null. Not that the eval() method was throwing a NPE.

OMG. Oops. But the stack trace didnt point out the line that created the engine.

This is the stack trace that I got:

java.lang.NullPointerException
	at CalculatorPanel$CalculatorListener.evaluateExpression(CalculatorFrame.java:278)
	at CalculatorPanel$CalculatorListener.actionPerformed(CalculatorFrame.java:255)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Thats why I thought the argument that was being passed to the engine was not being accepted....

Thanks. And I really feel very proud to be a member of a forum where people want others to learn. I really respect what Norm1 said. I should work more hard.

Thanks Ezzaral

The stack trace shows that the value of the engine variable was null on line 278.

OMG. How stupid can I be...........

Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.