/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2001 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 java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import javax.swing.JTree; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import net.wotonomy.foundation.internal.WotonomyException; import net.wotonomy.ui.EODisplayGroup; /** * A DisplayGroupNode that exposes the MutableTreeNode interface. * This was required so that other subclasses of DisplayGroupNode * could opt out of supporting MutableTreeNode (so that they can * implement IlvActivity, for example). * * @author michael@mpowers.net * @author $Author: cgruber $ * @version $Revision: 904 $ */ public class MutableDisplayGroupNode extends DisplayGroupNode implements MutableTreeNode { /** * Constructor for all nodes. * Root node must have a null delegate. */ public MutableDisplayGroupNode( TreeModelAssociation aParentAssociation, EODisplayGroup aParentGroup, Object anObject ) { super( aParentAssociation, aParentGroup, anObject ); } public int getIndex(TreeNode node) { return getIndex( (DisplayGroupNode) node ); } public TreeNode getChildAt(int childIndex) { return (TreeNode) getChildNodeAt( childIndex ); } public TreeNode getParent() { Object parent = getParentGroup(); if ( parent instanceof TreeNode ) { return (TreeNode) parent; } return null; } public void insert(MutableTreeNode aChild, int anIndex) { if ( aChild instanceof DisplayGroupNode ) { insertObjectAtIndex( ((DisplayGroupNode)aChild).object(), anIndex ); } else // not a display group node { throw new WotonomyException( "Cannot insert nodes of type: " + aChild ); } } /** * Removes the node at the index corresponding * to the index of the object. */ public void remove(MutableTreeNode node) { if ( node instanceof DisplayGroupNode ) { remove((DisplayGroupNode)node); } else // not a display group node { throw new WotonomyException( "Cannot insert nodes of type: " + node ); } } /** * Removes the value in the parent display group * at the index that corresponds to the index of this node * and add it to the end of the display group that corresponds * to the user value of the specified node. */ public void setParent(MutableTreeNode newParent) { if ( newParent instanceof DisplayGroupNode ) { setParent((DisplayGroupNode)newParent); } else // not a display group node { throw new WotonomyException( "Cannot set parent to nodes of type: " + newParent ); } } /** * Overridden to remember expanded state for nodes * after nodes have been rearranged. */ protected void fireEventsForChanges( Object[] oldObjects, Object[] newObjects ) { if ( !( parentAssociation.object() instanceof JTree ) ) { super.fireEventsForChanges( oldObjects, newObjects ); return; } JTree tree = (JTree) parentAssociation.object(); Map expansionMap = new HashMap(); DisplayGroupNode node; TreePath path; for ( int i = 0; i < oldObjects.length; i++ ) { node = (DisplayGroupNode) getChildNodeForObject( oldObjects[i] ); if ( node != null && ! node.isLeaf() ) { expansionMap.put( node, new Boolean( tree.isExpanded( node.treePath() ) ) ); } } super.fireEventsForChanges( oldObjects, newObjects ); Object value; Iterator iterator = new LinkedList( childNodes.values() ).iterator(); while ( iterator.hasNext() ) { node = (DisplayGroupNode) iterator.next(); value = expansionMap.get( node ); if ( value != null ) { if ( Boolean.TRUE.equals( value ) ) { tree.expandPath( node.treePath() ); } else { tree.collapsePath( node.treePath() ); } } } } } /* * $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.8 2003/08/06 23:07:52 chochos * general code cleanup (mostly, removing unused imports) * * Revision 1.7 2002/04/23 19:12:28 mpowers * Reimplemented fireEventsForChanges. Fitter and happier. * * Revision 1.6 2002/04/10 21:20:04 mpowers * Better handling for tree nodes when working with editing contexts. * Better handling for invalidation. No longer broadcasting events * when nodes have not been "registered" in the tree. * * Revision 1.5 2002/04/03 20:01:47 mpowers * Now remembers expanded state. * * Revision 1.4 2002/03/08 23:19:07 mpowers * Added getParentGroup to DisplayGroupNode. * * Revision 1.3 2002/02/27 23:19:17 mpowers * Refactoring of TreeAssociation to create TreeModelAssociation parent. * * Revision 1.2 2001/04/22 23:05:33 mpowers * Totally revised DisplayGroupNode so each object gets its own node * (so the nodes are no longer fixed by index). * * Revision 1.1 2001/04/21 23:05:56 mpowers * Contributing the tree-specific concrete subclass of DisplayGroupNode. * * */