Coverage Report - net.wotonomy.ui.swing.TreeColumnAssociation
 
Classes in this File Line Coverage Branch Coverage Complexity
TreeColumnAssociation
0% 
0% 
1.917
 
 1  
 /*
 2  
 Wotonomy: OpenStep design patterns for pure Java applications.
 3  
 Copyright (C) 2002 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 javax.swing.JTree;
 22  
 import javax.swing.table.TableColumn;
 23  
 
 24  
 import net.wotonomy.foundation.NSArray;
 25  
 import net.wotonomy.ui.EODisplayGroup;
 26  
 import net.wotonomy.ui.swing.components.TreeTableCellRenderer;
 27  
 
 28  
 /**
 29  
 * TreeColumnAssociation is a TableColumnAssocation 
 30  
 * that works like a TreeAssociation, allowing any
 31  
 * table to display hierarchical data in a tabular format.
 32  
 * This class is mainly a convenience for connecting a 
 33  
 * TreeAssociation to a JTree to a TreeTableCellRenderer 
 34  
 * to a TableColumn.<br><br>
 35  
 * 
 36  
 * Like TableColumnAssociation, you must call setTable()
 37  
 * to specify the JTable to be used.  (The corresponding
 38  
 * table association will direct all column header sorting
 39  
 * to the root node of the tree association.)
 40  
 *
 41  
 * You may also optionally call setTree() to specify a 
 42  
 * customized JTree to be used.  If not specified, a 
 43  
 * slightly customized JTree will be used (see createTree()
 44  
 * and configureColumn()).
 45  
 *  
 46  
 * TreeColumnAssociation supports the following bindings,
 47  
 * just as TableColumnAssociation does:
 48  
 * <ul>
 49  
 * <li>value: a property convertable to a string for
 50  
 * display in the cells of the table column.  This 
 51  
 * binding is equivalent to the titles binding of 
 52  
 * TreeAssociation.</li> 
 53  
 *
 54  
 * <li>editable: a property convertable to a boolean 
 55  
 * that determines the editability of the corresponding
 56  
 * cells in the column.</li> 
 57  
 * </ul>
 58  
 *
 59  
 * TreeColumnAssociation additionally supports the following
 60  
 * bindings, just as TreeAssociation does, except that the 
 61  
 * value binding is used instead of the titles binding.
 62  
 * <ul>
 63  
 * <li>children: a property of a node value that returns
 64  
 * zero, one or many objects, each of which will correspond
 65  
 * to a child node for the corresponding node in the tree.
 66  
 * If this aspect is not bound, the tree behaves like a list.</li>
 67  
 *
 68  
 * <li>isLeaf: a property of a node value that returns
 69  
 * a value convertable to a boolean value. 
 70  
 * If the isLeaf aspect is not bound, the tree will force 
 71  
 * nodes to load their children to determine whether they 
 72  
 * are leaf nodes (in effect loading the grandchildren for 
 73  
 * any expanded node).
 74  
 * </li>
 75  
 * </ul>
 76  
 *
 77  
 * @author michael@mpowers.net
 78  
 * @author $Author: cgruber $
 79  
 * @version $Revision: 904 $
 80  
 */
 81  0
 public class TreeColumnAssociation extends TableColumnAssociation
 82  
 {
 83  0
     static final NSArray aspects = 
 84  0
         new NSArray( new Object[] {
 85  0
             ValueAspect, EditableAspect, ChildrenAspect, IsLeafAspect
 86  
         } );
 87  0
     static final NSArray aspectSignatures = 
 88  0
         new NSArray( new Object[] {
 89  0
             AttributeToOneAspectSignature
 90  
         } );
 91  0
     static final NSArray objectKeysTaken = 
 92  0
         new NSArray( new Object[] {
 93  0
             "table" 
 94  
         } );
 95  
                 
 96  
         EODisplayGroup childrenDisplayGroup, leafDisplayGroup;
 97  
         String childrenKey, leafKey;
 98  
     
 99  
     TreeModelAssociation treeAssociation;
 100  
     JTree tree;
 101  
 
 102  
     /**
 103  
     * Constructor specifying the object to be controlled by this
 104  
     * association.  Throws an exception if the object is not
 105  
         * a TableColumn.  
 106  
     */
 107  
     public TreeColumnAssociation ( Object anObject )
 108  
     {
 109  0
         super( anObject );
 110  0
     }
 111  
         
 112  
     /**
 113  
     * Returns a List of aspect signatures whose contents
 114  
     * correspond with the aspects list.  Each element is 
 115  
     * a string whose characters represent a capability of
 116  
     * the corresponding aspect. <ul>
 117  
     * <li>"A" attribute: the aspect can be bound to
 118  
     * an attribute.</li>
 119  
     * <li>"1" to-one: the aspect can be bound to a
 120  
     * property that returns a single object.</li>
 121  
     * <li>"M" to-one: the aspect can be bound to a
 122  
     * property that returns multiple objects.</li>
 123  
     * </ul> 
 124  
     * An empty signature "" means that the aspect can
 125  
     * bind without needing a key.
 126  
     * This implementation returns "A1M" for each
 127  
     * element in the aspects array.
 128  
     */
 129  
     public static NSArray aspectSignatures ()
 130  
     {
 131  0
         return aspectSignatures;
 132  
     }
 133  
     
 134  
     /**
 135  
     * Returns a List that describes the aspects supported
 136  
     * by this class.  Each element in the list is the string
 137  
     * name of the aspect.  This implementation returns an
 138  
     * empty list.
 139  
     */
 140  
     public static NSArray aspects ()
 141  
     {
 142  0
         return aspects;
 143  
     }
 144  
     
 145  
     /**
 146  
     * Binds the specified aspect of this association to the
 147  
     * specified key on the specified display group.
 148  
     */
 149  
     public void bindAspect ( 
 150  
         String anAspect, EODisplayGroup aDisplayGroup, String aKey )
 151  
         {
 152  0
                 if ( ChildrenAspect.equals( anAspect ) )
 153  
                 {
 154  0
                         childrenDisplayGroup = aDisplayGroup;        
 155  0
                         childrenKey = aKey;
 156  
                 }
 157  0
                 if ( IsLeafAspect.equals( anAspect ) )
 158  
                 {
 159  0
                         leafDisplayGroup = aDisplayGroup;
 160  0
                         leafKey = aKey;
 161  
                 }
 162  0
                 super.bindAspect( anAspect, aDisplayGroup, aKey );
 163  0
         }
 164  
         
 165  
     /**
 166  
     * Overridden to call createTree if necessary,
 167  
     * call configureColumn, call createTreeAssociation
 168  
     * if necessary, and then call to super.
 169  
     */
 170  
     public void establishConnection ()
 171  
     {
 172  0
         if ( tree == null )
 173  
         {
 174  0
             tree = createTree();
 175  
         }
 176  
         
 177  0
         configureColumn( (TableColumn) object() );
 178  
         
 179  0
         if ( treeAssociation == null )
 180  
         {
 181  0
             treeAssociation = createTreeAssociation( tree );
 182  
         }
 183  
         
 184  0
         treeAssociation.bindAspect( TitlesAspect, valueDisplayGroup, valueKey );
 185  0
         if ( childrenKey != null )
 186  
         {
 187  0
             treeAssociation.bindAspect( ChildrenAspect, childrenDisplayGroup, childrenKey );
 188  
         }
 189  0
         if ( leafKey != null )
 190  
         {
 191  0
             treeAssociation.bindAspect( IsLeafAspect, leafDisplayGroup, leafKey );
 192  
         }
 193  
 
 194  
         // ensure table association's source is tree asssociation's child group
 195  0
         getTableAssociation().bindAspect( 
 196  0
                 SourceAspect, treeAssociation.childrenDisplayGroup, "" );
 197  
                 
 198  0
         treeAssociation.establishConnection();
 199  
 
 200  0
         table.setRowHeight( tree.getRowHeight() );      
 201  
         
 202  0
         super.establishConnection();
 203  
                 
 204  
         // cause sort ordering to apply to root node of tree
 205  0
         if ( childrenKey != null )
 206  
         {        
 207  0
             getTableAssociation().sortTarget = 
 208  0
                 (EODisplayGroup) treeAssociation.getRoot();
 209  
         }
 210  0
     }
 211  
     
 212  
     /**
 213  
     * Breaks the connection between this association and 
 214  
     * its object.  Override to stop listening for events
 215  
     * from the object.
 216  
     */
 217  
     public void breakConnection ()
 218  
     {
 219  0
         super.breakConnection();
 220  0
         treeAssociation.breakConnection();
 221  
         
 222  
         // restore original source display group
 223  0
         getTableAssociation().sortTarget = null;
 224  0
     }
 225  
 
 226  
     /**
 227  
     * Called by establishConnection if setTree was not called.
 228  
     * This implementation returns a stock JTree.  Override
 229  
     * to provide your own customized JTree.  Note that
 230  
     * TreeTableCellRenderer will further customize this tree
 231  
     * when configureColumn is called.
 232  
     */
 233  
     protected JTree createTree()
 234  
     {
 235  0
         return new JTree();
 236  
     }
 237  
 
 238  
     /**
 239  
     * Called by establishConnection to create a tree association
 240  
     * only if no tree association has already been created.
 241  
     * This implementation returns a stock TreeAssociation.
 242  
     * Override to return your own customized TreeAssociation.
 243  
     */    
 244  
     protected TreeModelAssociation createTreeAssociation( JTree aTree )
 245  
     {
 246  0
         return new TreeAssociation( aTree );
 247  
     }
 248  
     
 249  
     /**
 250  
     * Called by establishConnection to configure the column
 251  
     * with a TreeTableCellRenderer using the current JTree.
 252  
     * Override to further customize the column, or customize
 253  
     * your column yourself after the call to establishConnection.
 254  
     */
 255  
     protected void configureColumn( TableColumn aColumn )
 256  
     {
 257  0
         aColumn.setCellRenderer( new TreeTableCellRenderer( tree ) );
 258  0
     }
 259  
     
 260  
         /**
 261  
         * Gets the JTree currently used for the column renderer.
 262  
     * If not specified, returns null.
 263  
         */
 264  
         public JTree getTree()
 265  
         {
 266  0
         return tree;
 267  
         }
 268  
 
 269  
         /**
 270  
         * Gets the TreeModelAssociation currently used for the tree.
 271  
     * If not tree is not specified, returns null.
 272  
         */
 273  
         public TreeModelAssociation getTreeModelAssociation()
 274  
         {
 275  0
         if ( tree == null ) return null;
 276  0
         if (!( tree.getModel() instanceof TreeModelAssociation )) return null;
 277  0
         return (TreeModelAssociation) tree.getModel();
 278  
         }
 279  
 
 280  
         /**
 281  
         * Sets the JTree to be used for the column renderer.
 282  
     * If not specified, createTree() will be called to create a JTree.
 283  
         */
 284  
         public void setTree( JTree aTree )
 285  
         {
 286  0
         tree = aTree;
 287  0
         }
 288  
 
 289  
 }
 290  
 
 291  
 /*
 292  
  * $Log$
 293  
  * Revision 1.2  2006/02/18 23:19:05  cgruber
 294  
  * Update imports and maven dependencies.
 295  
  *
 296  
  * Revision 1.1  2006/02/16 13:22:22  cgruber
 297  
  * Check in all sources in eclipse-friendly maven-enabled packages.
 298  
  *
 299  
  * Revision 1.9  2003/08/06 23:07:52  chochos
 300  
  * general code cleanup (mostly, removing unused imports)
 301  
  *
 302  
  * Revision 1.8  2002/05/03 21:31:50  mpowers
 303  
  * Actually works better without selectionPaintedImmediately.
 304  
  *
 305  
  * Revision 1.7  2002/04/12 21:05:58  mpowers
 306  
  * Now distinguishing changes in titles group even better.
 307  
  *
 308  
  * Revision 1.6  2002/03/08 23:18:48  mpowers
 309  
  * Added accessor for tree association.
 310  
  *
 311  
  * Revision 1.5  2002/03/07 23:04:36  mpowers
 312  
  * Refining TreeColumnAssociation.
 313  
  *
 314  
  * Revision 1.4  2002/03/06 13:04:16  mpowers
 315  
  * Implemented cascading qualifiers in tree nodes.
 316  
  *
 317  
  * Revision 1.3  2002/03/05 23:18:28  mpowers
 318  
  * Added documentation.
 319  
  * Added isSelectionPaintedImmediate and isSelectionTracking attributes
 320  
  * to TableAssociation.
 321  
  * Added getTableAssociation to TableColumnAssociation.
 322  
  *
 323  
  * Revision 1.2  2002/03/04 22:48:22  mpowers
 324  
  * Now working with table association to sort the root node.
 325  
  *
 326  
  * Revision 1.1  2002/03/01 23:42:09  mpowers
 327  
  * Implemented TreeColumnAssociation, and updated documentation.
 328  
  *
 329  
  *
 330  
  */
 331