All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.cuf.state.SimpleStateExpression Maven / Gradle / Ivy

There is a newer version: 2.5.3
Show newest version
package net.sf.cuf.state;

import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.util.List;
import java.util.ArrayList;

/**
 * This class implements a StateExpression, see the interface for a
 * description of what added value SimpleStateExpression provides.
 */
public class SimpleStateExpression extends AbstractState implements StateExpression, ChangeListener
{
    /** marker for the value operation */
    private static final String VALUE= "value";
    /** marker for the and operation */
    private static final String AND  = "and";
    /** marker for the or operation */
    private static final String OR   = "or";
    /** marker for the xor operation */
    private static final String XOR  = "xor";

    /** the list of all states that form the expression */
    private List       mStates;
    /** the invert marker of each state */
    private List     mInverts;
    /** the operation for each state */
    private List      mOperations;

    /**
     * Creates an expression and sets the initial state. Use and/or/xor to add
     * additional states.
     * @param pState the initial state
     */
    public SimpleStateExpression(final State pState)
    {
        this(pState, false);
    }

    /**
     * Creates an expression and sets the initial state. Use and/or/xor to add
     * additional states.
     * @param pState the initial state
     * @param pInvert true if we should we should inverse the state of pState
     */
    public SimpleStateExpression(final State pState, final boolean pInvert)
    {
        super();
        mIsEnabled    = pState.isEnabled();
        mIsInitialized= pState.isInitialized();
        if (pInvert)
            mIsEnabled= !mIsEnabled;
        mStates      = new ArrayList<>();
        mOperations  = new ArrayList<>();
        mInverts     = new ArrayList<>();
        add(pState, pInvert, VALUE);
    }

    /**
     * Checks if we are in a defined state (either enabled or disabled).
     * We are in a defined state when all involved state are defined.
     * @return true if we have a defined state, false otherwise
     */
    public boolean isInitialized()
    {
        checkDisposed();
        for (final State state : mStates)
        {
            if (!state.isInitialized())
            {
                return false;
            }
        }
        return true;
    }

    public void and(final State pState)
    {
        and(pState, false);
    }

    public void andNot(final State pState)
    {
        and(pState, true);
    }

    public void and(final State pState, final boolean pInvert)
    {
        add(pState, pInvert, AND);
        checkState(pState);
    }

    public void or(final State pState)
    {
        or(pState, false);
    }

    public void orNot(final State pState)
    {
        or(pState, true);
    }

    public void or(final State pState, final boolean pInvert)
    {
        add(pState, pInvert, OR);
        checkState(pState);
    }

    public void xor(final State pState)
    {
        xor(pState, false);
    }

    public void xorNot(final State pState)
    {
        xor(pState, true);
    }

    public void xor(final State pState, final boolean pInvert)
    {
        add(pState, pInvert, XOR);
        checkState(pState);
    }

    /**
     * Small helper that combines common stuff of the add/or/xor methods.
     * @param pState the state to add
     * @param pInvert true if we should invert the state
     * @param pOperation VALUE, AND, OR, XOR
     */
    private void add(final State pState, final boolean pInvert, final String pOperation)
    {
        checkDisposed();
        if (!mStates.contains(pState))
        {
            pState.addChangeListener(this);
        }
        mStates    .add(pState);
        mOperations.add(pOperation);
        mInverts   .add(pInvert);
    }

    /**
     * Invoked when the one of our states has has changed its state.
     * @param pChangeEvent  a ChangeEvent object, must have a State as its source
     */
    public void stateChanged(final ChangeEvent pChangeEvent)
    {
        checkDisposed();
        Object  reason = ((State)pChangeEvent.getSource()).getChangeReason();
        checkState(reason);
    }

    /**
     * Check if we need to fire a change event.
     * @param pReason reason for the change (if we change at all)
     */
    private void checkState(final Object pReason)
    {
        if (!isInitialized())
        {
            mIsInitialized= false;
            return;
        }

        boolean initializedChanged= false;
        if (!mIsInitialized)
        {
            // we are now initialized, so we must fire a change event in any case
            mIsInitialized    = true;
            initializedChanged= true;
        }

        boolean oldState= mIsEnabled;
        boolean newState= oldState;

        for (int i = 0; i < mStates.size(); i++)
        {
            State   state    = mStates.get(i);
            boolean isEnabled= state.isEnabled();
            Boolean invert   = mInverts.get(i);
            String  operation= mOperations.get(i);

            if (invert)
            {
                isEnabled= !isEnabled;
            }

            if (operation.equals(VALUE))
            {
                newState= isEnabled;
            }
            else if (operation.equals(AND))
            {
                newState= newState && isEnabled;
            }
            else if (operation.equals(OR))
            {
                newState= newState || isEnabled;
            }
            else if (operation.equals(XOR))
            {
                newState= newState ^ isEnabled;
            }
        }

        if (initializedChanged || (oldState!=newState))
        {
            mIsEnabled= newState;
            mReason   = pReason;
            try
            {
                fireStateChanged();
            }
            finally
            {
                mReason= null;
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy