diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form index 3fb2b658d9..a847f700c7 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form @@ -166,9 +166,6 @@ - - - @@ -179,9 +176,6 @@ - - - @@ -192,9 +186,6 @@ - - - @@ -205,9 +196,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index a19ccb3f8d..965832b3bd 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -22,6 +22,7 @@ import com.google.common.eventbus.Subscribe; import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; import com.mxgraph.layout.mxCircleLayout; import com.mxgraph.layout.mxFastOrganicLayout; +import com.mxgraph.layout.mxGraphLayout; import com.mxgraph.layout.mxIGraphLayout; import com.mxgraph.layout.mxOrganicLayout; import com.mxgraph.model.mxCell; @@ -54,10 +55,14 @@ import java.text.DecimalFormat; import java.util.Arrays; import static java.util.Collections.singleton; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.concurrent.Future; +import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.ImageIcon; @@ -137,27 +142,23 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private final mxFastOrganicLayout fastOrganicLayout; private final mxCircleLayout circleLayout; private final mxOrganicLayout organicLayout; - private final mxHierarchicalLayout hierarchicalLayout; + private final mxHierarchicalLayout hierarchyLayout; @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private SwingWorker worker; private final PinnedAccountModel pinnedAccountModel; private final LockedVertexModel lockedVertexModel; - private final List layoutButtons; + private final Map layoutButtons = new HashMap<>(); + private mxGraphLayout currentLayout; public VisualizationPanel() { initComponents(); - this.layoutButtons = Arrays.asList(circleLayoutButton, fastOrganicLayoutButton, organicLayoutButton, hierarchyLayoutButton); - graph = new CommunicationsGraph(); + pinnedAccountModel = graph.getPinnedAccountModel(); lockedVertexModel = graph.getLockedVertexModel(); - - fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); - circleLayout = new mxCircleLayoutImpl(graph); - organicLayout = new mxOrganicLayoutImpl(graph); - hierarchicalLayout = new mxHierarchicalLayoutImpl(graph); + graphComponent = new mxGraphComponent(graph); graphComponent.setAutoExtend(true); @@ -197,9 +198,32 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graph.getModel().addListener(mxEvent.UNDO, undoListener); graph.getView().addListener(mxEvent.UNDO, undoListener); + + fastOrganicLayout = new mxFastOrganicLayoutImpl(graph); + circleLayout = new mxCircleLayoutImpl(graph); + organicLayout = new mxOrganicLayoutImpl(graph); + organicLayout.setMaxIterations(10); + hierarchyLayout = new mxHierarchicalLayoutImpl(graph); + //local method to configure layout buttons + BiConsumer configure = (layoutButton, layout) -> { + layoutButtons.put(layout, layoutButton); + layoutButton.addActionListener(event -> applyLayout(layout)); + }; + //configure layout buttons. + configure.accept(circleLayoutButton, circleLayout); + configure.accept(organicLayoutButton, organicLayout); + configure.accept(fastOrganicLayoutButton, fastOrganicLayout); + configure.accept(hierarchyLayoutButton, hierarchyLayout); + + applyLayout(circleLayout); } + /** + * + * @param layoutButton the value of layoutButton + * @param layout the value of layout + */ @Override public Lookup getLookup() { @@ -264,6 +288,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider if (worker.isCancelled()) { graph.resetGraph(); rebuildGraph(); + morph(organicLayout); } else { morph(fastOrganicLayout); } @@ -350,11 +375,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider borderLayoutPanel.setLayout(new BorderLayout()); + jTextArea1.setBackground(new Color(240, 240, 240)); jTextArea1.setColumns(20); jTextArea1.setLineWrap(true); jTextArea1.setRows(5); jTextArea1.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jTextArea1.text")); // NOI18N - jTextArea1.setBackground(new Color(240, 240, 240)); GroupLayout placeHolderPanelLayout = new GroupLayout(placeHolderPanel); placeHolderPanel.setLayout(placeHolderPanelLayout); @@ -379,49 +404,29 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider hierarchyLayoutButton.setFocusable(false); hierarchyLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); hierarchyLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - hierarchyLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - hierarchyLayoutButtonActionPerformed(evt); - } - }); fastOrganicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fastOrganicLayoutButton.text")); // NOI18N fastOrganicLayoutButton.setFocusable(false); fastOrganicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); fastOrganicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - fastOrganicLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - fastOrganicLayoutButtonActionPerformed(evt); - } - }); organicLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.organicLayoutButton.text")); // NOI18N organicLayoutButton.setFocusable(false); organicLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); organicLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - organicLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - organicLayoutButtonActionPerformed(evt); - } - }); circleLayoutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.circleLayoutButton.text")); // NOI18N circleLayoutButton.setFocusable(false); circleLayoutButton.setHorizontalTextPosition(SwingConstants.CENTER); circleLayoutButton.setVerticalTextPosition(SwingConstants.BOTTOM); - circleLayoutButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent evt) { - circleLayoutButtonActionPerformed(evt); - } - }); jSeparator1.setOrientation(SwingConstants.VERTICAL); zoomOutButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-out-red.png"))); // NOI18N zoomOutButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.text")); // NOI18N + zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N zoomOutButton.setFocusable(false); zoomOutButton.setHorizontalTextPosition(SwingConstants.CENTER); - zoomOutButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomOutButton.toolTipText")); // NOI18N zoomOutButton.setVerticalTextPosition(SwingConstants.BOTTOM); zoomOutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -431,9 +436,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider zoomInButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-in-green.png"))); // NOI18N zoomInButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.text")); // NOI18N + zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N zoomInButton.setFocusable(false); zoomInButton.setHorizontalTextPosition(SwingConstants.CENTER); - zoomInButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomInButton.toolTipText")); // NOI18N zoomInButton.setVerticalTextPosition(SwingConstants.BOTTOM); zoomInButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -443,9 +448,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider zoomActualButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-actual.png"))); // NOI18N zoomActualButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.text")); // NOI18N + zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N zoomActualButton.setFocusable(false); zoomActualButton.setHorizontalTextPosition(SwingConstants.CENTER); - zoomActualButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomActualButton.toolTipText")); // NOI18N zoomActualButton.setVerticalTextPosition(SwingConstants.BOTTOM); zoomActualButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -455,9 +460,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider fitZoomButton.setIcon(new ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/communications/images/magnifier-zoom-fit.png"))); // NOI18N fitZoomButton.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.text")); // NOI18N + fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N fitZoomButton.setFocusable(false); fitZoomButton.setHorizontalTextPosition(SwingConstants.CENTER); - fitZoomButton.setToolTipText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.fitZoomButton.toolTipText")); // NOI18N fitZoomButton.setVerticalTextPosition(SwingConstants.BOTTOM); fitZoomButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { @@ -557,38 +562,18 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider graphComponent.zoomOut(); }//GEN-LAST:event_zoomOutButtonActionPerformed - private void circleLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_circleLayoutButtonActionPerformed - makeButtonBold(circleLayoutButton); - morph(circleLayout); - }//GEN-LAST:event_circleLayoutButtonActionPerformed - - private void organicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_organicLayoutButtonActionPerformed - makeButtonBold(organicLayoutButton); - applyOrganicLayout(10); - }//GEN-LAST:event_organicLayoutButtonActionPerformed - - private void fastOrganicLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_fastOrganicLayoutButtonActionPerformed - makeButtonBold(fastOrganicLayoutButton); - morph(fastOrganicLayout); - }//GEN-LAST:event_fastOrganicLayoutButtonActionPerformed - /** - * Sets only the given button to have bold text. * - * @param layoutButton The button to make bold. + * @param layoutButton the value of layoutButton + * @param layout the value of layout */ - private void makeButtonBold(JButton layoutButton) { - layoutButtons.forEach((JButton t) -> { - t.setFont(t.getFont().deriveFont(Font.PLAIN)); - }); - - layoutButton.setFont(layoutButton.getFont().deriveFont(Font.BOLD)); + private void applyLayout(mxGraphLayout layout) { + currentLayout = layout; + layoutButtons.forEach((layoutKey, button) + -> button.setFont(button.getFont().deriveFont(layoutKey == layout ? Font.BOLD : Font.PLAIN)) ); + morph(layout); } - private void hierarchyLayoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_hierarchyLayoutButtonActionPerformed - makeButtonBold(hierarchyLayoutButton); - morph(hierarchicalLayout); - }//GEN-LAST:event_hierarchyLayoutButtonActionPerformed private void clearVizButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_clearVizButtonActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); @@ -602,11 +587,6 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider }//GEN-LAST:event_clearVizButtonActionPerformed - private void applyOrganicLayout(int iterations) { - organicLayout.setMaxIterations(iterations); - morph(organicLayout); - } - private void fitGraph() { graphComponent.zoomTo(1, true); mxPoint translate = graph.getView().getTranslate();