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