correctly handle subnodes when parent node is removed

This commit is contained in:
jmillman 2015-12-01 15:43:45 -05:00
parent 47b6842314
commit 6f2646d061
5 changed files with 41 additions and 35 deletions

View File

@ -356,7 +356,7 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
/**
* @param w the maximum width the description label should have
*/
abstract void setDescriptionWidth(double w);
abstract void setMaxDescriptionWidth(double w);
void setDescriptionVisibility(DescriptionVisibility get) {
descVisibility.set(get);

View File

@ -25,10 +25,8 @@ import java.util.Collections;
import java.util.List;
import static java.util.Objects.nonNull;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javafx.beans.binding.Bindings;
import javafx.concurrent.Task;
import javafx.event.EventHandler;
@ -68,24 +66,6 @@ import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
final public class EventClusterNode extends EventBundleNodeBase<EventCluster, EventStripe, EventStripeNode> {
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<EventStripeNode, Stream<EventStripe>> stripeFlattener = new Function<EventStripeNode, Stream<EventStripe>>() {
@Override
public Stream<EventStripe> 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
@ -137,7 +117,7 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
}
@Override
void setDescriptionWidth(double max) {
void setMaxDescriptionWidth(double max) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@ -214,7 +194,7 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
List<EventStripe> bundles = get();
//clear the existing subnodes
List<EventStripe> transform = subNodes.stream().flatMap(stripeFlattener).collect(Collectors.toList());
List<EventStripe> transform = subNodes.stream().flatMap(new StripeFlattener()).collect(Collectors.toList());
chart.getEventStripes().removeAll(transform);
subNodes.clear();
if (bundles.isEmpty()) {
@ -311,4 +291,5 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
disabledProperty().bind(Bindings.createBooleanBinding(() -> nonNull(getEventCluster()) && descLOD.get() == getEventCluster().getDescriptionLoD(), descLOD));
}
}
}

View File

@ -151,7 +151,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
private final Group nodeGroup = new Group();
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
private final ObservableList<EventStripe> bundles = FXCollections.observableArrayList();
private final ObservableList<EventStripe> eventStripes = FXCollections.observableArrayList();
private final ObservableList< EventStripeNode> stripeNodes = FXCollections.observableArrayList();
private final ObservableList< EventStripeNode> sortedStripeNodes = stripeNodes.sorted(Comparator.comparing(EventStripeNode::getStartMillis));
private final Map<EventCluster, Line> projectionMap = new ConcurrentHashMap<>();
@ -248,7 +248,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
}
ObservableList<EventStripe> getEventStripes() {
return bundles;
return eventStripes;
}
@Override
@ -392,7 +392,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
EventStripeNode stripeNode = new EventStripeNode(EventDetailsChart.this, eventStripe, null);
Platform.runLater(() -> {
bundles.add(eventStripe);
eventStripes.add(eventStripe);
stripeNodes.add(stripeNode);
nodeGroup.getChildren().add(stripeNode);
data.setNode(stripeNode);
@ -408,10 +408,8 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
*/
void removeDataItem(Data<DateTime, EventStripe> data) {
Platform.runLater(() -> {
EventStripe removedStripe = data.getYValue();
bundles.removeAll(removedStripe);
EventStripeNode removedNode = (EventStripeNode) data.getNode();
eventStripes.removeAll(new StripeFlattener().apply(removedNode).collect(Collectors.toList()));
stripeNodes.removeAll(removedNode);
nodeGroup.getChildren().removeAll(removedNode);
data.setNode(null);
@ -468,10 +466,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
.filter(p).collect(Collectors.toList());
}
Iterable<EventBundleNodeBase<?, ?, ?>> getAllNodes() {
return getNodes(x -> true);
}
synchronized void setVScroll(double vScrollValue) {
nodeGroup.setTranslateY(-vScrollValue);
}
@ -588,7 +582,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
bundleNode.setManaged(true);
//apply advanced layout description visibility options
bundleNode.setDescriptionVisibility(descrVisibility.get());
bundleNode.setDescriptionWidth(descriptionWidth);
bundleNode.setMaxDescriptionWidth(descriptionWidth);
//do recursive layout
bundleNode.layoutChildren();

View File

@ -102,7 +102,7 @@ final public class EventStripeNode extends EventBundleNodeBase<EventStripe, Even
* @param w the maximum width the description label should have
*/
@Override
public void setDescriptionWidth(double w) {
public void setMaxDescriptionWidth(double w) {
descrLabel.setMaxWidth(w);
}

View File

@ -0,0 +1,31 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.timeline.ui.detailview;
import java.util.function.Function;
import java.util.stream.Stream;
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
/**
* 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 containing 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
*/
class StripeFlattener implements Function<EventStripeNode, Stream<EventStripe>> {
@Override
public Stream<EventStripe> apply(EventStripeNode node) {
return Stream.concat(
Stream.of(node.getEventStripe()),
node.getSubNodes().stream().flatMap(clusterNode ->
clusterNode.getSubNodes().stream().flatMap(this)));
}
}