Hello guys, I am stuck again with a new problem.

I need help with 3 things:

1. Timer
2. State Pattern
3. Disabling the button on JFrame

lets go with the easiest one in the list, the Disabling of button one.

I have an app with buttons, and I need to disable all the buttons on it for certain period of time. Lets forget the time part.. I just want to disable the buttons on the frame.

BEFORE YOU GO ON SUGGESTING ME THE FUNCTION, I ALREADY HAVE TRIED "button.setEnabled(false);" AND IT DOESNT WORK! I dont know why :/

here's my source code:

myloader.java

/**
 * @(#)loader.java
 *
 *
 * @author 
 * @version 1.00 2010/6/24
 */
package uniKEY;

import java.*;
import java.awt.*;
import javax.swing.*;
import java.lang.*;

public class myLoader extends JFrame
{
	private myUI _uiobj;
	
	public myLoader()
	{
		_uiobj = new myUI();
		setSize(180,300);
		setTitle("UniKEY");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
		getContentPane().add(_uiobj);
	}
	
    public static void main(String[] args)
    {
		new myLoader();
    }
}

myUI.java

/**
 * @(#)ui.java
 *
 *
 * @author 
 * @version 1.00 2010/6/24
 */

package uniKEY;
import java.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;

class myUI extends JPanel implements ActionListener
{
	private JPanel _mainpanel;
	private JPanel _lightpanel;
	private JButton _button[];
	private JPanel _keypadpanel;
	private String _dbPass;
	private String _userPass;
	private String _clickValue;
	private int _click = 0;
	private JLabel _imagelabel; 
  	private Light _myLight;  
  	private Timer _timer;
  	private static final int WAIT = 0;
  	private static final int YES = 1;
	private static final int NO = 2;
  	private int _currentState;

    public myUI()
    {
    	_clickValue= null;
		_userPass= null;
    	loadDB();
   		renderLayout();
   		renderFrame();
    }

	public void renderLayout()
	{
    	_mainpanel = new JPanel();
    	_keypadpanel = new JPanel();
    	_lightpanel = new JPanel();
    	_button = new JButton[12];
		_mainpanel.setLayout(new BorderLayout());
		_keypadpanel.setLayout(new GridLayout(4,3,0,0));
		_lightpanel.setLayout(new FlowLayout());
						
		for (int i=0; i<=9; i++)
		{
			_button[i]= new JButton(String.valueOf(i));
			_button[i].setPreferredSize(new Dimension(55,55));
		}
		
		_button[10] = new JButton("*");
		_button[0] = new JButton("0");
		_button[11] = new JButton("#");
		
		for (int i=1; i<=3; i++)
		{
			_keypadpanel.add(_button[i]);	 	
		}

		for (int i=4; i<=6; i++)
		{
			_keypadpanel.add(_button[i]);	 	
		}
		
		for (int i=7; i<=9; i++)
		{
			_keypadpanel.add(_button[i]);	 	
		}

		_keypadpanel.add(_button[10]);
		_keypadpanel.add(_button[0]);
		_keypadpanel.add(_button[11]);

		for(int i=0;i<12;i++)
		{
			_button[i].addActionListener(this);
		}
				
		_myLight = new Light();
		//_myLight.setImage();
		_currentState=WAIT;
		_lightpanel.add(_myLight);
	}
 
    public void renderFrame()
    {
		_mainpanel.add(_keypadpanel,BorderLayout.NORTH);
		_mainpanel.add(_lightpanel,BorderLayout.SOUTH);
		this.add(_mainpanel);
    }
    
	public void loadDB()
	{
		try
		{
			FileInputStream _fis = new FileInputStream("myfile.txt"); 
			DataInputStream _dis = new DataInputStream(_fis);
			BufferedReader _br = new BufferedReader(new InputStreamReader(_dis));
			_dbPass=_br.readLine();
			_dis.close();
		}
		catch(Exception e)
		{
			JOptionPane.showMessageDialog(_mainpanel,"Error Occoured!\n"+e.getMessage()+"\n");
			System.exit(0);
		}
			
	}
	

	public void resetState()
	{
		_click=0;
		if((_currentState==YES)||(_currentState==NO))
		{
			_currentState=WAIT;
			for(int i=0;i<12;i++)
			{
				_button[i].setEnabled(true);
			}
		}
	}
	
    private void check()
	{
		if(_userPass.equals(_dbPass))
		{
			if(_currentState == WAIT)
			{
				_currentState = YES;
				_myLight.flipImage("go");
				for(int i=0;i<12;i++)
				{
					_button[i].setEnabled(false);
				}
				resetState();
			}
		}
		else
		{
			if(_currentState == WAIT)
			{
				_currentState = NO;
				_myLight.flipImage("stop");
				for(int i=0;i<12;i++)
				{
					_button[i].setEnabled(false);
				}
				resetState();
			}
		}
	}
	
	private void reportError()
	{
		JOptionPane.showMessageDialog(_mainpanel,"An Error Occoured!\nThe Application needs to be restarted!\n");
		System.exit(0);
	}
	
    private void processInput(String _value)
	{
		if(_click==0)
		{
			_userPass=_value;
			_click++;
		}
		else if(_click>0)
		{
			_userPass+=_value;
			_click++;
		}
	}
                
    public void actionPerformed(ActionEvent e)
	{
    	if(e.getSource() == _button[0])
    	{
    		_clickValue = _button[0].getText();
    		if(_click < 3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
		else if(e.getSource() == _button[1])
    	{
    		_clickValue = _button[1].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
		}
    	else if(e.getSource() == _button[2])
    	{
    		_clickValue = _button[2].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
		else if(e.getSource() == _button[3])
    	{
    		_clickValue = _button[3].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[4])
    	{
    		_clickValue = _button[4].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[5])
    	{
    		_clickValue = _button[5].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[6])
    	{
    		_clickValue = _button[6].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[7])
    	{
    		_clickValue = _button[7].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[8])
    	{
    		_clickValue = _button[8].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[9])
    	{
    		_clickValue = _button[9].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[10])
    	{
    		_clickValue = _button[10].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == _button[11])
    	{
    		_clickValue = _button[11].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
		else
    	{
			reportError();    			
		}
	}
}
package uniKEY;

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Light extends JLabel
{	
    public Light()
    {
		this.setIcon(resizeImage(new ImageIcon("wait.jpg")));
    }

    public void flipImage(String _state)
    {
		this.setIcon(resizeImage(new ImageIcon(_state+".jpg")));
	}

	private ImageIcon resizeImage(ImageIcon _myImage)
	{
		Image _img = _myImage.getImage();
		Image _newimg = _img.getScaledInstance(50, 38,Image.SCALE_SMOOTH); 
		ImageIcon _newIcon = new ImageIcon(_newimg); 
		return _newIcon;
	}
}

Light.java

1111

myfile.txt

and the following are the images used in the app:


The app runs finely without any problems. The actual behaviour of the app must be something like this:

when a password is entered right, a green image must be replaced by default one and keypad must freeze for few seconds, and unfreeze (disable/enable) along with resetting the image by original one and if a wrong password is entered, a red image must be replaced by default image and the process continues...

I have done the image part, they do change without any problems, now the buttons wont disable. I dont know why but they dont :(

can anyone please look into the code and help me out..?

thanks in advance

Attachments go.jpg 0.68 KB stop.jpg 0.68 KB wait.jpg 0.67 KB

lovely, now is there any way to use a timer to call resetState() after 5 seconds?

I have tried looking at the Timer class and many other threads on the forum. and I got a few different methods.. but they need a new action listener and stuff which would make the code complex (i think). Even If I wanted to do that how could I do that?

Timer _t = new Timer(5000, new ActionListener() { /* for loop to enable buttons again ? */});

If I place this code in stead of resetState() in check() in myUI.java

will that work? If it doesnt, what other alternative way could you suggest me?

Edited 6 Years Ago by emclondon: n/a

Fortunately (!) there's exactly one right way to do this: use a Timer... That's a javax.swing.Timer, not a java.util.Timer.
Set up the timer to run once after 5000 mSec, and use it to call your resetState method.
You'll find loads of examples on the web, just copy&paste one that fits.
It may look a little complex at first sight, but it's a standard Java idiom that you'll need to get comfortable with anyway.

ok this is what I have done,

I used a timer in my myUI.java file

private Timer _myTimer;

inside myUI class

and init'd the variable with an instance of an action listener class

_myTimer = new Timer(5000,new TimerListener());

inside myUI constructor

and added a class (nested) which had the functionality of enabling the buttons back to normal state and changing the image back to default one.

private class TimerListener implements ActionListener
	{ 
		public void actionPerformed(ActionEvent e)
		{
			resetState();
		}
		public void resetState()
		{
			_click=0;
			for(int i=0;i<12;i++)
			{
				_button[i].setEnabled(true);
			}
			_myLight.flipImage("wait");
			_myTimer.stop();
		}
	}

inside myUI class

the application is working fine, like a charm, but I wanted to know, whether if this is the right way of doing this? or is there any other way to do this? if there is please do let me know, if there isn't then I am a step closer to completion now.

The last part of my question is the state pattern. I am to implement State pattern in this applicaion. From my gatherings and readings I have figured it out that this pattern is used to reduce coding at places where the program exhibts various states.

my application exhibts 3 states.

  1. Waiting
  2. Go
  3. Stop

the waiting state displays black image on the panel, whilst the go and stop displays green and red respectively.

I am told that a state pattern needs an interface; I cant figure out what my interface must contain?
can anyone help me figure this thing out?

re the timer - yes, that's the right way. You can compress the code by using an anonymous inner class, but it still comes to the same thing in the end.

_myTimer = new Timer(5000,new TimerListener() {
public void actionPerformed(ActionEvent e) {
resetState();  // leave this method in the main class
}
});

I have no experience of the State pattern, so can't help you there, sorry.

strangely, that code gives me an error :/
the compiler says that it cant find the class TimeListener.

_myTimer = new Timer(5000,new TimerListener()
		{ 
			public void actionPerformed(ActionEvent e)
			{
				resetState();
			}
		}
		);

strange :/

Where is TimerListener defined? Why doesn't the compiler see it? Are the packages hiding it?

yes that worked fine. thank you very much :)

Norm can you help me out with state pattern?

from my understanding state pattern is a collective way of organising code of an application whose' object changes state frequently.

following is a generic image of state pattern as hosted on wikipedia:


so according to that image, I have a interface called state and classes called as openState, lockedState, unlockedState.
the main and sole purpose of these states are to draw images on my window when called.

I dont know what to do, I have my draw function. I dont understand how to let the app know which draw to draw and when does it draw. I dont understand the contept of context class, dont even know what is it, but an assuming that its n current image or something...

more info on state parrern with examples can be found here.. http://en.wikipedia.org/wiki/State_pattern

any help now?

Attachments state.png 11.32 KB

You need a bit more description of the pattern besides that diagram.
This isn't a java coding problem. Its a Computer science theory problem.

yes it is, according to my theory..

I just need to separate the logic of my program from the UI. and when I do that, I want a component in UI to behave differently based on my input.

by default the behaviour of the component (say panel) would be to display a black image on the frame at all times. and when the input from user is collected and compared with the one in the database, the component changes its default behaviour. e, it displays another image instead of black one. this can also be called as a change in state. similarly based on the output data generated by my custom functions, the behaviour of component changes to display different images...

the basic aim here is to achieve this is by using state pattern.

I have an interface with a function, and 3 classes implementing interface...each class doing its own work. now I have to call up interface by making an object of it. then I utilize the function in my frame to call up different class via interface. thats what im assuming.. :/

I have an interface with a function, and 3 classes implementing interface...each class doing its own work. now I have to call up interface by making an object of it. then I utilize the function in my frame to call up different class via interface. thats what im assuming.. :/

Sounds good. You just have to make sure that any processing related to state variable which triggers change in state should be delegated to your current state implementation. A trivial example would look something like:

interface PasswordIndicatorState {
    void setValidationStage(Application app, ValidationStage stage);
}

class OkPasswordIndicatorState implements PasswordIndicatorState {
    @Override
    public void setValidationStage(Application app, ValidationStage stage) {
        if(stage == ValidationStage.DEFAULT) {
            app.setStatus("DEFAULT");
            app.setState(new DefaultPasswordIndicatorState());
        }
    }
}

class WrongPasswordIndicatorState implements PasswordIndicatorState {
    @Override
    public void setValidationStage(Application app, ValidationStage stage) {
        if(stage == ValidationStage.DEFAULT) {
            app.setStatus("DEFAULT");
            app.setState(new DefaultPasswordIndicatorState());
        }
    }
}

class DefaultPasswordIndicatorState implements PasswordIndicatorState {
    @Override
    public void setValidationStage(Application app, ValidationStage stage) {
        if(stage == ValidationStage.OK) {
            app.setStatus("OK");
            app.setState(new OkPasswordIndicatorState());
        } else if(stage == ValidationStage.WRONG) {
            app.setStatus("WRONG");
            app.setState(new WrongPasswordIndicatorState());
        }
    }
}

enum ValidationStage {
    DEFAULT, OK, WRONG
}

class Application {

    private PasswordIndicatorState state;

    private String status;

    private ValidationStage validationStage;

    private Application() {
        setState(new DefaultPasswordIndicatorState());
        setValidationStage(ValidationStage.DEFAULT);
    }

    public static Application newApplication() {
        return new Application();
    }

    public void setState(PasswordIndicatorState state) {
        this.state = state;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public void setValidationStage(ValidationStage stage) {
        this.validationStage = stage;
        this.state.setValidationStage(this, stage);
    }

}

Edited 3 Years Ago by mike_2000_17: Fixed formatting

Hello, thanks for your reply, but that code is a bit confusing to me.. so I made a few changes to it..

I have taken 4 different files: openState, lockedState, defaultState and State

package uniKEY;

interface State
{
	public void setState(myUI obj, int i); 
}

State.java

package uniKEY;

class defaultState implements State
{
	public void setState(myUI obj, int i)
	{
		if(i == 1)
		{
			obj.setStatus("OPEN");
			obj.setState(new openState());
		}	
		else if(i == 2)
		{
			obj.setStatus("LOCKED");
			obj.setState(new lockedState());
		}		
	}
}

defaultState.java

package uniKEY;

class openState implements State
{
	public void setState(myUI obj, int i)
	{
		if(i == 0)
		{
			obj.setStatus("DEFAULT");
			obj.setState(new defaultState());
		}	
	}
}

openState.java

package uniKEY;

class lockedState implements State
{
	public void setState(myUI obj, int i)
	{
		if(i == 0)
		{
			obj.setStatus("DEFAULT");
			//obj.setState(new defaultState());
		}	
	}
}

lockedState.java

and my application has been modified to have

...
	...
	private State state;
	private String status;
	...
	...
	setState(new defaultState());
	...
 	public void setStatus(String ss)
 	{
 		this.status = ss;	
 	}
	...

myUI.java

I was wondering if I could take up 3 static ints in my UI and use them as enums?

...
    private static final int DEFAULT = 0;
    private static final int OPEN = 1;
    private static final int LOCKED = 2;
    ...

myUI.java

following the above change, in my methods, I have used the setState as setState(myUI obj, int i) where obj is an object of myUI and the integer i is the static int

they would serve the same purpose right?

also I don't understand the point of having this setStatus. it just sets a string right? I think I don't need that. or Will I?

also, when I try to use the code, it doesnt seem to match work :/

package uniKEY;

interface State
{
	public void setState(myUI obj, int i);
}


package uniKEY;

class defaultState implements State
{
	public void setState(myUI obj, int i)
	{
		if(i == 1)
		{
			obj.setState(new openState());
		}	
		else if(i == 2)
		{
			obj.setState(new lockedState());
		}		
	}
}

package uniKEY;

class openState implements State
{
	public void setState(myUI obj, int i)
	{
		if(i == 0)
		{
			obj.setState(new defaultState());
		}	
	}
}

package uniKEY;

class lockedState implements State
{
	public void setState(myUI obj, int i)
	{
		if(i == 0)
		{
			obj.setState(new defaultState());
		}	
	}
}

is my code, as you can see the setState has 2 parameters, and my function has only 1 parameter within it.
what do you suggest that I do?

I really like the use of enums for state, especially because you can define different implementations of a method for each member of the enum. This allows you to compress the whiole interface/mutiple state classes thing into a single enum. Eg:

enum State {
   waiting() {
      @Override
      public void paintBox() {
        // code to paint black box
      }
   },
   go() {
      @Override
      public void paintBox() {
        // code to paint green box
      }
   },
   stop() {
      @Override
      public void paintBox() {
        // code to paint red box
      }
   };
   abstract public void paintBox();
}

Then in your program you can have something like:

State s = State.waiting; // or whatever

and call

s.paintBox(); // to get the appropriate paint behaviour.

also I don't understand the point of having this setStatus. it just sets a string right?

I posted an example for your understanding which you'd need to adjust according to your specific needs. The state class normally has an extra parameter which is the reference to the class whose behaviour you would want to control.

I was wondering if I could take up 3 static ints in my UI and use them as enums?

Yes, but enums are better for a lot others reasons, the most important being type safety.

is my code, as you can see the setState has 2 parameters, and my function has only 1 parameter within it. what do you suggest that I do?

It seems that you are still struggling with the concept behind using the state pattern otherwise you wouldn't have asked this question. Read the wiki article again along with this article.

Edited 6 Years Ago by ~s.o.s~: n/a

This allows you to compress the whiole interface/mutiple state classes thing into a single enum

...thereby making it view dependent and reducing its general purpose usability. IMO, enums are much more useful if treated as data containers rather than behaviour containers since a given enum can be applicable to more than one scenarios. Enum methods generally operate on their state variables without any dependence on the application state.

Also, how would the `paintBox` in your code exactly work? Won't it require some kind of reference to the paint component?

~s.o.s~ Well, yes.
I generally wouldn't put UI behaviour into any kind of State model. But given a view of what this app is about, it seemed a useful compression to alangamate the two. But, no. I'd never do it in real life.
I wouldn't hesitate to put behaviour as well as data into an enum definition - why on earth not? - but only if the behaviour was an intrinsic aspect of the model.
"paintBox" was just a sketch to show how behaviour can be incorporated - obviously it would need something like a Graphics + x,y coords, or a JLabel for an ImageIcon, anything like that.

It seems that you are still struggling with the concept behind using the state pattern otherwise you wouldn't have asked this question. Read the wiki article again along with this article.

I still don't get it :(

let me build an image of state patterm in my mind which would clear a few things up.

I have an Interface and 3 Classes inheriting from the Interface.
My main method only talks with the Interface which in turn directs me to one of the classes depending on the objects of classes I created (?).

is my assumption right?

Edited 6 Years Ago by emclondon: n/a

Yes. Simply put, you have an object (your application) whose behaviour needs to change based on the state of that object (password valid or not). Going back to the example I posted, the 'Application' object has a variable (part of application state) called `validationState`. In order to modify the behaviour of our application, we need to do a couple of things.

Create a common state interface which would the super-type for all the state objects created. So what method should this State interface have? This interface normally harbours methods which are called on your application object. In our case, the method is called `setValidationStage`. This method would be called whenever you need to modify the "state" of your validationStage variable. Since it is the behaviour of this "state change" which we want to abstract, internally, this method would call the relevant "State" object by passing in a reference to self. The difference between the `setValidationStage` method of the `Application` object and the `State` object is that, the State object requires a reference to the `Application` also called as "context" in the wiki article, to modify its behaviour. Hence our State object would have a method called `setValidationStage(Application, ValidationStage)`.

Notice that the reference to state object in the Application is of type `PasswordIndicatorState`. This property would be set to the default state when the application initializes; which in our case is the `DefaultPasswordIndicatorState`. So, how is all this put in action? When the user clicks on the "Validate" button, the validatePassword() method is called. This method performs the validation and in turn calls the `setValidationStage` method of the `Application` object *which in turn* calls the `setValidationStage` method of the State object. Now it is the responsibility of the individual state objects to "set" the Application state (using the `setState` method) and keep the state transition rolling. For e.g. if the validation fails, ValidationStage.WRONG is passed to the `setValidationStage` method of the `DefautlPasswordIndicatorState` object.

Hi, thanks for the write up, from what I can gather from your write up is this:

- I have a method to change the state in my application
- I have an interface with 3 implemented classes
- When I validate, based on the result, I pick a state (yes/no) and call my method to change the application state...
- but, my method would in-turn call one of the implemented classes based on the state I picked (result) and then would change the state.
- so, finally the state gets changed by an external method (implemented class).

now I think I get it. Thanks for the help :)

Edited 6 Years Ago by emclondon: n/a

also I am trying to rip apart the application to separate the coding and the UI.

I have tried separating the UI part from functionality part. I have created a new class called myFunctions and dumped all the variables and functions related to functionality of the application.

now I'm stuck with a stupid Null Pointer Errors again! which I can't fix!.

so I request you to have a look here and please do let me know how to fix this.

File 1: State.java

/**
 * @(#)State.java
 *
 *
 * @author
 * @version 1.00, 2010/7/18
 */
 
 package uniKEY;

/**
 * This interface acts as an interface for the mechanism of state pattern used.
 */
 
interface State
{
	/**
	 * This method sets the state using the parameters passed.
	 *
	 * @param _myUIObj An instance of main application
	 * @param _myState state of the application
	 *
	 */
	void setStates(myFunctions _myFObj, States _myState);
}

File 2: closedState.java

/**
 * @(#)closedState.java
 *
 *
 * @author
 * @version 1.00, 2010/7/18
 */
 
package uniKEY;

/**
 * This class contains an implemented method which is used to change the state of the application depending upon the type of object and state passed.
 */
 
class closedState implements State
{
	
	/**
	 * This holds an Instance of myImage class
	 *
	 * see uniKEY.myImage
	 */
	 
	myImage _myIObj;

	/**
	 * This method sets the state based on the parameters passed to it. 
	 *
	 * @param _myUIObj An instance of main application
	 * @param _myState current state of the application
	 *
	 */
	 
	public void setStates(myFunctions _myFObj, States _myState)
	{
		if(_myState == States.DEFAULT)
		{
			_myIObj.setImage(States.DEFAULT);
            _myFObj.setState(new defaultState());
		}
	}
}

File 3: openState.java

/**
 * @(#)openState.java
 *
 *
 * @author
 * @version 1.00, 2010/7/18
 */
 
package uniKEY;

/**
 * This class contains an implemented method which is used to change the state of the application depending upon the type of object and state passed.
 */
 
class openState implements State
{
	
	/**
	 * This holds an Instance of myImage class
	 *
	 * see uniKEY.myImage
	 */
	 
	myImage _myIObj;

	/**
	 * This method sets the state based on the parameters passed to it. 
	 *
	 * @param _myUIObj An instance of main application
	 * @param _myState current state of the application
	 *
	 */
	 	
	public void setStates(myFunctions _myFObj, States _myState)
	{
		if(_myState == States.DEFAULT)
		{
			_myIObj.setImage(States.DEFAULT);
            _myFObj.setState(new defaultState());
		}
	}
}

File 4: defaultState.java

/**
 * @(#)defaultState.java
 *
 *
 * @author
 * @version 1.00, 2010/7/18
 */
 
package uniKEY;

/**
 * This class contains an implemented method which is used to change the state of the application depending upon the type of object and state passed.
 */
 
class defaultState implements State
{	
		
	/**
	 * This holds an Instance of myImage class
	 *
	 * see uniKEY.myImage
	 */
	 
	myImage _myIObj;

	/**
	 * This method sets the state based on the parameters passed to it. 
	 *
	 * @param _myUIObj An instance of main application
	 * @param _myState current state of the application
	 *
	 */
	 
	public void setStates(myFunctions _myFObj, States _myState)
	{
	if(_myState == States.OPEN)
		{
			_myIObj.setImage(States.OPEN);
          	_myFObj.setState(new openState());
		}
		else if(_myState == States.CLOSED)
		{
			_myIObj.setImage(States.CLOSED);
            _myFObj.setState(new closedState());
		}
	}
}

File 5: myFunctions.java

/**
 * @(#)ui.java
 *
 *
 * @author 
 * @version 1.5, 2010/6/24
 */
 
package uniKEY;

import java.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;

/**
 * This holds the states of the application in it by the names of DEFAULT, OPEN AND CLOSED.
 */
 
enum States
{
	DEFAULT, OPEN, CLOSED
};
	
/**
 * This class adds functionality to the objects.
 */
 	
class myFunctions implements ActionListener
{
	myUI myUIObj;
	private JFrame _thisFrame;
	 	
	/**
	 * This holds an object of State interface
	 *
	 * @see uniKEY.State
	 */
	 
	private State _currentState;
	
	
	/**
	 * This holds an object of States enumerator
	 */
	 
	private States _StatesObj;

	  	
	/**
	 * This variable holds data fetched from the file.
	 * It is used in processing of user input.
	 *
	 * @see #loadDB()
	 * @see #check()
	 */
	 
	private String _dbPass;
	

	/**
	 * This variable holds data entered by the user.
	 * It is used in processing of user input.
	 *
	 * @see #loadDB()
	 * @see #check()
	 */
	 
	private String _userPass;
	
	/**
	 * This variable holds data fetched from the file.
	 * It is used in processing of user input.
	 *
	 * @see #loadDB()
	 * @see #check()
	 */
	 
	private String _clickValue;
	
	/**
	 * This variable holds the data for number of attempts used by the user.
	 * It is used in limiting the user input
	 */
	 	 
	private int _click = 0;

	/**
	 * These holds an object of Timer class
	 */
	
  	private Timer _timer;
  	
  	/**
	 * This holds object of Timer class
	 */
	 
  	private Timer _myTimer;
  	
    
	public void myFunctions()
	{
		_clickValue= null;
		_userPass= null;
    	loadDB();
    	
    	
		/**
	 	* Assigning a functionality to Timer object;
	 	* a function resetState() is called upon when the time is elapsed.
		 *
		 * @see #resetState()
	 	*/
		 
		_myTimer = new Timer(5000,new ActionListener()
		{ 
			public void actionPerformed(ActionEvent e)
			{
				resetState();
			}
		}
		); 
	}
	

	/**
	 * The method tries to load the text from a file and stores data from it.
	 *
	 * @exception java.io.IOException If the specified file could not be found
	 */
	 	
	public void loadDB()
	{
		try
		{
			FileInputStream _fis = new FileInputStream("myfile.txt"); 
			DataInputStream _dis = new DataInputStream(_fis);
			BufferedReader _br = new BufferedReader(new InputStreamReader(_dis));
			_dbPass=_br.readLine();
			_dis.close();
		}
		catch(IOException e)
		{
			JOptionPane.showMessageDialog(_thisFrame, "An Error has Occoured!\n"+e.getMessage()+"\nThe Application will quit now.");
			System.exit(0);
		}
	}

	/**
	* The method reports a general error and kills the application
	*/
	
	private void reportError()
	{
		JOptionPane.showMessageDialog(_thisFrame,"An Error Occoured!\nThe Application needs to be restarted!\n");
		System.exit(0);
	}

	/**
	* The method collects the user input
	*/
		
    private void processInput(String _value)
	{
		if(_click==0)
		{
			_userPass=_value;
			_click++;
		}
		else if(_click>0)
		{
			_userPass+=_value;
			_click++;
		}
	}	
	
	/**
	 * The method sets the state of the application depending on the object of the state passed onto its.
	 *
	 * @param _myState is the new state of the application
	 */
	 
	public void setState(State _myState)
	{
		this._currentState = _myState;
	}
	
	/**
	 * The method sets the state and enumrated state value of the application depending on the object of the enumerated data passed onto its.
	 *
	 * @param _myState is the new state of the application
	 */
				
	public void setStates(States _newState)
	{
		this._StatesObj = _newState;
		this._currentState.setStates(this,_newState);	
	}
	
			
	/**
	* The method tries to validate the user input and changes the state of the application based on the result of validation
	*/
	 	
	private void check()
	{
		if(_userPass.equals(_dbPass))
		{
			setState(new openState());
			setStates(States.OPEN);
			myUIObj._myAccessImage.setImage(States.OPEN);
			for(int i=0;i<12;i++)
			{
				myUIObj._button[i].setEnabled(false);
			}
			_myTimer.start();
		}
		else
		{
	   		setState(new closedState());
        	setStates(States.CLOSED);
        	myUIObj._myAccessImage.setImage(States.CLOSED);
			for(int i=0;i<12;i++)
			{
				myUIObj._button[i].setEnabled(false);
			}
			_myTimer.start();
		}
	}
	

	/**
	* The method resets all changes done to the application and reverts the state to original condition
	*/
	     
	public void resetState()
	{
		_click=0;

		for(int i=0;i<12;i++)
		{
			myUIObj._button[i].setEnabled(true);
		}
 		setState(new defaultState());
        setStates(States.DEFAULT);
        myUIObj._myAccessImage.setImage(States.DEFAULT);
        _myTimer.stop();
	}
	
	/**
	* The method listens for any user input and acts accordingly
	*
	* @see #check()
	* @see #reportError()
	*/
		    
    public void actionPerformed(ActionEvent e)
	{
    	if(e.getSource() == myUIObj._button[0])
    	{
    		_clickValue = myUIObj._button[0].getText();
    		if(_click < 3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
		else if(e.getSource() == myUIObj._button[1])
    	{
    		_clickValue = myUIObj._button[1].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
		}
    	else if(e.getSource() == myUIObj._button[2])
    	{
    		_clickValue = myUIObj._button[2].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
		else if(e.getSource() == myUIObj._button[3])
    	{
    		_clickValue = myUIObj._button[3].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[4])
    	{
    		_clickValue = myUIObj._button[4].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[5])
    	{
    		_clickValue = myUIObj._button[5].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[6])
    	{
    		_clickValue = myUIObj._button[6].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[7])
    	{
    		_clickValue = myUIObj._button[7].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[8])
    	{
    		_clickValue = myUIObj._button[8].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[9])
    	{
    		_clickValue = myUIObj._button[9].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[10])
    	{
    		_clickValue = myUIObj._button[10].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
    	else if(e.getSource() == myUIObj._button[11])
    	{
    		_clickValue = myUIObj._button[11].getText();
    		if(_click <3)
    		{
    			processInput(_clickValue);
			}
    		else if(_click ==3) 
    		{
    			processInput(_clickValue);
    			check();	
			}
			else
			{
				reportError();
			}
    	}
		else
    	{
			reportError();
		}
	}
}

File 6: myImage.java

/**
 *
 * @(#)myImage.java
 *
 * This class is used to render an image on panel
 * which its being used.
 *
 * @author
 * @version 1.00, 2010/6/24
 */
 
package uniKEY;

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * This class contains methods used to resize and render an image on Panel.
 */
 
public class myImage extends JLabel
{

	/**
	 * This creates a variable of ImageIcon class to hold the image.
	 */	 

 	ImageIcon _temp;
 	 	
	/**
	 * The constructor loads up an image representing default state to be displayed on the panel and renders it. 
	 */
 	
    public myImage()
    {
    	_temp = new ImageIcon("default.jpg");
    	_temp = resizeImage(_temp);
		this.setIcon(_temp);
    }

	/**
	 * The method sets an image on to the panel its being called upon based on the parameters being passed onto it.
	 *
	 * @param _myState current state of the application
	 */

    public void setImage(States _myState)
    {
    	/**
    	 * if the state is open then an image representing default state is rendered
    	 */    	
    	if(_myState == States.DEFAULT)
    	{
    		/**
    		 * default image     	 
    		 * <IMG src="default.jpg" />
    		 */
    		this.setIcon(resizeImage(new ImageIcon("default.jpg")));
    	}
    	/*
    	 * if the state is open then an image representing open state is rendered
    	 */   
    	else if(_myState == States.OPEN)
    	{
    		/**
    		 * default image     	 
    		 * <IMG src="open.jpg" />
    		 */
			this.setIcon(resizeImage(new ImageIcon("open.jpg")));
    	}
    	/**
    	 * if the state is closed then an image representing closed state is rendered 
    	 */   
    	else if(_myState == States.CLOSED)
    	{
    		/**
    		 * default image     	 
    		 * <IMG src="closed.jpg" />
    		 */
    		this.setIcon(resizeImage(new ImageIcon("closed.jpg")));
		}
   	}

	/**
	 * The method resizes an image and returns it back to the sender.
	 *
	 * @param _myImage an image which needs to be resized
	 * @return _newIcon resized image of size 50x38 pixels
	 */
   	
	private ImageIcon resizeImage(ImageIcon _myImage)
	{
		Image _img = _myImage.getImage();
		Image _newimg = _img.getScaledInstance(50, 38,Image.SCALE_SMOOTH); 
		ImageIcon _newIcon = new ImageIcon(_newimg); 
		return _newIcon;
	}
}

File 7: myLoader.java

/**
 * @(#)loader.java
 *
 *
 * @author
 * @version 1.00, 2010/6/24
 */
 
package uniKEY;

import java.*;
import java.awt.*;
import javax.swing.*;
import java.lang.*;

/**
 * This class is the entry point of the application.
 * It sets all the frame properties, renders the frame and then starts the application.
 */
 
public class myLoader extends JFrame
{

	/**
	 * This holds an Instance of myUI class
	 *
	 * @see uniKEY.myUI
	 */
	 
	private myUI _myUIObj;

	/**
	 * The constructor creates a frame and loads up a panel onto it.
	 */
	
	public myLoader()
	{
		_myUIObj = new myUI();
		setSize(180,300);
		setTitle("UniKEY");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
		getContentPane().add(_myUIObj);
	}
	
	
	/**
	 * The entry point of the program.
	 */
	 
    public static void main(String[] args)
    {
		new myLoader();
    }
}

and lastly
File 8: myUI.java

/**
 * @(#)ui.java
 *
 *
 * @author
 * @version 1.5, 2010/6/24
 */

package uniKEY;

import java.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;


/**
 * This class renders a panel and objects onto it and adds functionality to the objects in it.
 */
 	
class myUI extends JPanel
{
	myFunctions _myFObj;
	
	/**
	 * This holds an object of type JPanel
	 */
	 
	private JPanel _mainPanel;
	
	/**
	 * This holds an object of type JPanel
	 */
	private JPanel _myImagePanel;

	/**
	 * This holds an object of type JPanel
	 */

	private JPanel _keypadPanel;
  	
	/**
	 * This holds an array of objects of type JButtons
	 */
	 
	public JButton _button[];
	
	
	/**
	 * This holds an objects of type JLabel
	 */
	
	private JLabel _imageLabel; 
  	
	/**
	 * This holds an object of myImage class
	 *
	 * @see uniKEY.myImage
	 */
	 
	public myImage _myAccessImage;
	

	/**
	 * The constructor tries to set the UI to Windows style and initializes the variables needed by the application.
	 * It also renders the layout, panel and sets the state of the application to default state.
	 *
	 * @exception java.lang.Exception If the specified UI look and feel could not be loaded
	 * @see #loadDB()
	 * @see #renderLayout()
	 * @see #renderFrame()
	 */
	 
    public myUI()
    {
    	try
    	{
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e)
        {
            System.err.println("An Error has occoured while loading the UI. Loading Default UI instead.\n" + e.getMessage());
        }
   		renderLayout();
   		renderFrame();
 		_myFObj.setState(new defaultState());
        _myFObj.setStates(States.DEFAULT);
	}

	/**
	 * The method tries to render layout on the frame.
	 *
	 * @see #myUI()
	 */
	 	
	public void renderLayout()
	{
		
		/**
		 * The objects declared are instantized
		 */
	 
    	_mainPanel = new JPanel();
    	_keypadPanel = new JPanel();
    	_myImagePanel = new JPanel();
    	_button = new JButton[12];
 		_myAccessImage = new myImage();
   
    	/**
		 * Setting the layout of the panel
		 */
		 	
		_mainPanel.setLayout(new BorderLayout());
		_keypadPanel.setLayout(new GridLayout(4,3,0,0));
		_myImagePanel.setLayout(new FlowLayout());
		
	   	/**
		 * Initializing the button and setting the preferable size
		 */
		 				
		for (int i=0; i<=9; i++)
		{
			_button[i]= new JButton(String.valueOf(i));
			_button[i].setPreferredSize(new Dimension(55,55));
		}
		
		_button[10] = new JButton("*");
		_button[0] = new JButton("0");
		_button[11] = new JButton("#");
		
		/**
		 * Adding Buttons to the panel
		 */
		 
		for (int i=1; i<=3; i++)
		{
			_keypadPanel.add(_button[i]);	 	
		}

		for (int i=4; i<=6; i++)
		{
			_keypadPanel.add(_button[i]);	 	
		}
		
		for (int i=7; i<=9; i++)
		{
			_keypadPanel.add(_button[i]);	 	
		}

		_keypadPanel.add(_button[10]);
		_keypadPanel.add(_button[0]);
		_keypadPanel.add(_button[11]);

	   	/**
		 * Adding a Listener to the Buttons on the panel
		 */
		 
		for(int i=0;i<12;i++)
		{
			_button[i].addActionListener(new myFunctions());
		}
				
	   	/**
		 * Adding the object to the panel
		 */
		 
		_myImagePanel.add(_myAccessImage);
	}

	/**
	* The method adds the panels to the frame.
	*
	* @see #myUI()
	*/
	 	
    public void renderFrame()
    {	

		_mainPanel.add(_keypadPanel,BorderLayout.NORTH);
		_mainPanel.add(_myImagePanel,BorderLayout.SOUTH);
		this.add(_mainPanel);
    }

}

whenever I run the myLoader I come across Null Pointer Exceptions.

Exception in thread "main" java.lang.NullPointerException
    at uniKEY.myUI.<init>(myUI.java:90)
    at uniKEY.myLoader.<init>(myLoader.java:38)
    at uniKEY.myLoader.main(myLoader.java:55)

one at myUI.java on line which says

_myFObj.setState(new defaultState());

and the other two in myLoader pointing at the lines

_myUIObj = new myUI();

and

new myLoader();

respectively..

the same code has worked earlier.. I wonder whats the problem now..
can you guys please help me fix this?

Edited 6 Years Ago by emclondon: n/a

There must be close on 1000 lines of code there - so, sorry, but I don't have that kind of free time.
But
null pointer means either an un-initialised variable or you valled a method expecting it to return something, but it didn't.
Here's what you need to do:
look at the line in your program where the NPE is raised. How many variables or retrned values are there? If its very complex, break it down into smaller steps and see which one throws the NPE. Add a line immediately before that staement to print all the variables and returned values, so you can see which is null.
When you know what is null you can work back to see why.

Hello mate,

thanks for the reply. The same code was used earlier and it didn't give my any errors.
It only started acting strange since I partitioned the code form UI. The three areas where the NPE occours are in my loader, and in my main frame of my application.

my Loader has cannot load up an instance of my main frame nor its own constructor. I dont know why. How do I debug this issue? Im expecting a frame to be generated from my loader and a panel to be generated from my UI class. neither of them work :/

similarly, in the constructor of my UI class I try setting up the state of the application by calling up methods in different class and setting up state variables and instantiating the default state class. but that one doesnt work too.

===================================

I dont know how to design this application properly now.


I have a Loader Class which generates a frame and Calls up UI Class to build UI which calls up the Functions Class and gets its functionality.


My simple query is where do I put my States? I know they dont go in loader so Its either in UI or functions class. In my old program, I had my states all set up and working fine in a single file (UI) now If only I could know where to put all the state's stuff, it might solve the problem (im assuming).

ok, I have made some minor modifications to the program and brought back the state's part to myUI, but the problem still exists! and the problem is SILLY!

I cant call the constructor of the myLoader class! it gives me a null pointer exception

public class myLoader extends JFrame
{
     private myUI _myUIObj;

     public myLoader()
     {
          _myUIObj = new myUI();   <---------------------------- HERE
     }

     public static void main(String[] args)
     {
          new myLoader();   <---------------------------- HERE
     }
}

the null pointer occours at new myLoader(); I dont know how to break down this statement to debug the problem. so I cant fix it myself.

Simiarly, I cant instantiate an object of myUI class from myLoader class and cant call the object of myUI class / cannot instantiate an object of myFunctions class and cannot use the object. it gives me an null pointer when I do the both.

how do I fix this?

class myUI extends JPanel
{
    myFunctions _myFObj;
	 
    public myUI()
    {
         // OTHER CODE HERE...
         _myFObj.loadDB();      <---------------------------- HERE
    }
}

Edited 6 Years Ago by emclondon: n/a

This question has already been answered. Start a new discussion instead.