Revision: 459 http://skycastle.svn.sourceforge.net/skycastle/?rev=459&view=rev Author: zzorn Date: 2008-04-14 10:59:09 -0700 (Mon, 14 Apr 2008) Log Message: ----------- Moved common functionality of UI:s for properties to a common base class, and refactored TextFieldUi to use it. Now it should be considerably easier to implement a lot of the various UI:s, such as bar indicators and list and table views. Modified Paths: -------------- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/PropertyReferenceListener.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/TextFieldUi.java Added Paths: ----------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/AbstractPropertyUiObject.java Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java 2008-04-14 16:44:52 UTC (rev 458) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java 2008-04-14 17:59:09 UTC (rev 459) @@ -140,7 +140,8 @@ //---------------------------------------------------------------------- // MessagingFacade Implementation - public final void addIndirectUpdateListener( final UpdateListenerFilter filter, final GameObjectId observerId ) + public final void addIndirectUpdateListener( final UpdateListenerFilter filter, + final GameObjectId observerId ) { myMessagingFacade.addIndirectUpdateListener( filter, observerId ); } @@ -153,7 +154,8 @@ } - public final void addDirectUpdateListener( final UpdateListenerFilter filter, final MessageListener listener ) + public final void addDirectUpdateListener( final UpdateListenerFilter filter, + final MessageListener listener ) { myMessagingFacade.addDirectUpdateListener( filter, listener ); } @@ -248,25 +250,29 @@ myPropertyFacade.removeProperty( propertyIdentifier ); } - public void addPropertyElement( final String propertyIdentifier, final Serializable collectionPropertyItem ) + public final void addPropertyElement( final String propertyIdentifier, + final Serializable collectionPropertyItem ) throws ParameterValidationException { myPropertyFacade.addPropertyElement( propertyIdentifier, collectionPropertyItem ); } - public void removePropertyElement( final String propertyIdentifier, final Serializable collectionPropertyItem ) + public final void removePropertyElement( final String propertyIdentifier, + final Serializable collectionPropertyItem ) throws ParameterValidationException { myPropertyFacade.removePropertyElement( propertyIdentifier, collectionPropertyItem ); } - public void addPropertyMapping( final String propertyIdentifier, final Serializable key, final Serializable value ) + public final void addPropertyMapping( final String propertyIdentifier, + final Serializable key, + final Serializable value ) throws ParameterValidationException { myPropertyFacade.addPropertyMapping( propertyIdentifier, key, value ); } - public void removePropertyMapping( final String propertyIdentifier, final Serializable key ) + public final void removePropertyMapping( final String propertyIdentifier, final Serializable key ) throws ParameterValidationException { myPropertyFacade.removePropertyMapping( propertyIdentifier, key ); Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java 2008-04-14 16:44:52 UTC (rev 458) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java 2008-04-14 17:59:09 UTC (rev 459) @@ -15,6 +15,11 @@ */ public interface PropertyFacade extends Serializable +// TODO: Change the collection updates to also include an update of a specific collection element, +// and move to a list based model where insertion and change and removal positions are indicated with indexes. +// Leave a set based collection for later if needed. + +// TODO: Allow properties have as type some kind of GameObject interfaces / templates? { /** @@ -33,8 +38,8 @@ * @param propertyIdentifier identifier of the property to set. * @param value value to set the property to. * - * @throws ParameterValidationException describing the error if there was a - * problem with setting the property value. + * @throws ParameterValidationException describing the error if there was a problem with setting the + * property value. */ void setPropertyValue( String propertyIdentifier, Serializable value ) throws ParameterValidationException; @@ -42,8 +47,7 @@ /** * @param propertyIdentifier the name of the property to check for. * - * @return true if this {@link GameObject} has a property with the specified - * identifier. + * @return true if this {@link GameObject} has a property with the specified identifier. */ boolean hasProperty( String propertyIdentifier ); @@ -60,31 +64,31 @@ ParameterMetadata getPropertyMetadata( String propertyIdentifier ); /** - * Adds a new property with the specified metadata and initial value to this {@link - * GameObject}. + * Adds a new property with the specified metadata and initial value to this {@link GameObject}. * <p/> * The type of the property is infered from the initialValue. * * @param propertyIdentifier a Java style identifier for the property. * @param initialValue initial value for the property. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem with adding the property - * or setting the initial property value + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem with adding the property or setting the + * initial property value */ void addProperty( String propertyIdentifier, Serializable initialValue ) throws ParameterValidationException; /** - * Adds a new property with the specified metadata and initial value to this {@link - * GameObject}. + * Adds a new property with the specified metadata and initial value to this {@link GameObject}. * * @param propertyIdentifier a Java style identifier for the property. * @param initialValue initial value for the property. * @param propertyMetadata metadata for the property. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem with adding the property - * or setting the initial property value + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem with adding the property or setting the + * initial property value */ void addProperty( String propertyIdentifier, Serializable initialValue, @@ -102,8 +106,9 @@ * @param validators an array / variable length list with validators to use for restricting the * possible property values. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem with adding the property - * or setting the initial property value + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem with adding the property or setting the + * initial property value */ void addProperty( String propertyIdentifier, Serializable initialValue, @@ -113,8 +118,7 @@ /** - * Adds a new property with the specified metadata and initial value to this {@link - * GameObject}. + * Adds a new property with the specified metadata and initial value to this {@link GameObject}. * * @param propertyIdentifier a Java style identifier for the property. * @param initialValue initial value for the property. @@ -123,8 +127,9 @@ * @param validators an array / variable length list with validators to use for restricting the * possible property values. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem with adding the property - * or setting the initial property value + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem with adding the property or setting the + * initial property value */ <T extends Serializable> void addProperty( String propertyIdentifier, T initialValue, @@ -138,8 +143,9 @@ * * @param propertyIdentifier the identifier of the property to remove. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem with adding the property - * or setting the initial property value + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem with adding the property or setting the + * initial property value */ void removeProperty( String propertyIdentifier ) throws ParameterValidationException; @@ -148,10 +154,12 @@ /** * Adds an item to a collection property. * - * @param propertyIdentifier the identifier of a property to add an item to. The property should be of a {@link Collection} type. + * @param propertyIdentifier the identifier of a property to add an item to. The property should be + * of a {@link Collection} type. * @param collectionPropertyItem the item to add to the collection. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem. + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem. */ void addPropertyElement( String propertyIdentifier, Serializable collectionPropertyItem ) throws ParameterValidationException; @@ -159,10 +167,13 @@ /** * Removes an item from a collection property. * - * @param propertyIdentifier the identifier of a property to remove the item from. The property should be of a {@link Collection} type. - * @param collectionPropertyItem the item to remove, if found. The first instance of this item will be removed from the collection. + * @param propertyIdentifier the identifier of a property to remove the item from. The property + * should be of a {@link Collection} type. + * @param collectionPropertyItem the item to remove, if found. The first instance of this item will be + * removed from the collection. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem. + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem. */ void removePropertyElement( String propertyIdentifier, Serializable collectionPropertyItem ) throws ParameterValidationException; @@ -170,11 +181,14 @@ /** * Adds an entry to a map property. * - * @param propertyIdentifier the identifier of the property to add to. The property should be of a {@link Map} type. - * @param key the key of the new mapping. If it is the same as an existing key, that key will be replaced. + * @param propertyIdentifier the identifier of the property to add to. The property should be of a {@link + * Map} type. + * @param key the key of the new mapping. If it is the same as an existing key, that key + * will be replaced. * @param value the value to associate with the key. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem. + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem. */ void addPropertyMapping( String propertyIdentifier, Serializable key, Serializable value ) throws ParameterValidationException; @@ -182,10 +196,12 @@ /** * Removes an entry from a map property. * - * @param propertyIdentifier the identifier of a property to remove the item from. The property should be of a {@link Map} type. + * @param propertyIdentifier the identifier of a property to remove the item from. The property should be + * of a {@link Map} type. * @param key the key of the entry to remove, if found. * - * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if there was a problem. + * @throws ParameterValidationException a {@link ParameterValidationException} describing the error if + * there was a problem. */ void removePropertyMapping( String propertyIdentifier, Serializable key ) throws ParameterValidationException; Added: trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/AbstractPropertyUiObject.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/AbstractPropertyUiObject.java (rev 0) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/AbstractPropertyUiObject.java 2008-04-14 17:59:09 UTC (rev 459) @@ -0,0 +1,266 @@ +package org.skycastle.ui; + +import org.skycastle.core.GameObject; +import org.skycastle.core.GameObjectId; +import org.skycastle.util.parameters.ParameterMetadata; + +import javax.swing.*; +import java.io.Serializable; + +/** + * A base class for {@link UiObject}s that are bound to a specific property, and require updates when it + * changes. + * <p/> + * Calls the abstract update functions when the UI needs to update as a result of changes in the property. + * <p/> + * Automatically disables the UI component when the referenced property is not available. + * + * @author Hans Häggström + */ +public abstract class AbstractPropertyUiObject + extends UiObject +{ + + //====================================================================== + // Private Fields + + private final PropertyReference myPropertyReference = new PropertyReferenceImpl(); + + private JComponent myPropertyUi; + + //====================================================================== + // Private Constants + + private static final long serialVersionUID = 1L; + + //====================================================================== + // Protected Methods + + //---------------------------------------------------------------------- + // Protected Constructors + + /** + * Creates a new AbstractPropertyUiObject with a {@link PropertyReference} not bound to any property. + */ + protected AbstractPropertyUiObject() + { + } + + + /** + * Creates a new AbstractPropertyUiObject with a {@link PropertyReference} bound to the specified + * property. + * + * @param gameObjectId the id of the {@link GameObject} where the property is. + * @param propertyIdentifier the identifier of the property to bind to. + */ + protected AbstractPropertyUiObject( final GameObjectId gameObjectId, final String propertyIdentifier ) + { + myPropertyReference.setReference( gameObjectId, propertyIdentifier ); + } + + //---------------------------------------------------------------------- + // Abstract Protected Methods + + /** + * Does not need to register as listener to the {@link PropertyReference}, the calling code does that. + * + * @return the UI for the {@link UiObject}. + */ + protected abstract JComponent createUiInDerivedClass(); + + /** + * Called when there is an update in the editability or availability of the property. + * + * @param available true if the property is available, false if it is not (it was removed, or no access + * rights, or connection terminated, etc) + * @param editable true if the property is editable, false if not. + */ + protected abstract void updateStatus( final boolean available, final boolean editable ); + + + /** + * @param description the new user readable description for the property. + */ + protected abstract void updateDescription( final String description ); + + + /** + * @param propertyValue the new value of the property. + */ + protected abstract void updateValue( final Object propertyValue ); + + //---------------------------------------------------------------------- + // Other Protected Methods + + /** + * Override if collection properties are handled specially. + * + * @param addedElement an element that was added to the collection property. + */ + protected void updateAddedElement( final Serializable addedElement ) + { + updateValueFromModel(); + } + + + /** + * Override if collection properties are handled specially. + * + * @param removedElement an element that was removed from the collection property. + */ + protected void updateRemovedElement( final Serializable removedElement ) + { + updateValueFromModel(); + } + + + /** + * Called when an entry is added to or changed in a map property. + * <p/> + * Override if map properties are handled specially. + * + * @param key the key of the added entry. + * @param value the value for the key. + */ + protected void updatePutEntry( final Serializable key, final Serializable value ) + { + updateValueFromModel(); + } + + + /** + * Called when an entry is removed from a map property. + * <p/> + * Override if map properties are handled specially. + * + * @param key the key of the removed entry. + */ + protected void updateRemovedEntry( final Serializable key ) + { + updateValueFromModel(); + } + + + /** + * @return the {@link PropertyReference} to the property that this {@link AbstractPropertyUiObject} is + * bound to. + */ + protected final PropertyReference getPropertyReference() + { + return myPropertyReference; + } + + + @Override + protected final JComponent createUi() + { + myPropertyUi = createUiInDerivedClass(); + + myPropertyReference.addChangeListener( createPropertyReferenceListener() ); + + updateUiFromModel(); + + return myPropertyUi; + } + + + /** + * @return user readable description of the property, or null if not available. + */ + protected final String getDescription() + { + final ParameterMetadata propertyMetadata = myPropertyReference.getPropertyMetadata(); + + String description = null; + if ( propertyMetadata != null ) + { + description = propertyMetadata.getUiMetadata().getDescription(); + } + + return description; + } + + + /** + * Updates the UI to reflect the current status of the model (the {@link PropertyReference}). + */ + protected final void updateUiFromModel() + { + updateUiEnabledStateFromModel(); + + updateStatus( myPropertyReference.isAvailable(), + myPropertyReference.isEditable() ); + + updateDescription( getDescription() ); + + updateValueFromModel(); + } + + //====================================================================== + // Private Methods + + private void updateUiEnabledStateFromModel() + { + if ( myPropertyUi != null ) + { + myPropertyUi.setEnabled( myPropertyReference.isAvailable() ); + } + } + + + private PropertyReferenceListener createPropertyReferenceListener() + { + return new PropertyReferenceListener() + { + + public void onPropertyValueChange( final PropertyReference propertyReference ) + { + updateValueFromModel(); + } + + + public void onPropertyChanged( final PropertyReference propertyReference ) + { + updateUiFromModel(); + } + + + public void onPropertyElementAdded( final PropertyReference propertyReference, + final Serializable addedElement ) + { + updateAddedElement( addedElement ); + } + + + public void onPropertyElementRemoved( final PropertyReference propertyReference, + final Serializable removedElement ) + { + updateRemovedElement( removedElement ); + } + + + public void onPropertyEntryPut( final PropertyReference propertyReference, + final Serializable key, + final Serializable value ) + { + updatePutEntry( key, value ); + } + + + public void onPropertyEntryRemoved( final PropertyReference propertyReference, + final Serializable key ) + { + updateRemovedEntry( key ); + } + + }; + } + + + private void updateValueFromModel() + { + updateValue( myPropertyReference.getProperty( getId(), Object.class, null ) ); + } + +} Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/PropertyReferenceListener.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/PropertyReferenceListener.java 2008-04-14 16:44:52 UTC (rev 458) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/PropertyReferenceListener.java 2008-04-14 17:59:09 UTC (rev 459) @@ -1,5 +1,7 @@ package org.skycastle.ui; +import java.io.Serializable; + /** * A listener that is notified of property value changes. * @@ -7,16 +9,53 @@ */ public interface PropertyReferenceListener { + /** * Called when the value of the property changed. * - * @param propertyReference + * @param propertyReference the reference that was updated. */ void onPropertyValueChange( PropertyReference propertyReference ); /** - * Called when there was a larger change to the property. The availability, metadata, and value may have changed. + * Called when there was a larger change to the property. The availability, metadata, and value may have + * changed. + * + * @param propertyReference the reference that was updated. */ void onPropertyChanged( PropertyReference propertyReference ); + /** + * Called when a new element is added to a collection property. + * + * @param propertyReference the reference that was updated. + * @param addedElement the collection element that was added + */ + void onPropertyElementAdded( PropertyReference propertyReference, Serializable addedElement ); + + /** + * Called when a new element is added to a collection property. + * + * @param propertyReference the reference that was updated. + * @param removedElement the collection element that was removed + */ + void onPropertyElementRemoved( PropertyReference propertyReference, Serializable removedElement ); + + /** + * Called when a new entry is put to a map type property. + * + * @param propertyReference the reference that was updated. + * @param key the key that was set or added + * @param value the new value for the key + */ + void onPropertyEntryPut( PropertyReference propertyReference, Serializable key, Serializable value ); + + /** + * Called when a new entry is removed from a map type property. + * + * @param propertyReference the reference that was updated. + * @param key the key that was removed + */ + void onPropertyEntryRemoved( PropertyReference propertyReference, Serializable key ); + } Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/TextFieldUi.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/TextFieldUi.java 2008-04-14 16:44:52 UTC (rev 458) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/ui/TextFieldUi.java 2008-04-14 17:59:09 UTC (rev 459) @@ -1,7 +1,7 @@ package org.skycastle.ui; +import org.skycastle.core.GameObject; import org.skycastle.core.GameObjectId; -import org.skycastle.util.parameters.ParameterMetadata; import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.ValidationError; @@ -16,58 +16,52 @@ * @author Hans Haggstrom */ public class TextFieldUi - extends UiObject + extends AbstractPropertyUiObject { //====================================================================== // Private Fields - private final PropertyReference myPropertyReference = new PropertyReferenceImpl(); - private JTextField myTextField; //====================================================================== + // Private Constants + + private static final long serialVersionUID = 1L; + + //====================================================================== // Public Methods + //---------------------------------------------------------------------- + // Constructors + + /** + * Creates a new {@link TextFieldUi} with a {@link PropertyReference} not bound any property. + */ public TextFieldUi() { } - public TextFieldUi( GameObjectId gameObjectId, String propertyIdentifier ) - { - myPropertyReference.setReference( gameObjectId, propertyIdentifier ); - } - public PropertyReference getPropertyReference() + /** + * Creates a new {@link TextFieldUi} with a {@link PropertyReference} bound to the specified property. + * + * @param gameObjectId the id of the {@link GameObject} where the property is. + * @param propertyIdentifier the identifier of the property to bind to. + */ + public TextFieldUi( final GameObjectId gameObjectId, final String propertyIdentifier ) { - return myPropertyReference; + super( gameObjectId, propertyIdentifier ); } //====================================================================== // Protected Methods @Override - protected JComponent createUi() + protected JComponent createUiInDerivedClass() { myTextField = new JTextField( 20 ); - myPropertyReference.addChangeListener( new PropertyReferenceListener() - { - - public void onPropertyValueChange( final PropertyReference propertyReference ) - { - // TODO: Only update the text field if it is not currently being actively edited? - - updateValue(); - } - - public void onPropertyChanged( final PropertyReference propertyReference ) - { - update(); - } - - } ); - // TODO: Check for correctness while the field is being edited myTextField.addActionListener( new ActionListener() @@ -77,11 +71,11 @@ { try { - myPropertyReference.setProperty( getId(), myTextField.getText() ); + getPropertyReference().setProperty( getId(), myTextField.getText() ); } catch ( ParameterValidationException e1 ) { - final Object value = myPropertyReference.getProperty( getId(), Object.class, "" ); + final Object value = getPropertyReference().getProperty( getId(), Object.class, "" ); myTextField.setText( value.toString() ); // Show errors as tooltip, or on other error indicator? @@ -94,43 +88,28 @@ } ); - update(); - return myTextField; } - private void update() - { - myTextField.setEditable( myPropertyReference.isAvailable() && - myPropertyReference.isEditable() ); - myTextField.setEnabled( myPropertyReference.isAvailable() ); - updateValue(); - updateDescription(); + @Override + protected void updateStatus( final boolean available, final boolean editable ) + { + myTextField.setEditable( available && editable ); } - //====================================================================== - // Private Methods - private void updateDescription() + @Override + protected void updateDescription( final String description ) { - final ParameterMetadata propertyMetadata = myPropertyReference.getPropertyMetadata(); - if ( propertyMetadata != null ) - { - myTextField.setToolTipText( propertyMetadata.getUiMetadata().getDescription() ); - } - else - { - myTextField.setToolTipText( null ); - } + myTextField.setToolTipText( description ); } - private void updateValue() + @Override + protected void updateValue( final Object propertyValue ) { - myTextField.setText( String.valueOf( myPropertyReference.getProperty( getId(), - Object.class, - " " ) ) ); + myTextField.setText( propertyValue.toString() ); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.