From 3e49de2c1b9d85f85ef4593813a602a9ac52b42c Mon Sep 17 00:00:00 2001 From: millmanorama Date: Fri, 5 Jan 2018 16:00:15 +0100 Subject: [PATCH] WIP 2 getting graph selection to populate MessageBrowser WIP 2 --- .../communications/AccountsBrowser.java | 19 +++-- .../autopsy/communications/Bundle.properties | 2 + .../communications/CVTTopComponent.form | 84 ++++++++++--------- .../communications/CVTTopComponent.java | 68 ++++++++++----- .../communications/VisualizationPanel.java | 63 +++++++------- 5 files changed, 137 insertions(+), 99 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java index 8e418d65fb..c90572bff8 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java +++ b/Core/src/org/sleuthkit/autopsy/communications/AccountsBrowser.java @@ -31,7 +31,7 @@ import org.openide.explorer.ExplorerManager; * A panel that goes in the Browse tab of the Communications Visualization Tool. * Hosts an OutlineView that shows information about Accounts. */ -public class AccountsBrowser extends JPanel { +public class AccountsBrowser extends JPanel implements ExplorerManager.Provider { private static final long serialVersionUID = 1L; @@ -56,10 +56,8 @@ public class AccountsBrowser extends JPanel { outline.setColumnSorted(3, false, 1); //it would be nice if the column index wasn't hardcoded } - @Override - public void addNotify() { - super.addNotify(); - em = ExplorerManager.find(this); + void init(ExplorerManager acctsBrowserExplorerManager) { + em = acctsBrowserExplorerManager; em.addPropertyChangeListener(evt -> { if (ExplorerManager.PROP_ROOT_CONTEXT.equals(evt.getPropertyName())) { SwingUtilities.invokeLater(this::setColumnWidths); @@ -67,8 +65,8 @@ public class AccountsBrowser extends JPanel { SwingUtilities.invokeLater(this::setColumnWidths); } }); - } - + + } private void setColumnWidths() { int margin = 4; int padding = 8; @@ -126,4 +124,11 @@ public class AccountsBrowser extends JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private org.openide.explorer.view.OutlineView outlineView; // End of variables declaration//GEN-END:variables + + @Override + public ExplorerManager getExplorerManager() { + return em; + } + + } diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 6f78ddf19b..d4740c7644 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -18,3 +18,5 @@ FiltersPanel.needsRefreshLabel.text=Displayed data is out of date. Press Refresh VisualizationPanel.jButton1.text=redo layout CVTTopComponent.vizPanel.TabConstraints.tabTitle=Visualize VisualizationPanel.jButton2.text=pan +CVTTopComponent.browseSplitPane.TabConstraints.tabTitle=Browse +CVTTopComponent.vizSplitPane.TabConstraints.tabTitle=Visualize diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form index a24037b927..5a2d718964 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.form @@ -19,9 +19,9 @@ - - - + + + @@ -29,63 +29,71 @@ - - - - + + + + + - + - - + + + - + - - - - - - + - - + + + + + + + + + - + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java index 9e54b5d87f..d395f9d1ab 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CVTTopComponent.java @@ -21,9 +21,12 @@ package org.sleuthkit.autopsy.communications; import com.google.common.eventbus.Subscribe; import java.util.List; import java.util.stream.Collectors; +import javax.swing.JSplitPane; import org.openide.explorer.ExplorerManager; -import org.openide.explorer.ExplorerUtils; +import static org.openide.explorer.ExplorerUtils.createLookup; +import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.openide.util.lookup.ProxyLookup; import org.openide.windows.Mode; import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; @@ -40,23 +43,25 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined; public final class CVTTopComponent extends TopComponent implements ExplorerManager.Provider { private static final long serialVersionUID = 1L; - private final ExplorerManager messagesBrowserExplorerManager; private final ExplorerManager acctsBrowserExplorerManager; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) public CVTTopComponent() { initComponents(); + setName(Bundle.CVTTopComponent_name()); /* * Associate an explorer manager with the GlobalActionContext (GAC) for - * use by the messages browser so that selections in the messages + * use by the messages browsers so that selections in the messages * browser can be exposed to context-sensitive actions. */ - messagesBrowserExplorerManager = new ExplorerManager(); - associateLookup(ExplorerUtils.createLookup(messagesBrowserExplorerManager, getActionMap())); - splitPane.setRightComponent(new MessageBrowser(messagesBrowserExplorerManager)); - + ExplorerManager browserExplorerManager = new ExplorerManager(); + ExplorerManager vizExplorerManager = new ExplorerManager(); + ProxyLookupImpl proxyLookup = new ProxyLookupImpl(); + associateLookup(proxyLookup); + browseSplitPane.setRightComponent(new MessageBrowser(browserExplorerManager)); + vizSplitPane.setRightComponent(new MessageBrowser(vizExplorerManager)); /* * Create a second explorer manager to be discovered by the accounts * browser and the message browser so that the browsers can both listen @@ -65,9 +70,14 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag * Nodes from the accounts browser to the messages browser. */ acctsBrowserExplorerManager = new ExplorerManager(); + accountsBrowser.init(acctsBrowserExplorerManager); + vizPanel.initVisualization(acctsBrowserExplorerManager); - vizPanel.initVisualization(acctsBrowserExplorerManager, messagesBrowserExplorerManager); - + browseVisualizeTabPane.addChangeListener(changeEvent -> { + JSplitPane selectedComponent = (JSplitPane) browseVisualizeTabPane.getSelectedComponent(); + ExplorerManager.Provider leftComponent = (ExplorerManager.Provider) selectedComponent.getLeftComponent(); + proxyLookup.changeLookup(createLookup(leftComponent.getExplorerManager(), getActionMap())); + }); CVTEvents.getCVTEventBus().register(this); @@ -86,20 +96,22 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag // //GEN-BEGIN:initComponents private void initComponents() { - splitPane = new javax.swing.JSplitPane(); browseVisualizeTabPane = new javax.swing.JTabbedPane(); + browseSplitPane = new javax.swing.JSplitPane(); accountsBrowser = new org.sleuthkit.autopsy.communications.AccountsBrowser(); + vizSplitPane = new javax.swing.JSplitPane(); vizPanel = new org.sleuthkit.autopsy.communications.VisualizationPanel(); filtersPane = new org.sleuthkit.autopsy.communications.FiltersPanel(); - splitPane.setDividerLocation(400); - splitPane.setResizeWeight(0.7); - browseVisualizeTabPane.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N - browseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.accountsBrowser.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), accountsBrowser); // NOI18N - browseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.vizPanel.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), vizPanel); // NOI18N - splitPane.setLeftComponent(browseVisualizeTabPane); + browseSplitPane.setLeftComponent(accountsBrowser); + + browseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.browseSplitPane.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/table.png")), browseSplitPane); // NOI18N + + vizSplitPane.setLeftComponent(vizPanel); + + browseVisualizeTabPane.addTab(org.openide.util.NbBundle.getMessage(CVTTopComponent.class, "CVTTopComponent.vizSplitPane.TabConstraints.tabTitle"), new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/emblem-web.png")), vizSplitPane); // NOI18N filtersPane.setMinimumSize(new java.awt.Dimension(256, 495)); @@ -111,27 +123,29 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag .addGap(6, 6, 6) .addComponent(filtersPane, javax.swing.GroupLayout.PREFERRED_SIZE, 265, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(splitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1324, Short.MAX_VALUE) - .addGap(0, 0, 0)) + .addComponent(browseVisualizeTabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 786, Short.MAX_VALUE) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(6, 6, 6) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(splitPane)) + .addComponent(filtersPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(5, 5, 5)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(browseVisualizeTabPane) + .addContainerGap()) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private org.sleuthkit.autopsy.communications.AccountsBrowser accountsBrowser; + private javax.swing.JSplitPane browseSplitPane; private javax.swing.JTabbedPane browseVisualizeTabPane; private org.sleuthkit.autopsy.communications.FiltersPanel filtersPane; - private javax.swing.JSplitPane splitPane; private org.sleuthkit.autopsy.communications.VisualizationPanel vizPanel; + private javax.swing.JSplitPane vizSplitPane; // End of variables declaration//GEN-END:variables @Override @@ -167,4 +181,14 @@ public final class CVTTopComponent extends TopComponent implements ExplorerManag return modes.stream().filter(mode -> mode.getName().equals("cvt")) .collect(Collectors.toList()); } + + private static class ProxyLookupImpl extends ProxyLookup { + + public ProxyLookupImpl() { + } + + void changeLookup(Lookup l){ + setLookups(l); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index a2ec62f8ff..15e71dc88f 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -27,8 +27,6 @@ import com.mxgraph.util.mxConstants; import com.mxgraph.view.mxGraph; import com.mxgraph.view.mxStylesheet; import java.awt.Color; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; import java.beans.PropertyVetoException; import java.util.HashMap; import java.util.List; @@ -59,7 +57,7 @@ import org.sleuthkit.datamodel.TskCoreException; /** * */ -public class VisualizationPanel extends JPanel { +public class VisualizationPanel extends JPanel implements ExplorerManager.Provider { static final private mxStylesheet mxStylesheet = new mxStylesheet(); private ExplorerManager explorerManager; @@ -92,12 +90,6 @@ public class VisualizationPanel extends JPanel { graphComponent.setOpaque(true); graphComponent.setBackground(Color.WHITE); this.add(graphComponent); - graphComponent.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - graphComponent.zoomTo(graphComponent.getZoomFactor() + e.getPreciseWheelRotation(), true); - } - }); CVTEvents.getCVTEventBus().register(this); @@ -105,7 +97,7 @@ public class VisualizationPanel extends JPanel { } - public void initVisualization(ExplorerManager em, ExplorerManager messageBrowserManager) { + public void initVisualization(ExplorerManager em) { explorerManager = em; graph.getSelectionModel().addListener(null, (sender, evt) -> { @@ -119,8 +111,8 @@ public class VisualizationPanel extends JPanel { final AccountDeviceInstanceNode accountDeviceInstanceNode = new AccountDeviceInstanceNode(((AccountDeviceInstanceKey) selectionCell.getValue()), commsManager); - messageBrowserManager.setRootContext(SimpleParentNode.createFromChildNodes(accountDeviceInstanceNode)); - messageBrowserManager.setSelectedNodes(new Node[]{accountDeviceInstanceNode}); + explorerManager.setRootContext(SimpleParentNode.createFromChildNodes(accountDeviceInstanceNode)); + explorerManager.setSelectedNodes(new Node[]{accountDeviceInstanceNode}); } else if (selectionCell.isEdge()) { System.out.println(selectionCell.getId()); @@ -136,6 +128,11 @@ public class VisualizationPanel extends JPanel { }); } + @Override + public ExplorerManager getExplorerManager() { + return explorerManager; + } + private void addEdge(mxCell pinnedAccountVertex, mxCell relatedAccountVertex) { Object[] edgesBetween = graph.getEdgesBetween(pinnedAccountVertex, relatedAccountVertex); @@ -150,6 +147,7 @@ public class VisualizationPanel extends JPanel { } } + @Deprecated private void addEdge(BlackboardArtifact artifact) throws TskCoreException { BlackboardArtifact.ARTIFACT_TYPE artfType = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID()); if (null != artfType) { @@ -177,8 +175,8 @@ public class VisualizationPanel extends JPanel { for (String to : tos) { if (StringUtils.isNotBlank(from) && StringUtils.isNotBlank(to)) { - mxCell fromV = getOrCreateNodeDraft(from, 10); - mxCell toV = getOrCreateNodeDraft(to, 10); + mxCell fromV = getOrCreateVertex(from, 10); + mxCell toV = getOrCreateVertex(to, 10); Object[] edgesBetween = graph.getEdgesBetween(fromV, toV); @@ -206,7 +204,7 @@ public class VisualizationPanel extends JPanel { nodeMap.clear(); graph.removeCells(graph.getChildCells(graph.getDefaultParent(), true, true)); - mxCell pinnedAccountVertex = getOrCreateNodeDraft(adiKey); + mxCell pinnedAccountVertex = getOrCreateVertex(adiKey); CommunicationsManager commsManager = adiNode.getCommsManager(); final CommunicationsFilter commsFilter = adiNode.getFilter(); List relatedAccountDeviceInstances = @@ -216,7 +214,7 @@ public class VisualizationPanel extends JPanel { long communicationsCount = commsManager.getRelationshipSourcesCount(relatedADI, commsFilter); String dataSourceName = AccountsRootChildren.getDataSourceName(relatedADI); AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, commsFilter, communicationsCount, dataSourceName); - mxCell relatedAccountVertex = getOrCreateNodeDraft(relatedADIKey); + mxCell relatedAccountVertex = getOrCreateVertex(relatedADIKey); addEdge(pinnedAccountVertex, relatedAccountVertex); } @@ -231,30 +229,31 @@ public class VisualizationPanel extends JPanel { new mxFastOrganicLayout(graph).execute(graph.getDefaultParent()); } - private mxCell getOrCreateNodeDraft(AccountDeviceInstanceKey accountDeviceInstanceKey) { + private mxCell getOrCreateVertex(AccountDeviceInstanceKey accountDeviceInstanceKey) { final AccountDeviceInstance accountDeviceInstance = accountDeviceInstanceKey.getAccountDeviceInstance(); final String name =// accountDeviceInstance.getDeviceId() + ":" + accountDeviceInstance.getAccount().getTypeSpecificID(); - mxCell nodeDraft = nodeMap.get(name); - if (nodeDraft == null) { - double size = accountDeviceInstanceKey.getMessageCount() / 10; - nodeDraft = (mxCell) graph.insertVertex( + mxCell vertex = nodeMap.get(name); + if (vertex == null) { + double size = Math.sqrt(accountDeviceInstanceKey.getMessageCount()) + 10; + vertex = (mxCell) graph.insertVertex( graph.getDefaultParent(), name, accountDeviceInstanceKey, new Random().nextInt(200), new Random().nextInt(200), size, size); - graph.getView().getState(nodeDraft, true).setLabel(name); - nodeMap.put(name, nodeDraft); + graph.getView().getState(vertex, true).setLabel(name); + nodeMap.put(name, vertex); } - return nodeDraft; + return vertex; } - private mxCell getOrCreateNodeDraft(String name, long size) { - mxCell nodeDraft = nodeMap.get(name); - if (nodeDraft == null) { - nodeDraft = (mxCell) graph.insertVertex( + @Deprecated + private mxCell getOrCreateVertex(String name, long size) { + mxCell vertex = nodeMap.get(name); + if (vertex == null) { + vertex = (mxCell) graph.insertVertex( graph.getDefaultParent(), name, name, @@ -262,10 +261,10 @@ public class VisualizationPanel extends JPanel { new Random().nextInt(200), size, size); - graph.getView().getState(nodeDraft, true).setLabel(name); - nodeMap.put(name, nodeDraft); + graph.getView().getState(vertex, true).setLabel(name); + nodeMap.put(name, vertex); } - return nodeDraft; + return vertex; } /** @@ -312,7 +311,7 @@ public class VisualizationPanel extends JPanel { private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed // graphComponent.addMouseListener(new mxPanningHandler(graphComponent)); -graphComponent.getPanningHandler().setEnabled(true); + graphComponent.getPanningHandler().setEnabled(true); }//GEN-LAST:event_jButton2ActionPerformed private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed