source: trunk/gli/src/org/greenstone/gatherer/file/FileSystemModel.java@ 10682

Last change on this file since 10682 was 10682, checked in by chi, 19 years ago

Problems solving of long-delay to drag a tree structure in Gather Pane. This happens when GLI compile with Java 1.5. If the size of tree directory dragged is large, it will take ages to copy the files over.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1package org.greenstone.gatherer.file;
2
3import java.io.File;
4import java.util.*;
5import java.util.regex.*;
6import javax.swing.event.*;
7import javax.swing.tree.*;
8import org.greenstone.gatherer.DebugStream;
9import org.greenstone.gatherer.Gatherer;
10import org.greenstone.gatherer.gui.tree.DragTree;
11import org.greenstone.gatherer.util.SynchronizedTreeModelTools;
12
13public class FileSystemModel
14 extends DefaultTreeModel
15 implements TreeExpansionListener, TreeWillExpandListener
16{
17 private DragTree tree = null;
18 private FileFilter current_filter = null;
19 private FileFilter[] filters = null;
20 /** The filters in place for any file system model. */
21 private FileFilter[] default_filters = { new FileFilter("\\..*", true), new FileFilter("metadata\\.xml", true) };
22
23 public FileSystemModel(FileNode root) {
24 super(root);
25 root.setModel(this);
26 root.map();
27 }
28
29 public int getChildCount(Object parent) {
30 return ((TreeNode)parent).getChildCount();
31 }
32
33 public FileFilter[] getFilters() {
34 if(filters == null) {
35 if(current_filter != null) {
36 filters = new FileFilter[default_filters.length + 1];
37 filters[default_filters.length] = current_filter;
38 }
39 else {
40 filters = new FileFilter[default_filters.length];
41 }
42 System.arraycopy(default_filters, 0, filters, 0, default_filters.length);
43 }
44 return filters;
45 }
46
47 /** Retrieve the node denoted by the given tree path. Note that this isn't equivelent to saying path.lastPathComponent, as the references within the path may be stale. */
48 public FileNode getNode(TreePath path) {
49 FileNode last = (FileNode)path.getLastPathComponent();
50 DebugStream.println("Last Path Component = " + last);
51 return last;
52 /*
53 ///atherer.println("**** getNode(" + path + ") ****");
54 FileNode current = (FileNode)root;
55 // Special case for the root node. Check the first path component is the root node.
56 FileNode first_node = (FileNode)path.getPathComponent(0);
57 if(current.equals(first_node)) {
58 DebugStream.println("First path component matches root node.");
59 // For each path with this tree path
60 for(int i = 1; current != null && i < path.getPathCount(); i++) {
61 // Retrieve the stale path
62 Object stale_object = path.getPathComponent(i);
63 FileNode stale_node = null;
64 if(stale_object instanceof FileNode) {
65 stale_node = (FileNode) stale_object;
66 }
67 DebugStream.print("Searching for '" + stale_object + "': ");
68 // Locate the fresh node by searching current's children. Remember to ensure that current is mapped.
69 boolean found = false;
70
71 // First we search through the mapped children
72 for(int j = 0; !found && j < current.getChildCount(); j++) {
73 FileNode child_node = (FileNode) current.getChildAt(j);
74 DebugStream.print(child_node + " ");
75 if((stale_node != null && stale_node.equals(child_node)) || stale_object.toString().equals(child_node.toString())) {
76 found = true;
77 current = child_node;
78 DebugStream.println("Found!");
79 }
80 child_node = null;
81 }
82 // Failing that we search through all the children, including filtered files
83 for(int j = 0; !found && j < current.size(); j++) {
84 FileNode child_node = (FileNode) current.getChildAtUnfiltered(j);
85 DebugStream.print(child_node + " ");
86 if((stale_node != null && stale_node.equals(child_node)) || stale_object.toString().equals(child_node.toString())) {
87 found = true;
88 current = child_node;
89 DebugStream.println("Found!");
90 }
91 child_node = null;
92 }
93 // If no match is found, then set current to null and exit.
94 if(!found) {
95 current = null;
96 DebugStream.println("Not Found!");
97 }
98 else {
99 DebugStream.println("Returning node: " + new TreePath(current.getPath()));
100 }
101 // Repeat as necessary
102 }
103 }
104 return current;
105 */
106 }
107
108 public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index) {
109 ///ystem.err.println("insertNodeInto(" + newChild + ", " + parent + ", " + index + ")");
110 super.insertNodeInto(newChild, parent, index);
111 }
112
113
114 public void refresh(TreePath path)
115 {
116 // Can only refresh if the model is currently being displayed in a tree
117 if (tree == null) {
118 return;
119 }
120
121 // If no path is set, take the path to the root node (ie. update the whole tree)
122 if (path == null) {
123 // System.err.println("\nFileSystemModel.refresh(entire tree).");
124 path = new TreePath(((FileNode) root).getPath());
125
126 // Make sure the root node is expanded
127 tree.expandPath(path);
128 }
129 // else {
130 // System.err.println("\nFileSystemModel.refresh(" + path + ").");
131 // }
132
133 // Record all the expanded paths under this node
134 Enumeration old_expanded_paths_enumeration = tree.getExpandedDescendants(path);
135 if (old_expanded_paths_enumeration == null) {
136 return;
137 }
138
139 // Map and unmap the node to refresh its contents
140 FileNode node = (FileNode) path.getLastPathComponent();
141 node.refresh();
142
143 // Fire the appropriate event
144 nodeStructureChanged(node);
145
146 // Sort the old expanded paths by length, smallest first
147 ArrayList old_expanded_paths_list = Collections.list(old_expanded_paths_enumeration);
148 Collections.sort(old_expanded_paths_list, new TreePathComparator());
149
150 // Restore each of the expanded paths
151 for (int i = 0; i < old_expanded_paths_list.size(); i++) {
152 TreePath old_expanded_path = (TreePath) old_expanded_paths_list.get(i);
153 // System.err.println("Expanded path: " + old_expanded_path);
154
155 // Build up the new path in the tree
156 TreePath current_path = new TreePath(path.getPath());
157 FileNode current_node = node;
158
159 // Traverse the tree to find the node to expand (or find it no longer exists)
160 while (!current_path.toString().equals(old_expanded_path.toString())) {
161 // System.err.println("Current path: " + current_path);
162
163 FileNode old_expanded_node =
164 (FileNode) old_expanded_path.getPathComponent(current_path.getPathCount());
165 // System.err.println("Looking for: " + old_expanded_node);
166
167 // Find the child node that matches the next element in the path
168 boolean found = false;
169 for (int j = 0; j < current_node.getChildCount(); j++) {
170 FileNode child_node = (FileNode) current_node.getChildAt(j);
171 // System.err.println("Child node: " + child_node);
172 if (child_node.equals(old_expanded_node)) {
173 // System.err.println("Found!");
174 current_path = current_path.pathByAddingChild(child_node);
175 current_node = child_node;
176 found = true;
177 break;
178 }
179 }
180
181 // The node was not found, so we cannot expand this path
182 if (!found) {
183 // System.err.println("Not found...");
184 break;
185 }
186 }
187
188 // If we have built up the correct path, expand it
189 if (current_path.toString().equals(old_expanded_path.toString())) {
190 tree.expandPath(current_path);
191 }
192 }
193 }
194
195
196 private class TreePathComparator
197 implements Comparator {
198
199 public int compare(Object o1, Object o2)
200 {
201 return (((TreePath) o1).getPathCount() - ((TreePath) o2).getPathCount());
202 }
203 }
204
205
206 public void setFilter(String pattern) {
207 if(pattern != null) {
208 current_filter = new FileFilter(pattern, false);
209 }
210 else {
211 current_filter = null;
212 }
213 filters = null;
214 }
215
216 public void setTree(DragTree tree) {
217 this.tree = tree;
218 }
219
220 public String toString() {
221 if(tree != null) {
222 return tree.toString();
223 }
224 return "FileSystemModel";
225 }
226
227 /** Called whenever an item in the tree has been collapsed. */
228 public void treeCollapsed(TreeExpansionEvent event) {
229 // Deallocate the affected nodes children. Don't need to do this in a swing worker, as the nodes children are currently not visable.
230 TreePath path = event.getPath();
231 FileNode node = (FileNode) path.getLastPathComponent();
232 node.unmap();
233 // Fire the appropriate event.
234 nodeStructureChanged(node);
235 }
236
237 /** Called whenever an item in the tree has been expanded. */
238 public void treeExpanded(TreeExpansionEvent event) {
239 }
240
241 /** Invoked whenever a node in the tree is about to be collapsed. */
242 public void treeWillCollapse(TreeExpansionEvent event)
243 throws ExpandVetoException {
244 // Veto the event if the user is attempting to collapse the root node (regardless of whether it is visible).
245 TreePath path = event.getPath();
246 if(path.getPathCount() == 1) {
247 throw new ExpandVetoException(event, "Cannot collapse root node!");
248 }
249 }
250
251 /** Invoked whenever a node in the tree is about to be expanded. */
252 public void treeWillExpand(TreeExpansionEvent event)
253 throws ExpandVetoException {
254 // Set the wait cursor.
255 Gatherer.g_man.wait(true);
256 // Allocate the children. Don't need to do this in a swing worker, as the nodes children are currently not visable.
257 TreePath path = event.getPath();
258 FileNode node = (FileNode) path.getLastPathComponent();
259 ///ystem.err.println("Mapping: " + node);
260 node.map();
261 ///ystem.err.println(" -> node has " + node.getChildCount() + " children");
262 nodeStructureChanged(node);
263 // Restore the cursor.
264 Gatherer.g_man.wait(false);
265 }
266}
Note: See TracBrowser for help on using the repository browser.