/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.ui.helpers; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; /** * This class handles the lazy loading of nodes. It calls the necessary methods * on the current tree node to ask it for it's actual children. * * Note: This implementation is rather simple and targeted for the current use * in Jajuk where the expanding of the node is usually a quick (in-memory) * operation. This implementation is not fully usable for cases where it takes * some time to retrieve the data, e.g. when there are database or other remote * requests involved. */ public class LazyLoadingTreeExpander implements TreeWillExpandListener { /** Tree Model. */ private DefaultTreeModel model; /** * Default constructor. * * @param model Tree model */ public LazyLoadingTreeExpander(DefaultTreeModel model) { this.model = model; } /* (non-Javadoc) * @see javax.swing.event.TreeWillExpandListener#treeWillCollapse(javax.swing.event.TreeExpansionEvent) */ @Override public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { // Do nothing on collapse. } /** * Invoked whenever a node in the tree is about to be expanded. * * If the Node is a LazyLoadingTreeNode load it's children. * * @param event * * @throws ExpandVetoException the expand veto exception */ @Override public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { TreePath path = event.getPath(); Object lastPathComponent = path.getLastPathComponent(); if (lastPathComponent instanceof LazyLoadingTreeNode) { LazyLoadingTreeNode lazyNode = (LazyLoadingTreeNode) lastPathComponent; if (!lazyNode.areChildrenLoaded()) { MutableTreeNode[] nodes = lazyNode.loadChildren(model); ((DefaultMutableTreeNode) lazyNode).setAllowsChildren(nodes != null && nodes.length > 0); setChildren(lazyNode, nodes); } } } /** * Define nodes children. * * @param lazyNode * @param nodes new nodes */ private void setChildren(LazyLoadingTreeNode lazyNode, MutableTreeNode... nodes) { int childCount = lazyNode.getChildCount(); if (childCount > 0) { for (int i = 0; i < childCount; i++) { model.removeNodeFromParent((MutableTreeNode) lazyNode.getChildAt(0)); } } for (int i = 0; nodes != null && i < nodes.length; i++) { model.insertNodeInto(nodes[i], lazyNode, i); } } }