From 3ca666d8786a537cf68510d75bff7a344743156a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 16 Jun 2021 13:17:06 -0400 Subject: [PATCH 1/2] pre-expand nodes no longer on tree listener and optimally loads root level nodes before expansion --- .../sleuthkit/autopsy/datamodel/HostNode.java | 2 +- .../DirectoryTreeTopComponent.java | 61 ++++++------------- 2 files changed, 19 insertions(+), 44 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java index b05bca24a1..b060c63c08 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/HostNode.java @@ -226,7 +226,7 @@ public class HostNode extends DisplayableItemNode { * @param hostGrouping The HostGrouping key. */ HostNode(HostGrouping hostGrouping) { - this(Children.create(new HostGroupingChildren(HOST_GROUPING_CONVERTER, hostGrouping.getHost()), false), hostGrouping.getHost()); + this(Children.create(new HostGroupingChildren(HOST_GROUPING_CONVERTER, hostGrouping.getHost()), true), hostGrouping.getHost()); } /** diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 26e4518cea..2736c6f6cb 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.prefs.PreferenceChangeEvent; @@ -134,31 +135,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat // only allow one item to be selected at a time getTree().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); - //Hook into the JTree and pre-expand the Views Node and Results node when a user - //expands an item in the tree that makes these nodes visible. - ((ExpansionBeanTreeView) getTree()).addTreeExpansionListener(new TreeExpansionListener() { - @Override - public void treeExpanded(TreeExpansionEvent event) { - //Bail immediately if we are not in the Group By view. - //Assumption here is that the views are already expanded. - if (!CasePreferences.getGroupItemsInTreeByDataSource()) { - return; - } - Node expandedNode = Visualizer.findNode(event.getPath().getLastPathComponent()); - for (Node child : em.getRootContext().getChildren().getNodes()) { - if (child.equals(expandedNode)) { - preExpandNodes(child.getChildren()); - } - } - } - - @Override - public void treeCollapsed(TreeExpansionEvent event) { - //Do nothing - } - - }); // remove the close button putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); setName(NbBundle.getMessage(DirectoryTreeTopComponent.class, "CTL_DirectoryTreeTopComponent")); @@ -201,30 +178,28 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat */ private void preExpandNodes(Children rootChildren) { BeanTreeView tree = getTree(); - for (String categoryKey : new String[]{AnalysisResults.getName(), DataArtifacts.getName()}) { - Node categoryNode = rootChildren.findChild(categoryKey); - if (!Objects.isNull(categoryNode)) { - tree.expandNode(categoryNode); - Children resultsChildren = categoryNode.getChildren(); - Arrays.stream(resultsChildren.getNodes()).forEach(tree::expandNode); - } - } - - Node views = rootChildren.findChild(ViewsNode.NAME); - if (!Objects.isNull(views)) { - tree.expandNode(views); + // using getNodes(true) to fetch children so that async nodes are loaded + Node[] rootChildrenNodes = rootChildren.getNodes(true); + if (rootChildrenNodes == null || rootChildrenNodes.length < 1) { + return; } // expand all nodes parents of and including hosts if group by host/person if (Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true)) { - Node[] rootNodes = rootChildren.getNodes(); - if (rootNodes != null) { - Stream.of(rootNodes) - .flatMap((n) -> getHostNodesAndParents(n).stream()) - .filter((n) -> n != null) - .forEach((n) -> tree.expandNode(n)); - } + Stream.of(rootChildrenNodes) + .flatMap((n) -> getHostNodesAndParents(n).stream()) + .filter((n) -> n != null) + .forEach(tree::expandNode); + } else { + // nodes to be opened if present at top level + Set resultArtifactNames + = Stream.of(AnalysisResults.getName(), DataArtifacts.getName(), ViewsNode.NAME) + .collect(Collectors.toSet()); + + Stream.of(rootChildrenNodes) + .filter(n -> n != null && resultArtifactNames.contains(n.getName())) + .forEach(tree::expandNode); } } From 13365f966297bce3f6f51091df451e4140d36bfa Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 18 Jun 2021 13:38:35 -0400 Subject: [PATCH 2/2] static field --- .../directorytree/DirectoryTreeTopComponent.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 2736c6f6cb..e4904a5cb8 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -45,14 +45,11 @@ import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; -import javax.swing.event.TreeExpansionEvent; -import javax.swing.event.TreeExpansionListener; import javax.swing.tree.TreeSelectionModel; import org.apache.commons.lang3.StringUtils; import org.openide.explorer.ExplorerManager; import org.openide.explorer.ExplorerUtils; import org.openide.explorer.view.BeanTreeView; -import org.openide.explorer.view.Visualizer; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; @@ -127,6 +124,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat private static final String GROUPING_THRESHOLD_NAME = "GroupDataSourceThreshold"; private static final String SETTINGS_FILE = "CasePreferences.properties"; //NON-NLS + // nodes to be opened if present at top level + private static final Set NODES_TO_EXPAND = Stream.of(AnalysisResults.getName(), DataArtifacts.getName(), ViewsNode.NAME) + .collect(Collectors.toSet()); + /** * the constructor */ @@ -192,13 +193,8 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat .filter((n) -> n != null) .forEach(tree::expandNode); } else { - // nodes to be opened if present at top level - Set resultArtifactNames - = Stream.of(AnalysisResults.getName(), DataArtifacts.getName(), ViewsNode.NAME) - .collect(Collectors.toSet()); - Stream.of(rootChildrenNodes) - .filter(n -> n != null && resultArtifactNames.contains(n.getName())) + .filter(n -> n != null && NODES_TO_EXPAND.contains(n.getName())) .forEach(tree::expandNode); } }