source: trunk/gli/src/org/greenstone/gatherer/util/TreeSynchronizer.java@ 4364

Last change on this file since 4364 was 4364, checked in by mdewsnip, 21 years ago

Fixed tabbing.

  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1package org.greenstone.gatherer.util;
2/**
3 *#########################################################################
4 *
5 * A component of the Gatherer application, part of the Greenstone digital
6 * library suite from the New Zealand Digital Library Project at the
7 * University of Waikato, New Zealand.
8 *
9 * Author: John Thompson, Greenstone Digital Library, University of Waikato
10 *
11 * Copyright (C) 1999 New Zealand Digital Library Project
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *########################################################################
27 */
28import java.util.Vector;
29import javax.swing.JTree;
30import javax.swing.event.TreeExpansionEvent;
31import javax.swing.event.TreeExpansionListener;
32import javax.swing.event.TreeSelectionEvent;
33import javax.swing.event.TreeSelectionListener;
34import javax.swing.tree.TreeModel;
35import javax.swing.tree.TreePath;
36import org.greenstone.gatherer.gui.tree.DragTree;
37/** My latest diabolical class synchronizes the expansion state of two or more JTrees. Muh-hahahaha. Note that these tree should be based on the same model.
38 * @author John Thompson, Greenstone Digital Library, University of Waikato
39 * @version 2.1
40 */
41final public class TreeSynchronizer
42 extends Vector
43 implements TreeExpansionListener, TreeSelectionListener {
44 /** <i>true</i> if we should temporarily ignore further events, most likely because we know our actions are causing them. */
45 private boolean ignore;
46 /** A list of tree selection listeners. */
47 private Vector selection_listeners = new Vector();
48 /** Add a new tree to the synchronization list of trees to be synchronized.
49 * @param tree The lastest victim, a <strong>JTree</strong>.
50 */
51 public void add(JTree tree) {
52 super.add(tree);
53 tree.addTreeExpansionListener(this);
54 //tree.addTreeSelectionListener(this);
55 }
56
57 /** We allow the Gatherer to add tree listeners to this class, as it persists between collection changes transparently. Thus there is no need to reattach listeners everytime the collection changes. */
58 public void addTreeSelectionListener(TreeSelectionListener listener) {
59 if(!selection_listeners.contains(listener)) {
60 selection_listeners.add(listener);
61 }
62 }
63
64 /** Called whenever an item in the tree has been collapsed.
65 * @param event A <strong>TreeExpansionEvent</strong> containing information about the event.
66 */
67 public void treeCollapsed(TreeExpansionEvent event) {
68 if(!ignore) {
69 ignore = true;
70 // Collapse that path in all registered trees.
71 JTree tree = (JTree)event.getSource();
72 TreePath path = event.getPath();
73 for(int i = size(); i != 0; i--) {
74 JTree sibling = (JTree) get(i - 1);
75 if(!sibling.equals(tree)) {
76 sibling.collapsePath(path);
77 }
78 }
79 ignore = false;
80 }
81 }
82 /** Called whenever an item in the tree has been expanded.
83 * @param event A <strong>TreeExpansionEvent</strong> containing information about the event.
84 */
85 public void treeExpanded(TreeExpansionEvent event) {
86 if(!ignore) {
87 ignore = true;
88 // Expand that path in all registered trees.
89 JTree tree = (JTree)event.getSource();
90 TreePath path = event.getPath();
91 for(int i = size(); i != 0; i--) {
92 JTree sibling = (JTree) get(i - 1);
93 if(!sibling.equals(tree)) {
94 sibling.expandPath(path);
95 }
96 }
97 ignore = false;
98 }
99 }
100 /** Called whenever the one of the trees selection changes.
101 * @param event A <strong>TreeSelectionEvent</strong> containing information about the event.
102 */
103 public void valueChanged(TreeSelectionEvent event) {
104 if(!ignore) {
105 ignore = true;
106 // Recover the tree that is the source.
107 JTree tree = (JTree) event.getSource();
108 // Brute Force approach.
109 // Extract the currently selected paths.
110 TreePath paths[] = tree.getSelectionPaths();
111 // Then for every registered tree, that isn't this one, ensure those paths are selected.
112 for(int i = size(); paths != null && i != 0; i--) {
113 JTree sibling = (JTree) get(i - 1);
114 if(!sibling.equals(tree)) {
115 // One last thing to do. If this is actually a DragTree we are dealing with we have to tell it to set the selection values immediately, not wait for the clear until it is sure it is no the pre-cursor to a drag.
116 if(sibling instanceof DragTree) {
117 DragTree gtree = (DragTree)sibling;
118 gtree.setImmediate(true);
119 gtree.setSelectionPaths(paths);
120 // I'm going to ensure that the last selected path is visible.
121 gtree.scrollPathToVisible(paths[paths.length - 1]);
122 gtree.setImmediate(false);
123 }
124 else {
125 sibling.setSelectionPaths(paths);
126 sibling.scrollPathToVisible(paths[paths.length - 1]);
127 }
128 }
129 }
130 // Pass on message to all listeners.
131 for(int i = 0; i < selection_listeners.size(); i++) {
132 ((TreeSelectionListener) selection_listeners.get(i)).valueChanged(event);
133 }
134 ignore = false;
135 }
136 }
137}
Note: See TracBrowser for help on using the repository browser.