/* // This software is subject to the terms of the Eclipse Public License v1.0 // Agreement, available at the following URL: // http://www.eclipse.org/legal/epl-v10.html. // You must accept the terms of that agreement to use this software. // // Copyright (C) 2006-2009 Pentaho // Copyright (C) 2006-2007 Cincom Systems, Inc. // Copyright (C) 2006-2007 JasperSoft // All Rights Reserved. */ package mondrian.gui; import java.util.HashSet; import java.util.Set; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; /** * Helper to enable update the tree and keep expanded nodes expanded after * reloading the tree. * * @author erik */ public class JTreeUpdater implements TreeExpansionListener, TreeSelectionListener { private JTree tree = null; private Set<TreePath> expandedTreePaths = new HashSet<TreePath>(); private TreePath[] selectedTreePaths = new TreePath[0]; /** * Constructor * * @param tree The tree to track */ public JTreeUpdater(JTree tree) { this.tree = tree; this.tree.addTreeExpansionListener(this); this.tree.addTreeSelectionListener(this); } /** * Call this method whenever you update the tree and needs it reloaded */ public synchronized void update() { synchronized (this.tree) { this.tree.removeTreeExpansionListener(this); this.tree.removeTreeSelectionListener(this); ((DefaultTreeModel) this.tree.getModel()).reload(); for (TreePath treePath : expandedTreePaths) { this.tree.expandPath(treePath); } this.tree.getSelectionModel().setSelectionPaths(selectedTreePaths); this.tree.addTreeExpansionListener(this); this.tree.addTreeSelectionListener(this); } } public void treeExpanded(TreeExpansionEvent treeExpansionEvent) { TreePath expandedPath = treeExpansionEvent.getPath(); // remove all ancestors of eventpath from expandedpaths set. Object[] paths = expandedTreePaths.toArray(); for (int i = 0; i < paths.length; i++) { TreePath path = (TreePath) paths[i]; // Path is a descendant of event path if path contains all // components that make eventpath. For example, if eventpath = [a,b] // path=[a,b,c] then path is descendant of eventpath. if (path.isDescendant(expandedPath)) { expandedTreePaths.remove(path); } } expandedTreePaths.add(expandedPath); } public void treeCollapsed(TreeExpansionEvent treeExpansionEvent) { TreePath collapsedPath = treeExpansionEvent.getPath(); expandedTreePaths.remove(collapsedPath); // remove all descendants from expandedpaths set. Object[] paths = expandedTreePaths.toArray(); for (int i = 0; i < paths.length; i++) { TreePath path = (TreePath) paths[i]; // Path is a descendant of event path if path contains all // components that make eventpath. For example, if eventpath = [a,b] // path=[a,b,c] then path is descendant of eventpath. if (collapsedPath.isDescendant(path)) { expandedTreePaths.remove(path); } } } public void valueChanged(TreeSelectionEvent treeSelectionEvent) { if (this.tree.getSelectionPaths() != null && this.tree.getSelectionPaths().length > 0) { selectedTreePaths = this.tree.getSelectionModel().getSelectionPaths(); } } } // End JTreeUpdater.java