/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2002 Intersect Software Corporation This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org */ package net.wotonomy.ui.swing; import javax.swing.JTree; import javax.swing.table.TableColumn; import net.wotonomy.foundation.NSArray; import net.wotonomy.ui.EODisplayGroup; import net.wotonomy.ui.swing.components.TreeTableCellRenderer; /** * TreeColumnAssociation is a TableColumnAssocation * that works like a TreeAssociation, allowing any * table to display hierarchical data in a tabular format. * This class is mainly a convenience for connecting a * TreeAssociation to a JTree to a TreeTableCellRenderer * to a TableColumn.

* * Like TableColumnAssociation, you must call setTable() * to specify the JTable to be used. (The corresponding * table association will direct all column header sorting * to the root node of the tree association.) * * You may also optionally call setTree() to specify a * customized JTree to be used. If not specified, a * slightly customized JTree will be used (see createTree() * and configureColumn()). * * TreeColumnAssociation supports the following bindings, * just as TableColumnAssociation does: * * * TreeColumnAssociation additionally supports the following * bindings, just as TreeAssociation does, except that the * value binding is used instead of the titles binding. * * * @author michael@mpowers.net * @author $Author: cgruber $ * @version $Revision: 904 $ */ public class TreeColumnAssociation extends TableColumnAssociation { static final NSArray aspects = new NSArray( new Object[] { ValueAspect, EditableAspect, ChildrenAspect, IsLeafAspect } ); static final NSArray aspectSignatures = new NSArray( new Object[] { AttributeToOneAspectSignature } ); static final NSArray objectKeysTaken = new NSArray( new Object[] { "table" } ); EODisplayGroup childrenDisplayGroup, leafDisplayGroup; String childrenKey, leafKey; TreeModelAssociation treeAssociation; JTree tree; /** * Constructor specifying the object to be controlled by this * association. Throws an exception if the object is not * a TableColumn. */ public TreeColumnAssociation ( Object anObject ) { super( anObject ); } /** * Returns a List of aspect signatures whose contents * correspond with the aspects list. Each element is * a string whose characters represent a capability of * the corresponding aspect. * An empty signature "" means that the aspect can * bind without needing a key. * This implementation returns "A1M" for each * element in the aspects array. */ public static NSArray aspectSignatures () { return aspectSignatures; } /** * Returns a List that describes the aspects supported * by this class. Each element in the list is the string * name of the aspect. This implementation returns an * empty list. */ public static NSArray aspects () { return aspects; } /** * Binds the specified aspect of this association to the * specified key on the specified display group. */ public void bindAspect ( String anAspect, EODisplayGroup aDisplayGroup, String aKey ) { if ( ChildrenAspect.equals( anAspect ) ) { childrenDisplayGroup = aDisplayGroup; childrenKey = aKey; } if ( IsLeafAspect.equals( anAspect ) ) { leafDisplayGroup = aDisplayGroup; leafKey = aKey; } super.bindAspect( anAspect, aDisplayGroup, aKey ); } /** * Overridden to call createTree if necessary, * call configureColumn, call createTreeAssociation * if necessary, and then call to super. */ public void establishConnection () { if ( tree == null ) { tree = createTree(); } configureColumn( (TableColumn) object() ); if ( treeAssociation == null ) { treeAssociation = createTreeAssociation( tree ); } treeAssociation.bindAspect( TitlesAspect, valueDisplayGroup, valueKey ); if ( childrenKey != null ) { treeAssociation.bindAspect( ChildrenAspect, childrenDisplayGroup, childrenKey ); } if ( leafKey != null ) { treeAssociation.bindAspect( IsLeafAspect, leafDisplayGroup, leafKey ); } // ensure table association's source is tree asssociation's child group getTableAssociation().bindAspect( SourceAspect, treeAssociation.childrenDisplayGroup, "" ); treeAssociation.establishConnection(); table.setRowHeight( tree.getRowHeight() ); super.establishConnection(); // cause sort ordering to apply to root node of tree if ( childrenKey != null ) { getTableAssociation().sortTarget = (EODisplayGroup) treeAssociation.getRoot(); } } /** * Breaks the connection between this association and * its object. Override to stop listening for events * from the object. */ public void breakConnection () { super.breakConnection(); treeAssociation.breakConnection(); // restore original source display group getTableAssociation().sortTarget = null; } /** * Called by establishConnection if setTree was not called. * This implementation returns a stock JTree. Override * to provide your own customized JTree. Note that * TreeTableCellRenderer will further customize this tree * when configureColumn is called. */ protected JTree createTree() { return new JTree(); } /** * Called by establishConnection to create a tree association * only if no tree association has already been created. * This implementation returns a stock TreeAssociation. * Override to return your own customized TreeAssociation. */ protected TreeModelAssociation createTreeAssociation( JTree aTree ) { return new TreeAssociation( aTree ); } /** * Called by establishConnection to configure the column * with a TreeTableCellRenderer using the current JTree. * Override to further customize the column, or customize * your column yourself after the call to establishConnection. */ protected void configureColumn( TableColumn aColumn ) { aColumn.setCellRenderer( new TreeTableCellRenderer( tree ) ); } /** * Gets the JTree currently used for the column renderer. * If not specified, returns null. */ public JTree getTree() { return tree; } /** * Gets the TreeModelAssociation currently used for the tree. * If not tree is not specified, returns null. */ public TreeModelAssociation getTreeModelAssociation() { if ( tree == null ) return null; if (!( tree.getModel() instanceof TreeModelAssociation )) return null; return (TreeModelAssociation) tree.getModel(); } /** * Sets the JTree to be used for the column renderer. * If not specified, createTree() will be called to create a JTree. */ public void setTree( JTree aTree ) { tree = aTree; } } /* * $Log$ * Revision 1.2 2006/02/18 23:19:05 cgruber * Update imports and maven dependencies. * * Revision 1.1 2006/02/16 13:22:22 cgruber * Check in all sources in eclipse-friendly maven-enabled packages. * * Revision 1.9 2003/08/06 23:07:52 chochos * general code cleanup (mostly, removing unused imports) * * Revision 1.8 2002/05/03 21:31:50 mpowers * Actually works better without selectionPaintedImmediately. * * Revision 1.7 2002/04/12 21:05:58 mpowers * Now distinguishing changes in titles group even better. * * Revision 1.6 2002/03/08 23:18:48 mpowers * Added accessor for tree association. * * Revision 1.5 2002/03/07 23:04:36 mpowers * Refining TreeColumnAssociation. * * Revision 1.4 2002/03/06 13:04:16 mpowers * Implemented cascading qualifiers in tree nodes. * * Revision 1.3 2002/03/05 23:18:28 mpowers * Added documentation. * Added isSelectionPaintedImmediate and isSelectionTracking attributes * to TableAssociation. * Added getTableAssociation to TableColumnAssociation. * * Revision 1.2 2002/03/04 22:48:22 mpowers * Now working with table association to sort the root node. * * Revision 1.1 2002/03/01 23:42:09 mpowers * Implemented TreeColumnAssociation, and updated documentation. * * */