![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.cuf.ui.builder.StateHandlingBuilderDelegate Maven / Gradle / Ivy
The newest version!
package net.sf.cuf.ui.builder;
import net.sf.cuf.model.state.MinMaxState;
import org.jdom2.Element;
import java.util.List;
import java.util.Collection;
import java.lang.reflect.Constructor;
import java.awt.Color;
import net.sf.cuf.state.State;
import net.sf.cuf.state.SimpleState;
import net.sf.cuf.state.StateAdapter;
import net.sf.cuf.state.MutableState;
import net.sf.cuf.state.StateExpression;
import net.sf.cuf.state.SimpleStateExpression;
import net.sf.cuf.state.ui.SwingSelectedState;
import net.sf.cuf.state.ui.SwingEnabledAdapter;
import net.sf.cuf.state.ui.SwingEnabledState;
import net.sf.cuf.state.ui.SwingListSelectionState;
import net.sf.cuf.state.ui.SwingListModelFillState;
import net.sf.cuf.state.ui.SwingTableModelFillState;
import net.sf.cuf.state.ui.SwingTreeModelFillState;
import net.sf.cuf.state.ui.SwingTreeSelectionState;
import net.sf.cuf.state.ui.SwingEditableAdapter;
import net.sf.cuf.state.ui.SwingJTableEnabledAdapter;
import net.sf.cuf.state.ui.SwingSelectedAdapter;
import net.sf.cuf.state.ui.SwingVisibleAdapter;
import net.sf.cuf.state.ui.SwingBorderAdapter;
import net.sf.cuf.state.ui.SwingDocumentState;
import net.sf.cuf.state.ui.SwingBackgroundAdapter;
import net.sf.cuf.model.state.CollectionFilledState;
import net.sf.cuf.model.state.EqualsState;
import net.sf.cuf.model.state.NullState;
import net.sf.cuf.model.state.RegExpState;
import net.sf.cuf.model.state.ValueState;
import net.sf.cuf.model.ValueModel;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.JComboBox;
import javax.swing.border.Border;
import javax.swing.text.JTextComponent;
/**
* The StateHandlingBuilderDelegate class handles the "statehandling" entry of
* a xml2swing XML description.
*/
class StateHandlingBuilderDelegate implements SwingXMLBuilder.BuilderDelegate
{
/**
* Build the specific part of the delegate.
* @param pBuilder the builder that controls the creation process
* @param pStateHandlingElement the JDOM element the delegate should handle, "statehandling" in our case
*/
public void build(final SwingXMLBuilder pBuilder, final Element pStateHandlingElement)
{
List statehandlings= pStateHandlingElement.getChildren();
for (final Element element : statehandlings)
{
String objectType = element.getName();
Object object = null;
// get id
String id = element.getAttributeValue(SwingXMLBuilder.ID_ATTRIBUTE);
//
switch (objectType)
{
case SwingXMLBuilder.STATE_ELEMENT:
object = createState(element, id, pBuilder);
break;
case SwingXMLBuilder.EXPRESSION_ELEMENT:
object = createStateExpression(element, id, pBuilder);
break;
case SwingXMLBuilder.STATEADAPTER_ELEMENT:
object = createStateAdapter(element, id, pBuilder);
break;
case SwingXMLBuilder.SETSTATE_ELEMENT:
setState(element, id, pBuilder);
break;
default:
throw SwingXMLBuilder.createException("unknown state handling " + objectType,
element);
}
// put it in our builder's map
if ((id != null) && (object != null))
{
if (pBuilder.getNameToNonVisual().containsKey(id))
{
throw SwingXMLBuilder.createException("nonvisual with id " + id + " already defined", element);
}
else
{
pBuilder.getNameToNonVisual().put(id, object);
}
}
}
}
/**
* Creates a new state.
* @param pElement element describing the object
* @param pId value of the id attribute of pElement
* @param pBuilder our builder
* @throws IllegalArgumentException if we have a problem (parameters, ...)
* @return the new state, never null
*/
@SuppressWarnings({"ConstantConditions"})
private Object createState(final Element pElement, final String pId, final SwingXMLBuilder pBuilder) throws IllegalArgumentException
{
if (pId==null)
throw SwingXMLBuilder.createException("id of "+pElement.getName()+" must not be null",
pElement);
// get needed attributes
String type = pElement.getAttributeValue(SwingXMLBuilder.TYPE_ATTRIBUTE);
String refId= pElement.getAttributeValue(SwingXMLBuilder.REF_ATTRIBUTE);
State state= null;
if ("simple".equals(type))
{
state= new SimpleState();
}
else if ("custom".equals(type))
{
Class> customClass= SwingXMLBuilder.getClass(pElement);
if (refId==null)
{
// use default constructor
try
{
state= (State)customClass.newInstance();
}
catch (Exception e)
{
throw SwingXMLBuilder.createException("could not create state for class "+customClass,
e, pElement);
}
}
else
{
// use single argument constructor
Object ref= pBuilder.getNonVisualObject(refId);
if (ref == null)
{
ref= pBuilder.getComponentByAnyName(refId);
}
if (ref==null)
{
throw SwingXMLBuilder.createException(refId+ " doesn't map to an object",
pElement);
}
try
{
Constructor>[] constructors= customClass.getConstructors();
for (final Constructor> constructor : constructors)
{
Class>[] parameters = constructor.getParameterTypes();
if (parameters.length != 1)
continue;
if (parameters[0].isAssignableFrom(ref.getClass()))
{
Object[] args = {ref};
state = (State) constructor.newInstance(args);
}
}
}
catch (Exception e)
{
throw SwingXMLBuilder.createException("could not create state for class "+customClass+
" with argument "+ref, e, pElement);
}
if (state==null)
{
throw SwingXMLBuilder.createException("could not create state for class "+customClass+
" with argument "+ref, pElement);
}
}
}
else if ("value".equals(type))
{
Object ref= pBuilder.getNonVisualObject(refId);
if (!(ref instanceof ValueModel))
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+")is no ValueModel",
pElement);
}
state= new ValueState((ValueModel>)ref);
}
else if ("enabled".equals(type))
{
Object ref= pBuilder.getNonVisualObject(refId);
if (ref instanceof Action)
{
state= new SwingEnabledState((Action)ref);
}
else
{
ref= pBuilder.getComponentByAnyName(refId);
if (ref instanceof JComponent)
{
state= new SwingEnabledState((JComponent)ref);
}
}
if (state==null)
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not known",
pElement);
}
}
else if ("selected".equals(type))
{
Object ref= pBuilder.getComponentByAnyName(refId);
if (!(ref instanceof AbstractButton))
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is no AbstractButton",
pElement);
}
state= new SwingSelectedState((AbstractButton)ref);
}
else if ("document".equals(type))
{
Object ref= pBuilder.getComponentByAnyName(refId);
if (!(ref instanceof JTextComponent))
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is no JTextComponent",
pElement);
}
state= new SwingDocumentState((JTextComponent)ref);
}
else if ("listSelection".equals(type))
{
Object ref = pBuilder.getComponentByAnyName(refId);
int index = SwingListSelectionState.NO_SELECTION;
boolean reverseIndex= false;
String refId2 = pElement.getAttributeValue(SwingXMLBuilder.REF2_ATTRIBUTE);
if (refId2!=null)
{
String stringIndex= refId2;
if (refId2.startsWith("r"))
{
reverseIndex= true;
stringIndex= refId2.substring(1);
}
try
{
index= Integer.parseInt(stringIndex);
}
catch (NumberFormatException e)
{
throw SwingXMLBuilder.createException("ref2 index ("+refId2+") is not an integer",
pElement);
}
}
if (ref==null)
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not known",
pElement);
}
else if (ref instanceof JList)
{
state= new SwingListSelectionState((JList)ref, index, reverseIndex);
}
else if (ref instanceof JTable)
{
state= new SwingListSelectionState((JTable)ref, index, reverseIndex);
}
else if (ref instanceof JComboBox)
{
state= new SwingListSelectionState((JComboBox)ref, index, reverseIndex);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a JList/JTable/JComboBox",
pElement);
}
}
else if ("listFill".equals(type))
{
Object ref= pBuilder.getComponentByAnyName(refId);
int threshold = getThreshold(pElement);
if (ref instanceof JList)
{
state= new SwingListModelFillState((JList)ref, threshold);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a JList",
pElement);
}
}
else if ("tableFill".equals(type))
{
Object ref= pBuilder.getComponentByAnyName(refId);
int threshold = getThreshold(pElement);
if (ref instanceof JTable)
{
state= new SwingTableModelFillState((JTable)ref, threshold);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a JTable",
pElement);
}
}
else if ("treeFill".equals(type))
{
Object ref= pBuilder.getComponentByAnyName(refId);
int threshold = getThreshold(pElement);
if (ref instanceof JTree)
{
state= new SwingTreeModelFillState(((JTree)ref).getModel(), false, threshold);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a JTree",
pElement);
}
}
else if ("collectionFill".equals(type))
{
Object ref= pBuilder.getNonVisualObject(refId);
if (ref instanceof ValueModel)
{
state= new CollectionFilledState((ValueModel>)ref);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a ValueModel",
pElement);
}
}
else if ("treeSelection".equals(type))
{
Object ref= pBuilder.getComponentByAnyName(refId);
if (ref instanceof JTree)
{
state= new SwingTreeSelectionState((JTree)ref);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a JTree",
pElement);
}
}
else if ("nullState".equals(type))
{
Object ref= pBuilder.getNonVisualObject(refId);
if (ref instanceof ValueModel)
{
state = new NullState((ValueModel>)ref);
}
else
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a ValueModel",
pElement);
}
}
else if ("equals".equals(type))
{
Object ref = pBuilder.getNonVisualObject(refId);
String refId2 = pElement.getAttributeValue(SwingXMLBuilder.REF2_ATTRIBUTE);
String value = pElement.getAttributeValue(SwingXMLBuilder.VALUE_ATTRIBUTE);
Object ref2 = pBuilder.getNonVisualObject(refId2);
if (!(ref instanceof ValueModel))
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a ValueModel",
pElement);
}
if (refId2!=null)
{
if (ref2 instanceof ValueModel)
{
state = new EqualsState( (ValueModel>)ref, (ValueModel>)ref2);
}
else
{
state = new EqualsState( (ValueModel>)ref, ref2);
}
}
else
{
state = new EqualsState( (ValueModel>)ref, value);
}
}
else if ("regexp".equals(type))
{
Object ref = pBuilder.getNonVisualObject(refId);
String value = pElement.getAttributeValue(SwingXMLBuilder.VALUE_ATTRIBUTE);
if (!(ref instanceof ValueModel))
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a ValueModel",
pElement);
}
if (value==null)
{
throw SwingXMLBuilder.createException("selected state value must not be null", pElement);
}
state = new RegExpState( (ValueModel>)ref, value);
}
else if ("minmax".equals(type))
{
Object ref = pBuilder.getNonVisualObject(refId);
String minValue= pElement.getAttributeValue(SwingXMLBuilder.MIN_ATTRIBUTE);
String maxValue= pElement.getAttributeValue(SwingXMLBuilder.MAX_ATTRIBUTE);
String inverted= pElement.getAttributeValue(SwingXMLBuilder.INVERT_ATTRIBUTE);
if (!(ref instanceof ValueModel))
{
throw SwingXMLBuilder.createException("selected state ref ("+refId+") is not a ValueModel",
pElement);
}
if (minValue==null && maxValue==null)
{
throw SwingXMLBuilder.createException("either min or max must be set", pElement);
}
Integer minIntValue;
try
{
minIntValue= (minValue!=null?Integer.parseInt(minValue):null);
}
catch (NumberFormatException e)
{
throw SwingXMLBuilder.createException("min value ("+minValue+") is not an integer",
pElement);
}
Integer maxIntValue;
try
{
maxIntValue= (maxValue!=null?Integer.parseInt(maxValue):null);
}
catch (NumberFormatException e)
{
throw SwingXMLBuilder.createException("max value ("+maxValue+") is not an integer",
pElement);
}
state = new MinMaxState( (ValueModel>)ref, minIntValue, maxIntValue, Boolean.valueOf(inverted));
}
if (state==null)
{
throw SwingXMLBuilder.createException("unknown state type "+type, pElement);
}
state.setName(pId);
return state;
}
/**
* Small helper to extract the threshold from the REF2 attribute.
* @param pElement the element we check, must not be null
* @return the threshold or 1 if no one is defined
*/
private int getThreshold(Element pElement)
{
int threshold= 1;
String refId2 = pElement.getAttributeValue(SwingXMLBuilder.REF2_ATTRIBUTE);
if (refId2!=null)
{
try
{
threshold= Integer.parseInt(refId2);
}
catch (NumberFormatException e)
{
throw SwingXMLBuilder.createException("ref2 threshold ("+refId2+") is not an integer",
pElement);
}
}
return threshold;
}
/**
* Creates a new state expression.
* @param pElement element describing the object
* @param pId value of the id attribute of pElement
* @param pBuilder our builder
* @throws IllegalArgumentException if we have a problem (parameters, ...)
* @return the new state expression, never null
*/
private Object createStateExpression(final Element pElement, final String pId, final SwingXMLBuilder pBuilder) throws IllegalArgumentException
{
if (pId==null)
throw SwingXMLBuilder.createException("id of "+pElement.getName()+" must not be null", pElement);
State startState = getState (pElement, pBuilder, SwingXMLBuilder.REF_ATTRIBUTE);
boolean invert = getInvertFlag(pElement);
StateExpression stateExpression= new SimpleStateExpression(startState, invert);
List conditions= pElement.getChildren();
for (final Element element : conditions)
{
String elementName= element.getName();
State state = getState(element, pBuilder, SwingXMLBuilder.REF_ATTRIBUTE);
invert = getInvertFlag(element);
if ("and".equals(elementName))
stateExpression.and(state, invert);
else if ("andNot".equals(elementName))
stateExpression.andNot(state);
else if ("or".equals(elementName))
stateExpression.or(state, invert);
else if ("orNot".equals(elementName))
stateExpression.orNot(state);
else if ("xor".equals(elementName))
stateExpression.xor(state, invert);
else if ("xorNot".equals(elementName))
stateExpression.xorNot(state);
}
return stateExpression;
}
/**
* Creates a new state adapter.
* @param pElement element describing the object
* @param pId value of the id attribute of pElement
* @param pBuilder our builder
* @throws IllegalArgumentException if we have a problem (parameters, ...)
* @return the new state adapter, never null
*/
private Object createStateAdapter(final Element pElement, final String pId, final SwingXMLBuilder pBuilder) throws IllegalArgumentException
{
// get needed attributes
String type = pElement.getAttributeValue(SwingXMLBuilder.TYPE_ATTRIBUTE);
State state = getState(pElement, pBuilder, SwingXMLBuilder.REF_ATTRIBUTE);
StateAdapter stateAdapter= null;
if ("custom".equals(type))
{
Class> customClass= SwingXMLBuilder.getClass(pElement);
try
{
Class>[] params = {State.class};
Constructor> constructor= customClass.getConstructor(params);
Object[] args = {state};
stateAdapter= (StateAdapter)constructor.newInstance(args);
}
catch (Exception e)
{
throw SwingXMLBuilder.createException("could not create StateAdapter for class "+customClass+
" with state argument "+state, e, pElement);
}
}
else if ("editable".equals(type))
{
stateAdapter= new SwingEditableAdapter(state);
}
else if ("enabled".equals(type))
{
boolean deep= Boolean.valueOf(
pElement.getAttributeValue(SwingXMLBuilder.DEEP_ATTRIBUTE));
boolean handleOpaque= Boolean.valueOf(
pElement.getAttributeValue(SwingXMLBuilder.OPAQUE_ATTRIBUTE));
stateAdapter= new SwingEnabledAdapter(state, deep, handleOpaque);
}
else if ("tableEnabled".equals(type))
{
stateAdapter= new SwingJTableEnabledAdapter(state);
}
else if ("selected".equals(type))
{
stateAdapter= new SwingSelectedAdapter(state);
}
else if ("visible".equals(type))
{
stateAdapter= new SwingVisibleAdapter(state);
}
else if ("border".equals(type))
{
Border border= VisualBuilderDelegate.getBorder(pElement.getChild("border"));
if (border==null)
stateAdapter= new SwingBorderAdapter(state);
else
stateAdapter= new SwingBorderAdapter(state, border);
}
else if ("background".equals(type))
{
Color color= VisualBuilderDelegate.getColor(pElement, 0);
if (color==null)
stateAdapter= new SwingBackgroundAdapter(state);
else
stateAdapter= new SwingBackgroundAdapter(state, color);
}
if (stateAdapter==null)
{
throw SwingXMLBuilder.createException("unknown state adapter type "+type, pElement);
}
// attach all adaptees to the adapter
List adaptees= pElement.getChildren(SwingXMLBuilder.ADAPTEE_ELEMENT);
for (final Element element : adaptees)
{
String id = element.getAttributeValue(SwingXMLBuilder.REF_ATTRIBUTE);
Object adaptee= pBuilder.getComponentByAnyName(id);
if (adaptee==null)
{
adaptee= pBuilder.getNonVisualObject(id);
}
if (adaptee==null)
{
throw SwingXMLBuilder.createException("unknown adaptee "+id, pElement);
}
boolean invert = getInvertFlag(element);
stateAdapter.add(adaptee, invert);
}
if (pId!=null)
{
stateAdapter.setName(pId);
}
return stateAdapter;
}
/**
* Checks the invert attribute.
* @param pElement element describing the object
* @return true if the invert attribute is available and is "true", false otherwise
*/
private boolean getInvertFlag(final Element pElement)
{
boolean invert= false;
if (pElement.getAttribute(SwingXMLBuilder.INVERT_ATTRIBUTE)!=null)
{
invert= "true".equals(
pElement.getAttributeValue(SwingXMLBuilder.INVERT_ATTRIBUTE));
}
return invert;
}
/**
* Gets a state from the non visual map.
* @param pElement element describing the object
* @param pBuilder our builder
* @param pAttributeName name of the id attribute
* @throws IllegalArgumentException if we have a problem (parameters, ...)
* @return the state, never null
*/
private State getState(final Element pElement, final SwingXMLBuilder pBuilder, final String pAttributeName)
{
String refId= pElement.getAttributeValue(pAttributeName);
Object ref = pBuilder.getNonVisualObject(refId);
if (!(ref instanceof State))
{
throw SwingXMLBuilder.createException("ref "+refId+" is no state", pElement);
}
return (State)ref;
}
/**
* Sets a state to a value.
* @param pElement element describing the object
* @param pId value of the id attribute of pElement
* @param pBuilder our builder
* @throws IllegalArgumentException if we have a problem (parameters, ...)
*/
private void setState(final Element pElement, final String pId, final SwingXMLBuilder pBuilder) throws IllegalArgumentException
{
Object ref= pBuilder.getNonVisualObject(pId);
if (!(ref instanceof MutableState))
{
throw SwingXMLBuilder.createException("state "+pId+" is not a mutable state", pElement);
}
// get needed attributes
String enabled= pElement.getAttributeValue(SwingXMLBuilder.ENABLED_ATTRIBUTE);
MutableState mutableState= (MutableState)ref;
mutableState.setEnabled("true".equals(enabled));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy