diff --git a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties index 27068a5f55..094538665e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/communications/Bundle.properties @@ -35,3 +35,5 @@ VisualizationPanel.circleLayoutButton.text=Circle VisualizationPanel.OrganicLayoutButton.text=Organic VisualizationPanel.fastOrganicLayoutButton.text=Fast Organic VisualizationPanel.hierarchyLayoutButton.text=Hierarchy +VisualizationPanel.jLabel2.text=Zoom: +VisualizationPanel.zoomLabel.text=100% diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form index baca6eec89..3353f365fe 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.form @@ -165,7 +165,11 @@ - + + + + + @@ -184,6 +188,8 @@ + + @@ -316,6 +322,20 @@ + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 0dd0c4844d..69ea3b9368 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -43,6 +43,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.beans.PropertyVetoException; +import java.text.DecimalFormat; import java.util.Arrays; import static java.util.Collections.singleton; import java.util.EnumSet; @@ -138,41 +139,25 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider //install rubber band selection handler rubberband = new mxRubberband(graphComponent); -// new mxLayoutManager(graph) { -// final private mxOrganicLayout layout; -// private int counter; -// { -// this.layout = new mxOrganicLayout(graph); -// this.layout.setMaxIterations(1); -// } -// -// @Override -// protected void executeLayout(mxIGraphLayout layout, Object parent) { -// if (counter % 10 == 0) -// { -// super.executeLayout(layout, parent); -//// fitGraph(); -// } -// counter++; -// } -// -// @Override -// public mxIGraphLayout getLayout(Object parent) { -// if (graph.getModel().getChildCount(parent) > 0) { -// return layout; -// } -// return null; -// } -// }; - //right click handler - graphComponent.getGraphControl().addMouseListener(new MouseAdapter() { + + graph.getView().addListener(mxEvent.SCALE, (Object sender, mxEventObject evt) -> { + zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getScale())); + }); + + graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, (Object sender, mxEventObject evt) -> { + zoomLabel.setText(DecimalFormat.getPercentInstance().format(graph.getScale())); + }); + final MouseAdapter mouseAdapter = new MouseAdapter() { @Override public void mouseWheelMoved(MouseWheelEvent e) { super.mouseWheelMoved(e); if (e.getPreciseWheelRotation() > 0) { - graphComponent.zoomIn(); + graphComponent.zoomTo(graph.getScale() / graphComponent.getZoomFactor(), true); +// graphComponent.zoomIn(); } else if (e.getPreciseWheelRotation() < 0) { - graphComponent.zoomOut(); + graphComponent.zoomTo(graph.getScale() * graphComponent.getZoomFactor(), true); +// graphComponent.zoomOut(); + } } @@ -192,14 +177,14 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider })); } else { - jPopupMenu.add(new JMenuItem(new AbstractAction("Lock Account " + cellAt.getId(), unlockIcon) { + jPopupMenu.add(new JMenuItem(new AbstractAction("Lock Account " + cellAt.getId(), lockIcon) { @Override public void actionPerformed(ActionEvent e) { graph.lockAccount((AccountDeviceInstanceKey) cellAt.getValue()); } })); - jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock Account " + cellAt.getId(), lockIcon) { + jPopupMenu.add(new JMenuItem(new AbstractAction("UnLock Account " + cellAt.getId(), unlockIcon) { @Override public void actionPerformed(ActionEvent e) { graph.unlockAccount((AccountDeviceInstanceKey) cellAt.getValue()); @@ -223,7 +208,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } } } - }); + }; + //right click handler + graphComponent.getGraphControl().addMouseWheelListener(mouseAdapter); + graphComponent.getGraphControl().addMouseListener(mouseAdapter); splitPane.setRightComponent(new MessageBrowser(vizEM, gacEM)); @@ -372,6 +360,8 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider zoomInButton = new JButton(); zoomActualButton = new JButton(); fitZoomButton = new JButton(); + jLabel2 = new JLabel(); + zoomLabel = new JLabel(); setLayout(new BorderLayout()); @@ -515,6 +505,10 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } }); + jLabel2.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.jLabel2.text")); // NOI18N + + zoomLabel.setText(NbBundle.getMessage(VisualizationPanel.class, "VisualizationPanel.zoomLabel.text")); // NOI18N + GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(GroupLayout.LEADING) @@ -539,7 +533,11 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider .add(zoomActualButton, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.RELATED) .add(fitZoomButton, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) - .addContainerGap(214, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.RELATED, 110, Short.MAX_VALUE) + .add(jLabel2) + .addPreferredGap(LayoutStyle.RELATED) + .add(zoomLabel) + .add(27, 27, 27)) ); jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(GroupLayout.LEADING) .add(jPanel2Layout.createSequentialGroup() @@ -554,7 +552,9 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider .add(zoomOutButton) .add(zoomInButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .add(zoomActualButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .add(fitZoomButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .add(fitZoomButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .add(jLabel2) + .add(zoomLabel)) .add(3, 3, 3)) ); @@ -610,17 +610,31 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider } private void fitGraph() { - final Object[] childVertices = graph.getChildVertices(graph.getDefaultParent()); - mxRectangle boundsForCells = graph.getBoundsForCells(childVertices, true, true, true); - if (boundsForCells == null) { - boundsForCells = new mxRectangle(); - } + mxPoint translate = graph.getView().getTranslate(); - if (translate == null) { + if (translate == null || Double.isNaN(translate.getX()) || Double.isNaN(translate.getY())) { translate = new mxPoint(); } + mxRectangle boundsForCells = graph.getCellBounds(graph.getDefaultParent(), true, true, true); + if (boundsForCells == null||Double.isNaN( boundsForCells.getWidth()) || Double.isNaN(boundsForCells.getHeight())) { + boundsForCells = new mxRectangle(0,0,1,1); + } graph.getView().setTranslate(new mxPoint(translate.getX() - boundsForCells.getX(), translate.getY() - boundsForCells.getY())); + + boundsForCells = graph.getCellBounds(graph.getDefaultParent(), true, true, true); + if (boundsForCells == null||Double.isNaN( boundsForCells.getWidth()) || Double.isNaN(boundsForCells.getHeight())) { + boundsForCells = new mxRectangle(0,0,1,1); + } + + Dimension size = graphComponent.getSize(); + + double widthFactor = size.getWidth() / boundsForCells.getWidth(); +// widthFactor = boundsForCells.getWidth() / size.getWidth(); + + graphComponent.zoom(widthFactor); + +// bounds = graph.getGraphBounds(); } private void morph(mxIGraphLayout layout) { @@ -655,6 +669,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private JButton fitZoomButton; private JButton hierarchyLayoutButton; private JLabel jLabel1; + private JLabel jLabel2; private JPanel jPanel1; private JPanel jPanel2; private JToolBar.Separator jSeparator1; @@ -666,6 +681,7 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider private JLabel statusLabel; private JButton zoomActualButton; private JButton zoomInButton; + private JLabel zoomLabel; private JButton zoomOutButton; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/communications/mxGraphImpl.java b/Core/src/org/sleuthkit/autopsy/communications/mxGraphImpl.java index da235f1526..7da06754fb 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/mxGraphImpl.java +++ b/Core/src/org/sleuthkit/autopsy/communications/mxGraphImpl.java @@ -93,6 +93,33 @@ final class mxGraphImpl extends mxGraph { setKeepEdgesInBackground(true); setResetEdgesOnMove(true); setHtmlLabels(true); + +// new mxLayoutManager(graph) { +// final private mxOrganicLayout layout; +// private int counter; +// { +// this.layout = new mxOrganicLayout(graph); +// this.layout.setMaxIterations(1); +// } +// +// @Override +// protected void executeLayout(mxIGraphLayout layout, Object parent) { +// if (counter % 10 == 0) +// { +// super.executeLayout(layout, parent); +//// fitGraph(); +// } +// counter++; +// } +// +// @Override +// public mxIGraphLayout getLayout(Object parent) { +// if (graph.getModel().getChildCount(parent) > 0) { +// return layout; +// } +// return null; +// } +// }; } @Override @@ -214,7 +241,12 @@ final class mxGraphImpl extends mxGraph { } boolean hasPinnedAccounts() { - return pinnedAccountDevices.isEmpty() == false; } + return pinnedAccountDevices.isEmpty() == false; + } + + double getScale() { + return getView().getScale(); + } class SwingWorkerImpl extends SwingWorker {