/* 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. * * */