Coverage Report - net.wotonomy.ui.swing.AdjustableAssociation
 
Classes in this File Line Coverage Branch Coverage Complexity
AdjustableAssociation
0% 
0% 
1.733
 
 1  
 /*
 2  
 Wotonomy: OpenStep design patterns for pure Java applications.
 3  
 Copyright (C) 2000 Intersect Software Corporation
 4  
 
 5  
 This library is free software; you can redistribute it and/or
 6  
 modify it under the terms of the GNU Lesser General Public
 7  
 License as published by the Free Software Foundation; either
 8  
 version 2.1 of the License, or (at your option) any later version.
 9  
 
 10  
 This library is distributed in the hope that it will be useful,
 11  
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 Lesser General Public License for more details.
 14  
 
 15  
 You should have received a copy of the GNU Lesser General Public
 16  
 License along with this library; if not, see http://www.gnu.org
 17  
 */
 18  
 
 19  
 package net.wotonomy.ui.swing;
 20  
 
 21  
 import java.awt.Adjustable;
 22  
 import java.awt.Component;
 23  
 import java.awt.event.AdjustmentEvent;
 24  
 import java.awt.event.AdjustmentListener;
 25  
 
 26  
 import net.wotonomy.foundation.NSArray;
 27  
 import net.wotonomy.foundation.internal.ValueConverter;
 28  
 import net.wotonomy.ui.EOAssociation;
 29  
 import net.wotonomy.ui.EODisplayGroup;
 30  
 
 31  
 /**
 32  
 * AdjustableAssociation binds any Adjustable component to
 33  
 * a display group.  Components implementing the adjustable
 34  
 * interface include: ScrollBar and JScrollBar.
 35  
 * Bindings are: 
 36  
 * <ul>
 37  
 * <li>value: a property convertable to/from a string</li> 
 38  
 * <li>enabled: a boolean property that determines whether
 39  
 * the user can select the text in the field</li> 
 40  
 * </ul>
 41  
 *
 42  
 * @author michael@mpowers.net
 43  
 * @author $Author: cgruber $
 44  
 * @version $Revision: 904 $
 45  
 */
 46  0
 public class AdjustableAssociation extends EOAssociation
 47  
         implements AdjustmentListener
 48  
 {
 49  0
     static final NSArray aspects = 
 50  0
         new NSArray( new Object[] {
 51  0
             ValueAspect, EnabledAspect
 52  
         } );
 53  0
     static final NSArray aspectSignatures = 
 54  0
         new NSArray( new Object[] {
 55  0
             AttributeToOneAspectSignature, 
 56  0
                         AttributeToOneAspectSignature, 
 57  0
                         AttributeToOneAspectSignature,
 58  0
                         AttributeToOneAspectSignature 
 59  
         } );
 60  0
     static final NSArray objectKeysTaken = 
 61  0
         new NSArray( new Object[] {
 62  0
             "value" 
 63  
         } );
 64  
                 
 65  
     /**
 66  
     * Constructor specifying the object to be controlled by this
 67  
     * association.  Does not establish connection.
 68  
     */
 69  
     public AdjustableAssociation ( Object anObject )
 70  
     {
 71  0
         super( anObject );
 72  0
     }
 73  
     
 74  
     /**
 75  
     * Returns a List of aspect signatures whose contents
 76  
     * correspond with the aspects list.  Each element is 
 77  
     * a string whose characters represent a capability of
 78  
     * the corresponding aspect. <ul>
 79  
     * <li>"A" attribute: the aspect can be bound to
 80  
     * an attribute.</li>
 81  
     * <li>"1" to-one: the aspect can be bound to a
 82  
     * property that returns a single object.</li>
 83  
     * <li>"M" to-one: the aspect can be bound to a
 84  
     * property that returns multiple objects.</li>
 85  
     * </ul> 
 86  
     * An empty signature "" means that the aspect can
 87  
     * bind without needing a key.
 88  
     * This implementation returns "A1M" for each
 89  
     * element in the aspects array.
 90  
     */
 91  
     public static NSArray aspectSignatures ()
 92  
     {
 93  0
         return aspectSignatures;
 94  
     }
 95  
     
 96  
     /**
 97  
     * Returns a List that describes the aspects supported
 98  
     * by this class.  Each element in the list is the string
 99  
     * name of the aspect.  This implementation returns an
 100  
     * empty list.
 101  
     */
 102  
     public static NSArray aspects ()
 103  
     {
 104  0
         return aspects;
 105  
     }
 106  
     
 107  
     /**
 108  
     * Returns a List of EOAssociation subclasses that,
 109  
     * for the objects that are usable for this association,
 110  
     * are less suitable than this association.
 111  
     */
 112  
     public static NSArray associationClassesSuperseded ()
 113  
     {
 114  0
         return new NSArray();
 115  
     }
 116  
     
 117  
     /**
 118  
     * Returns whether this class can control the specified 
 119  
     * object. 
 120  
     */
 121  
     public static boolean isUsableWithObject ( Object anObject )
 122  
     {
 123  0
         return ( anObject instanceof Adjustable );
 124  
     }
 125  
     
 126  
     /**
 127  
     * Returns a List of properties of the controlled object
 128  
     * that are controlled by this class.  For example,
 129  
     * "stringValue", or "selected".
 130  
     */
 131  
     public static NSArray objectKeysTaken ()
 132  
     {
 133  0
         return objectKeysTaken;
 134  
     }
 135  
     
 136  
     /**
 137  
     * Returns the aspect that is considered primary
 138  
     * or default.  This is typically "value" or somesuch.
 139  
     */
 140  
     public static String primaryAspect ()
 141  
     {
 142  0
         return ValueAspect;
 143  
     }
 144  
         
 145  
     /**
 146  
     * Returns whether this association can bind to the
 147  
     * specified display group on the specified key for
 148  
     * the specified aspect.  
 149  
     */
 150  
     public boolean canBindAspect ( 
 151  
         String anAspect, EODisplayGroup aDisplayGroup, String aKey)
 152  
     {
 153  0
         return ( aspects.containsObject( anAspect ) );
 154  
     }
 155  
     
 156  
     /**
 157  
     * Establishes a connection between this association
 158  
     * and the controlled object.  This implementation 
 159  
         * attempts to add this class as an ActionListener
 160  
         * and as a FocusListener to the specified object.
 161  
     */
 162  
     public void establishConnection ()
 163  
     {
 164  0
                 component().addAdjustmentListener( this );
 165  0
         super.establishConnection();
 166  
                 
 167  
                 // forces update from bindings
 168  0
                 subjectChanged();
 169  0
     }
 170  
         
 171  
     /**
 172  
     * Breaks the connection between this association and 
 173  
     * its object.  Override to stop listening for events
 174  
     * from the object.
 175  
     */
 176  
     public void breakConnection ()
 177  
     {
 178  0
                 component().removeAdjustmentListener( this );
 179  0
         super.breakConnection();
 180  0
     }
 181  
 
 182  
     /**
 183  
     * Called when either the selection or the contents 
 184  
     * of an associated display group have changed.
 185  
     */
 186  
     public void subjectChanged ()
 187  
     {
 188  0
                 Adjustable component = component();
 189  
                 EODisplayGroup displayGroup;
 190  
                 String key;
 191  
                 Object value;
 192  
         
 193  
                 // value aspect
 194  0
                 displayGroup = displayGroupForAspect( ValueAspect );
 195  0
                 if ( displayGroup != null )
 196  
                 {
 197  0
                         key = displayGroupKeyForAspect( ValueAspect );
 198  0
             if ( component instanceof Component )
 199  
             {
 200  0
                 ((Component)component).setEnabled( 
 201  0
                         displayGroup.enabledToSetSelectedObjectValueForKey( key ) );
 202  
             }
 203  0
                         value = displayGroup.selectedObjectValueForKey( key );
 204  
                         
 205  
                         // convert value to int
 206  0
                         value = ValueConverter.convertObjectToClass( 
 207  0
                                 value, Integer.class );
 208  
 
 209  
                         int intValue;
 210  0
                         if ( value == null ) 
 211  
                         {
 212  0
                                 intValue = 0;
 213  0
                         }
 214  
                         else
 215  
                         {
 216  0
                                 intValue = ((Integer)value).intValue();
 217  
                         }
 218  
                         
 219  0
                         if ( component.getValue() != intValue )
 220  
                         {
 221  0
                                 component.setValue( intValue );
 222  
                         }
 223  
                 }
 224  
 
 225  
                 // enabled aspect
 226  0
                 displayGroup = displayGroupForAspect( EnabledAspect );
 227  0
                 key = displayGroupKeyForAspect( EnabledAspect );
 228  0
                 if ( ( ( displayGroup != null ) || ( key != null ) )
 229  0
                 && ( component instanceof Component ) )
 230  
                 {
 231  0
                         if ( displayGroup != null )
 232  
                         {
 233  0
                                 value =
 234  0
                                         displayGroup.selectedObjectValueForKey( key );
 235  0
                         }
 236  
                         else
 237  
                         {
 238  
                                 // treat bound key without display group as a value
 239  0
                                 value = key;        
 240  
                         }
 241  0
             Boolean converted = null;
 242  0
             if ( value != null ) 
 243  
             {
 244  0
                 converted = (Boolean)
 245  0
                     ValueConverter.convertObjectToClass(
 246  0
                         value, Boolean.class );
 247  
             }
 248  0
             if ( converted == null ) converted = Boolean.FALSE;
 249  0
             if ( converted.booleanValue() != ((Component)component).isEnabled() )
 250  
             {
 251  0
                 ((Component)component).setEnabled( converted.booleanValue() );        
 252  
             }
 253  
                 }
 254  
 
 255  0
     }
 256  
         
 257  
     /**
 258  
     * Forces this association to cause the object to 
 259  
     * stop editing and validate the user's input.
 260  
     * @return false if there were problems validating,
 261  
     * or true to continue.
 262  
     */
 263  
     public boolean endEditing ()
 264  
     {
 265  0
                 return writeValueToDisplayGroup();
 266  
     }
 267  
         
 268  
         /**
 269  
         * Writes the value currently in the component
 270  
         * to the selected object in the display group
 271  
         * bound to the value aspect.
 272  
     * @return false if there were problems validating,
 273  
     * or true to continue.
 274  
         */
 275  
         protected boolean writeValueToDisplayGroup()
 276  
         {
 277  0
                 EODisplayGroup displayGroup = 
 278  0
                         displayGroupForAspect( ValueAspect );
 279  0
                 if ( displayGroup != null )
 280  
                 {
 281  0
                         String key = displayGroupKeyForAspect( ValueAspect );
 282  0
                         Object value = new Integer( component().getValue() );
 283  0
                         return displayGroup.setSelectedObjectValue( value, key );
 284  
                 }
 285  0
                 return false;
 286  
         }
 287  
 
 288  
     // interface AdjustmentListener
 289  
         
 290  
         /**
 291  
         * Updates object on action performed.
 292  
         */
 293  
         public void adjustmentValueChanged(AdjustmentEvent e) 
 294  
         {
 295  0
                 writeValueToDisplayGroup();
 296  0
         }
 297  
     
 298  
         private Adjustable component()
 299  
         {
 300  0
                 return (Adjustable) object();        
 301  
         }
 302  
 }
 303  
 
 304  
 /*
 305  
  * $Log$
 306  
  * Revision 1.2  2006/02/18 23:19:05  cgruber
 307  
  * Update imports and maven dependencies.
 308  
  *
 309  
  * Revision 1.1  2006/02/16 13:22:23  cgruber
 310  
  * Check in all sources in eclipse-friendly maven-enabled packages.
 311  
  *
 312  
  * Revision 1.3  2004/01/28 18:34:57  mpowers
 313  
  * Better handling for enabling.
 314  
  * Now respecting enabledToSetSelectedObjectValueForKey from display group.
 315  
  *
 316  
  * Revision 1.2  2003/08/06 23:07:52  chochos
 317  
  * general code cleanup (mostly, removing unused imports)
 318  
  *
 319  
  * Revision 1.1.1.1  2000/12/21 15:48:35  mpowers
 320  
  * Contributing wotonomy.
 321  
  *
 322  
  * Revision 1.2  2000/12/20 16:25:40  michael
 323  
  * Added log to all files.
 324  
  *
 325  
  *
 326  
  */
 327