From 883e48b0430ac947aa3941b552068a2c46bdfdfb Mon Sep 17 00:00:00 2001 From: jmillman Date: Tue, 24 Nov 2015 12:49:02 -0500 Subject: [PATCH] details view node / tree clean up and bugfixes reinstate wrongly removed layout constraints; bind subnodepane children to subnodes list; keep tree and main visualization in sync better --- .../timeline/datamodel/EventStripe.java | 2 - .../ui/detailview/EventBundleNodeBase.java | 16 ++++-- .../ui/detailview/EventClusterNode.java | 50 ++++++++++++++----- .../ui/detailview/EventDetailsChart.java | 2 +- .../ui/detailview/EventStripeNode.java | 11 ++-- .../ui/detailview/tree/EventTypeTreeItem.java | 5 +- 6 files changed, 61 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/EventStripe.java b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/EventStripe.java index f46cbd82da..7424727fcf 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/datamodel/EventStripe.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/datamodel/EventStripe.java @@ -180,6 +180,4 @@ public final class EventStripe implements EventBundle { public String toString() { return "EventStripe{" + "description=" + description + ", eventIDs=" + eventIDs.size() + '}'; } - - } diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventBundleNodeBase.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventBundleNodeBase.java index 730c97bf6b..87dc2f56ae 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventBundleNodeBase.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventBundleNodeBase.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.timeline.ui.detailview; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -32,7 +31,10 @@ import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.application.Platform; +import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleObjectProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.concurrent.Task; import javafx.event.EventHandler; import javafx.geometry.Insets; @@ -120,7 +122,7 @@ public abstract class EventBundleNodeBase subNodes = new ArrayList<>(); + final ObservableList subNodes = FXCollections.observableArrayList(); final Pane subNodePane = new Pane(); final Label descrLabel = new Label(); final Label countLabel = new Label(); @@ -152,7 +154,11 @@ public abstract class EventBundleNodeBase setDescriptionVisibiltiyImpl(descVisibility.get())); descVisibility.set(DescriptionVisibility.SHOWN); //trigger listener for initial value + + Bindings.bindContent(subNodePane.getChildren(), subNodes); } final DescriptionLoD getDescriptionLoD() { @@ -342,6 +350,8 @@ public abstract class EventBundleNodeBase { private static final Logger LOGGER = Logger.getLogger(EventClusterNode.class.getName()); + /** + * Use this recursive function to flatten a tree of nodes into an single + * stream. More specifically it takes an EventStripeNode and produces a + * stream of EventStripes conaiting the stripes for the given node and all + * child eventStripes, ignoring intervening EventCluster nodes. + * + * @see + * #loadSubBundles(org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD.RelativeDetail) + * for usage + */ + private final static Function> stripeFlattener = new Function>() { + @Override + public Stream apply(EventStripeNode node) { + return Stream.concat( + Stream.of(node.getEventStripe()), + node.getSubNodes().stream().flatMap(clusterNode -> clusterNode.getSubNodes().stream().flatMap(this))); + } + }; + private static final BorderWidths CLUSTER_BORDER_WIDTHS = new BorderWidths(2, 1, 2, 1); private static final Image PLUS = new Image("/org/sleuthkit/autopsy/timeline/images/plus-button.png"); // NON-NLS //NOI18N private static final Image MINUS = new Image("/org/sleuthkit/autopsy/timeline/images/minus-button.png"); // NON-NLS //NOI18N @@ -89,6 +113,7 @@ final public class EventClusterNode extends EventBundleNodeBase> loggedTask = new Task>() { + Task> loggedTask = new LoggedTask>(Bundle.EventStripeNode_loggedTask_name(), false) { private volatile DescriptionLoD loadedDescriptionLoD = getDescriptionLoD().withRelativeDetail(relativeDetail); - { - updateTitle(Bundle.EventStripeNode_loggedTask_name()); - } - @Override protected List call() throws Exception { List bundles; @@ -182,7 +203,9 @@ final public class EventClusterNode extends EventBundleNodeBase eventStripe.withParent(getEventCluster())); + return bundles.stream() + .map(eventStripe -> eventStripe.withParent(getEventCluster())) + .collect(Collectors.toList()); } @Override @@ -190,14 +213,16 @@ final public class EventClusterNode extends EventBundleNodeBase bundles = get(); + //clear the existing subnodes + List transform = subNodes.stream().flatMap(stripeFlattener).collect(Collectors.toList()); + chart.getEventStripes().removeAll(transform); + subNodes.clear(); if (bundles.isEmpty()) { - subNodePane.getChildren().clear(); getChildren().setAll(subNodePane, infoHBox); descLOD.set(getEventBundle().getDescriptionLoD()); } else { chart.getEventStripes().addAll(bundles); - subNodes.addAll(Lists.transform(bundles, EventClusterNode.this::createStripeNode)); - subNodePane.getChildren().setAll(subNodes); + subNodes.addAll(Lists.transform(bundles, EventClusterNode.this::createChildNode)); getChildren().setAll(new VBox(infoHBox, subNodePane)); descLOD.set(loadedDescriptionLoD); } @@ -214,7 +239,8 @@ final public class EventClusterNode extends EventBundleNodeBase impl * @return all the nodes that pass the given predicate */ synchronized Iterable> getNodes(Predicate> p) { - //use this recursive function to flatten the tree of nodes into an iterable. + //use this recursive function to flatten the tree of nodes into an single stream. Function, Stream>> stripeFlattener = new Function, Stream>>() { @Override diff --git a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java index 573302a100..f6861735bd 100644 --- a/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java +++ b/Core/src/org/sleuthkit/autopsy/timeline/ui/detailview/EventStripeNode.java @@ -73,17 +73,20 @@ final public class EventStripeNode extends EventBundleNodeBase> path) { - EventBundle head = path.removeFirst(); EventDescriptionTreeItem descTreeItem = childMap.get(head.getDescription()); if (descTreeItem != null) { if (path.isEmpty() == false) { descTreeItem.remove(path); - } else if (descTreeItem.getChildren().isEmpty()) { + } + if (descTreeItem.getChildren().isEmpty()) { childMap.remove(head.getDescription()); getChildren().remove(descTreeItem); - } } }