#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    7
    Rep Power
    0

    Why is this method not returning anything?


    I have these two classes that make a simple calculator, however when I try to use it I get the error java.lang.NumberFormatException, which I get because the getText method in the SimpleCalc class is returning an empty String. Here is the source code:

    Of the SimpleCalc class:
    Code:
    	//Imports are listed in full to show what's being used
    	//could just import javax.swing.* and java.awt.* etc..
    
    	import java.awt.GridLayout;
    	import java.awt.BorderLayout;
    	import java.awt.event.ActionListener;
    	import java.awt.event.ActionEvent;
    	import javax.swing.JFrame;
    	import javax.swing.JPanel;
    	import javax.swing.JTextField;
    	import javax.swing.JButton;
    	import java.awt.Container;
    
    	public class SimpleCalc implements ActionListener{
    	 
    		public static final SimpleCalc instance = new SimpleCalc();
    		
    		JFrame guiFrame;
    		JPanel buttonPanel;
    		JTextField numberCalc;
    		int calcOperation = 0;
    		int currentCalc;
    		int operatorAction;
    		
    		//Note: Typically the main method will be in a
    		//separate class. As this is a simple one class
    		//example it's all in the one class.
    		
    		
    		public SimpleCalc()
    		{
    			guiFrame = new JFrame();
    			
    			//make sure the program exits when the frame closes
    			guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    			guiFrame.setTitle("Simple Calculator");
    			guiFrame.setSize(300,300);
    		  
    			//This will center the JFrame in the middle of the screen
    			guiFrame.setLocationRelativeTo(null);
    			
    			numberCalc = new JTextField();
    			numberCalc.setHorizontalAlignment(JTextField.RIGHT);
    			numberCalc.setEditable(false);
    			
    			guiFrame.add(numberCalc, BorderLayout.NORTH);
    			
    			buttonPanel = new JPanel();
    				   
    			//Make a Grid that has three rows and four columns
    			buttonPanel.setLayout(new GridLayout(4,3));   
    			guiFrame.add(buttonPanel, BorderLayout.CENTER);
    			
    			//Add the number buttons
    			for (int i=1;i<10;i++)
    			{
    				addButton(buttonPanel, String.valueOf(i));
    			}
    
    			JButton addButton = new JButton("+");
    			addButton.setActionCommand("+");
    			
    			OperatorAction subAction = new OperatorAction(1);
    			addButton.addActionListener(subAction);
    			
    			JButton subButton = new JButton("-");
    			subButton.setActionCommand("-");
    			
    			OperatorAction addAction = new OperatorAction(2);
    			subButton.addActionListener(addAction);
    			
    			JButton equalsButton = new JButton("=");
    			equalsButton.setActionCommand("=");
    			equalsButton.addActionListener(new ActionListener()
    			{
    				@Override
    				public void actionPerformed(ActionEvent event)
    				{
    					if (!numberCalc.getText().isEmpty())
    					{
    						int number = Integer.parseInt(numberCalc.getText()); 
    						if (calcOperation == 1)
    						{
    							int calculate = currentCalc  + number;
    							numberCalc.setText(Integer.toString(calculate));
    						}
    						else if (calcOperation == 2)
    						{
    							int calculate = currentCalc  - number;
    							numberCalc.setText(Integer.toString(calculate));
    						}
    					}
    				}
    			});
    			
    			buttonPanel.add(addButton);
    			buttonPanel.add(subButton);
    			buttonPanel.add(equalsButton);
    			guiFrame.setVisible(true);  
    		}
    		
    		//All the buttons are following the same pattern
    		//so create them all in one place.
    		private void addButton(Container parent, String name)
    		{
    			JButton but = new JButton(name);
    			but.setActionCommand(name);
    			but.addActionListener(this);
    			parent.add(but);
    		}
    		
    		//As all the buttons are doing the same thing it's
    		//easier to make the class implement the ActionListener
    		//interface and control the button clicks from one place
    		@Override
    		public void actionPerformed(ActionEvent event)
    		{
    			//get the Action Command text from the button
    			String action = event.getActionCommand();
    			
    			//set the text using the Action Command text
    			numberCalc.setText(action);       
    		}
    		
    		public String getText() {
    			return numberCalc.getText();
    		}
    		
    	}
    And here is the other class OperatorAction:

    Code:
    import java.awt.event.ActionEvent;
    	import java.awt.event.ActionListener;
    
    	import javax.swing.JTextField;
    
    		public class OperatorAction implements ActionListener
    		{
    			int calcOperation = 0;
    			int currentCalc;
    			private int operator;
    			// How to make 
    		  
    			
    			public OperatorAction(int operation)
    			{
    				operator = operation;
    			}
    			
    			public void actionPerformed(ActionEvent event)
    			{
    				currentCalc =   Integer.parseInt(SimpleCalc.instance.getText()); 
    				calcOperation = operator;
    			}
    		}
    So I do get that it is my getText method that is failing, but why? I really cannot see why this should not work :/

    And why is it that I cannot access the public JTextField of the SimpleCalc class, with it is inherited getText method. If I try to do that Eclipse says that it does not this variable... So should public fields not be accessible to other classes?
  2. #2
  3. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,696
    Rep Power
    347
    Where is the main() method for executing this?
  4. #3
  5. Java Junkie
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jan 2004
    Location
    Mobile, Alabama
    Posts
    4,020
    Rep Power
    1285
    My suspicion is that you have nothing in the JTextField. When you use the getText() method, it returns "", which cannot be converted to a number. I would recommend initializing that field with "0".

    I don't see a JTextField in that class that is declared public. There is only one instance variable declared public.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    7
    Rep Power
    0
    Ok well firstly here is my main class:

    Code:
    import java.awt.EventQueue;
    
    
    public class Main {
    
    	public static void main(String[] args) {
    		  
            //Use the event dispatch thread for Swing components
            EventQueue.invokeLater(new Runnable()
            {
                
               @Override
                public void run()
                {
                  
                    new SimpleCalc();         
                }
            });
                 
       }
    }
    And well I get this GUI calculator which is shown here, and then I get this error when I try to use the "-" or "+" button, so it is not because the JTextField is actually empty.

    Here is the picture:



    Also found here: http://tinypic.com/r/2mevbyu/6

    And lastly I do have a public field JTextField in my simpleCalc called numberCalc, why is it that cannot just use that with the .getText (inherited from JTextField) method in the OperatorAction?

    And thanks for helping, it really means a lot!
  8. #5
  9. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,696
    Rep Power
    347
    How many instances of the SimpleCalc class are created? Which one does the getText() use to get its data from?
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    7
    Rep Power
    0
    Originally Posted by NormR
    How many instances of the SimpleCalc class are created? Which one does the getText() use to get its data from?
    One as its constructor makes sure it is a singleton via this code fragment:

    Code:
    public static final SimpleCalc instance = new SimpleCalc();
  12. #7
  13. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,696
    Rep Power
    347
    What about the one created in the main() method?

    If you are not sure how many are being created, add a println() statement in the constructor and see how many times it prints out a message.

    What does that statement have to do with the class being a singleton?
  14. #8
  15. Java Junkie
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jan 2004
    Location
    Mobile, Alabama
    Posts
    4,020
    Rep Power
    1285
    I see the numberCalc variable, but it's not declared public. It has default access which means only members of the same package or members of the class can access it. If you want subclasses to access it that aren't in the package, declare it protected.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    7
    Rep Power
    0
    Yeah well the main class creates two object of SimpleCalc, at the present state. So it seems what I have done so far does not really work.

    But well what I actually just want to do, is find a way to transfer the content of the JTextField in the SimpleCalc, to a variable in the OperatorAction class, which is used to implement the various operator (+,-).

    So how could I do this most easily?
  18. #10
  19. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,696
    Rep Power
    347
    So how could I do this most easily?
    Create only one instance of the class and use that one. Pass a reference to it to other classes that need to be able to access its members.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    7
    Rep Power
    0
    Originally Posted by NormR
    Create only one instance of the class and use that one. Pass a reference to it to other classes that need to be able to access its members.
    Yeah well but as you can see I have not really been able to do that. So could you perhaps give me an example of how to do this?
  22. #12
  23. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,696
    Rep Power
    347
    Get rid of the second call to the constructor so that there is only one instance created (in the main() method).
    Make the action listener class an inner method so that it as access to the method.
    Last edited by NormR; February 16th, 2013 at 06:50 AM.
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    47
    Rep Power
    0
    Code:
    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class Digital extends JFrame{
    public Digital(){
    	;
    	setVisible(true);
    	add(new Panel());
    	setSize(400,400);
    	//t.setSize(20, 20);
    	 //pack();
    	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
    public static void main(String args[]){
    	
    	new Digital();
    	
    }
    }
    class Panel extends JPanel implements ActionListener{
    	JButton c[]=new JButton[10];
    	JTextField t=new JTextField(20);
    	JButton mul=new JButton("*");
    	JButton div=new JButton("/");
    	JButton add=new JButton("+");
    	JButton sub=new JButton("-");
    	public Panel(){   
    		//setLayout(null);
    
    	for(int i=0;i<10;i++)c[i]=new JButton(String.valueOf(i));
    //	setLayout(new GridLayout(3,3));
    		//setSize(100,100);
    		//setLayout(new GridLayout(3,3));
    		
    		for(int i=0;i<10;i++)add(c[i]);
    		
    		//setLayout(new BorderLayout());
    		for(int i=0;i<10;i++)c[i].addActionListener(this);
    		//setLayout(new BorderLayout());
    add(mul);add(div);add(add);add(sub);
     mul.addActionListener(new ActionListener(){
    
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
    		String d=t.getText();
    		t.setText(d+String.valueOf("*"));
    	}
    	 
    	 
    	 
     });
     sub.addActionListener(new ActionListener(){
    
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
    		String d=t.getText();
    		t.setText(d+String.valueOf("-"));
    	}
    	 
    	 
    	 
     });
     div.addActionListener(new ActionListener(){
    
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
    		String d=t.getText();
    		t.setText(d+String.valueOf("/"));
    	}
    	 
    	 
    	 
     });
     add.addActionListener(new ActionListener(){
    
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
    		String d=t.getText();
    		t.setText(d+String.valueOf("+"));
    	}
    	 
    	 
    	 
     });
    	//setLayout(new FlowLayout());
    
    		add(t);
    		
    		
    	}
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
    
    		for(int i=0;i<10;i++)if(arg0.getSource()==c[i]) {
    			String d=t.getText();
    			t.setText(d+String.valueOf(i));
    		}
    	}
    	
    }
    Another calculator code could be as such ! Maybe you can adapt it t your case

    Good Luck !

IMN logo majestic logo threadwatch logo seochat tools logo