
net.sf.cuf.state.AbstractState Maven / Gradle / Ivy
package net.sf.cuf.state;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
/**
* This class holds common code of mutable and immutable states.
*/
public class AbstractState implements State
{
/** our name (never null), defaults to "" */
protected String mName;
/** initialized status, defaults to false if the default constructor is used */
protected boolean mIsInitialized;
/** enable status, defaults to false if the default constructor is used */
protected boolean mIsEnabled;
/** marker if we are disposed (= no longer valid) */
private boolean mIsDisposed;
/** the registered listeners */
protected EventListenerList mListenerList;
/** null or state change reason */
protected Object mReason;
/** to avoid re-creation of an (immutable) object, each AbstractState
* uses only one ChangeEvent, it is created when the event is
* required for the first time */
private ChangeEvent mChangeEvent;
/**
* Create a new state with defaults.
*/
public AbstractState()
{
mName = "";
mIsInitialized= false;
mIsEnabled = false;
mIsDisposed = false;
mListenerList = new EventListenerList();
mReason = null;
}
/**
* Return the name of the state.
* @return the name of the state (never null)
*/
public String getName()
{
return mName;
}
/**
* Set the name of the state.
* @param pName the name of the state (must not be null)
* @throws java.lang.IllegalArgumentException if pState is null
*/
public void setName(final String pName)
{
checkDisposed();
if (pName==null)
{
throw new IllegalArgumentException("name must not be null");
}
mName= pName;
}
/**
* Checks if we are in a defined state (either enabled or disabled).
* @return true if we have a defined state, false otherwise
*/
public boolean isInitialized()
{
checkDisposed();
return mIsInitialized;
}
/**
* Checks the state.
* @return true if we are enabled, false if we are disabled or not initialized
*/
public boolean isEnabled()
{
checkDisposed();
return mIsEnabled;
}
/**
* During a callback, a listener can call this method to get a reason object
* for the change. If we are not in the stateChanged() callback method or
* we don't know the reason for the change, null is returned.
* @return null or the reason of a change
*/
public Object getChangeReason()
{
checkDisposed();
return mReason;
}
/**
* Helper method to fire a state change.
*/
protected void fireStateChanged()
{
checkDisposed();
// Process the listeners last to first, notifying
// those that are interested in this event
Object[] listeners = mListenerList.getListenerList();
for (int i= listeners.length-2; i>=0; i-=2)
{
if (listeners[i]==ChangeListener.class)
{
// lazy initialisation
if (mChangeEvent==null)
{
mChangeEvent= new ChangeEvent(this);
}
((ChangeListener)listeners[i+1]).stateChanged(mChangeEvent);
}
}
}
/**
* Add a listener. If we already know the listener, we do nothing.
* @param pStateChangeListener the listener to be added
*/
public void addChangeListener(final ChangeListener pStateChangeListener)
{
checkDisposed();
mListenerList.add(ChangeListener.class, pStateChangeListener);
}
/**
* Remove a listener. If we don't know the listener, we do nothing.
* @param pStateChangeListener the listener to be removed
*/
public void removeChangeListener(final ChangeListener pStateChangeListener)
{
checkDisposed();
mListenerList.remove(ChangeListener.class, pStateChangeListener);
}
/**
* Cleanup all resources: disconnect from any input sources
* and remove all listeners.
* Any method besides isDisposed, dispose or getName will throw an
* IllegalStateException after the State was disposed.
*/
public void dispose()
{
mIsDisposed= true;
mListenerList= new EventListenerList();
// TODO: check all derived classes if they need to release listeners etc.
}
/**
* Check if the state is disposed.
* @return true if the state is disposed (= no longer valid)
*/
public boolean isDisposed()
{
return mIsDisposed;
}
/**
* Helper method to throw a IllegalStateException if we are disposed.
* @throws IllegalStateException if the state is disposed
*/
protected void checkDisposed() throws IllegalStateException
{
if (mIsDisposed)
{
throw new IllegalStateException("state "+mName+" was already disposed");
}
}
/**
* Return a immutable list of all direct dependents of the value model.
* @return an immutablelList of all direct dependents
*/
public List getDependents()
{
checkDisposed();
Object[] ll= mListenerList.getListenerList();
List dependents= new ArrayList<>(mListenerList.getListenerCount());
for (int i = 0; i < ll.length; i+=2)
{
if (ll[i]==ChangeListener.class)
{
ChangeListener dependent= (ChangeListener)ll[i+1];
dependents.add(dependent);
}
}
return Collections.unmodifiableList(dependents);
}
/**
* Returns a string representation of the object.
*
* @return a string representation of the object.
*/
public String toString()
{
return super.toString() + "[name= " +
mName +
", isInitialized= " +
mIsInitialized +
", isEnabled= " +
mIsEnabled +
", reason= " +
mReason +
']';
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy