Skip to content

Commit 6867500

Browse files
committed
FileSystemTree: add additional filtering system for file names,
that uses a FileFilter and is set via setFileFilter. Can be null. Applies to plain files only, doesn't apply to directories.
1 parent 864d7e3 commit 6867500

File tree

1 file changed

+56
-8
lines changed

1 file changed

+56
-8
lines changed

src/main/java/org/scijava/ui/swing/script/FileSystemTree.java

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ public boolean isDirectory() {
103103
return new File(this.path).isDirectory();
104104
}
105105

106-
public File[] updatedChildrenFiles(final boolean sort) {
106+
/**
107+
*
108+
* @param sort
109+
* @param file_filter Applies to leafs, not to directories.
110+
* @return
111+
*/
112+
public File[] updatedChildrenFiles(final boolean sort, final FileFilter file_filter) {
107113
final File file = new File(this.path);
108114
if (!file.isDirectory()) {
109115
return new File[0];
@@ -112,7 +118,8 @@ public File[] updatedChildrenFiles(final boolean sort) {
112118
@Override
113119
public boolean accept(final File f) {
114120
return !f.isHidden() && !f.getName().endsWith("~")
115-
&& !re_ignored_extensions.matcher(f.getName()).matches();
121+
&& !re_ignored_extensions.matcher(f.getName()).matches()
122+
&& (f.isDirectory() || file_filter.accept(f));
116123
}
117124
});
118125
if (sort) Arrays.sort(files);
@@ -122,11 +129,11 @@ public boolean accept(final File f) {
122129
/**
123130
* If it's a directory, add a Node for each of its visible files.
124131
*/
125-
public synchronized void populateChildren(final DefaultTreeModel model) {
132+
public synchronized void populateChildren(final DefaultTreeModel model, final FileFilter file_filter) {
126133
try {
127134
if (isLeaf()) return;
128135
int index = 0;
129-
for (final File file : updatedChildrenFiles(true)) {
136+
for (final File file : updatedChildrenFiles(true, file_filter)) {
130137
// Can't use add: would try to insert at getChildCount(), which is the wrong value here
131138
model.insertNodeInto(new Node(file.getAbsolutePath()), this, index++);
132139
}
@@ -207,9 +214,9 @@ public synchronized void removeAllChildren(final DefaultTreeModel model) {
207214
}
208215
}
209216

210-
public synchronized void updateChildrenList(final DefaultTreeModel model) {
217+
public synchronized void updateChildrenList(final DefaultTreeModel model, final FileFilter file_filter) {
211218
removeAllChildren(model);
212-
populateChildren(model);
219+
populateChildren(model, file_filter);
213220
}
214221
}
215222

@@ -225,6 +232,7 @@ public interface LeafListener {
225232

226233
private final HashSet<String> ignored_extensions = new HashSet<>();
227234
private Pattern re_ignored_extensions = Pattern.compile("^.*$", Pattern.CASE_INSENSITIVE); // match all
235+
private FileFilter file_filter = ((f) -> true);
228236

229237
public FileSystemTree(final Logger log)
230238
{
@@ -238,7 +246,7 @@ public FileSystemTree(final Logger log)
238246
@Override
239247
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
240248
final Node node = ((Node)event.getPath().getLastPathComponent());
241-
node.populateChildren(getModel());
249+
node.populateChildren(getModel(), file_filter);
242250
dir_watcher.register(node);
243251
}
244252

@@ -329,6 +337,46 @@ private void updateIgnoreExtensionPattern() {
329337
this.re_ignored_extensions = Pattern.compile(s.toString(), Pattern.CASE_INSENSITIVE);
330338
}
331339
}
340+
341+
public void setFileFilter(final FileFilter file_filter) {
342+
this.file_filter = file_filter;
343+
updateRecursively(file_filter);
344+
}
345+
346+
private void updateRecursively(final FileFilter file_filter) {
347+
// Find expanded directories
348+
final ArrayList<Node> stack = new ArrayList<>();
349+
final Node root = (Node) this.getModel().getRoot();
350+
for (int i=root.getChildCount() -1; i>-1; --i) {
351+
stack.add((Node)root.getChildAt(i));
352+
}
353+
final ArrayList<Node> stack2 = new ArrayList<>(stack); // copy for second phase
354+
final HashSet<String> expanded = new HashSet<>();
355+
while (!stack.isEmpty()) {
356+
final Node node = stack.remove(0);
357+
if (this.isExpanded(new TreePath(node.getPath()))) {
358+
expanded.add(node.path);
359+
for (int i=node.getChildCount() -1; i>-1; --i) {
360+
final Node child = node.getChildAt(i);
361+
if (child.isDirectory()) stack.add(child);
362+
}
363+
}
364+
}
365+
// Re-list all files, filtering
366+
while (!stack2.isEmpty()) {
367+
final Node node = stack2.remove(0);
368+
if (expanded.contains(node.path)) {
369+
node.removeAllChildren(this.getModel());
370+
node.populateChildren(this.getModel(), file_filter);
371+
final int count = node.getChildCount();
372+
if (count > 0) expandPath(new TreePath(node.getChildAt(0).getPath())); // awkward way to ensure parent is expanded
373+
for (int i=0; i<count; ++i) {
374+
final Node child = node.getChildAt(i);
375+
if (expanded.contains(child.path)) stack2.add(child);
376+
}
377+
}
378+
}
379+
}
332380

333381
synchronized public void addLeafListener(final LeafListener l) {
334382
this.leaf_listeners.add(l);
@@ -508,7 +556,7 @@ public void run() {
508556

509557
SwingUtilities.invokeLater(() -> {
510558
for (final Node node : nodes) {
511-
node.updateChildrenList(FileSystemTree.this.getModel());
559+
node.updateChildrenList(FileSystemTree.this.getModel(), file_filter);
512560
FileSystemTree.this.expandPath(new TreePath(node.getPath()));
513561
}
514562
});

0 commit comments

Comments
 (0)