From eaab28e734d7916a7786c8beaf025d487175c68e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 12 May 2020 06:03:37 -0400 Subject: [PATCH] 6305 fixed animating of details area --- .../autopsy/core/discoveryWsmode.xml | 2 +- .../autopsy/discovery/Bundle.properties | 3 +- .../discovery/Bundle.properties-MERGED | 3 +- .../autopsy/discovery/DetailsPanel.form | 96 ++++- .../autopsy/discovery/DetailsPanel.java | 207 +++++++++- .../autopsy/discovery/DiscoveryDialog.form | 5 +- .../autopsy/discovery/DiscoveryDialog.java | 24 +- .../discovery/DiscoveryEventUtils.java | 51 ++- .../discovery/DiscoveryTopComponent.form | 19 +- .../discovery/DiscoveryTopComponent.java | 158 ++++++-- .../discovery/OpenDiscoveryAction.java | 21 +- .../autopsy/discovery/ResultsPanel.form | 147 ++----- .../autopsy/discovery/ResultsPanel.java | 373 ++---------------- 13 files changed, 553 insertions(+), 556 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/core/discoveryWsmode.xml b/Core/src/org/sleuthkit/autopsy/core/discoveryWsmode.xml index ef5da81277..cde1d1b91d 100644 --- a/Core/src/org/sleuthkit/autopsy/core/discoveryWsmode.xml +++ b/Core/src/org/sleuthkit/autopsy/core/discoveryWsmode.xml @@ -3,7 +3,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties index db3f094fc7..6adf34c316 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties @@ -48,14 +48,12 @@ ResultsPanel.currentPageLabel.text=Page: - ResultsPanel.pageControlsLabel.text=Pages: ResultsPanel.gotoPageLabel.text=Go to Page: ResultsPanel.pageSizeLabel.text=Page Size: -ResultsPanel.instancesList.border.title=Instances DiscoveryExtractAction.title.extractFiles.text=Extract File FileSearchPanel.includeRadioButton.text=Include FileSearchPanel.excludeRadioButton.text=Exclude FileSearchPanel.knownFilesCheckbox.toolTipText= FileSearchPanel.knownFilesCheckbox.text=Hide known files GroupListPanel.groupKeyList.border.title=Groups -ResultsPanel.resultsSplitPane.toolTipText= FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings DocumentPanel.fileSizeLabel.toolTipText= DocumentPanel.isDeletedLabel.toolTipText= @@ -66,3 +64,4 @@ DiscoveryDialog.videosButton.text=Videos DiscoveryDialog.imagesButton.text=Images DiscoveryDialog.searchButton.text=Show DiscoveryDialog.cancelButton.text=Cancel +DetailsPanel.instancesList.border.title=Instances diff --git a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties-MERGED index f69686a0ea..b7dd8cf30a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/discovery/Bundle.properties-MERGED @@ -200,14 +200,12 @@ ResultsPanel.openInExternalViewer.name=Open in External Viewer ResultsPanel.pageControlsLabel.text=Pages: ResultsPanel.gotoPageLabel.text=Go to Page: ResultsPanel.pageSizeLabel.text=Page Size: -ResultsPanel.instancesList.border.title=Instances DiscoveryExtractAction.title.extractFiles.text=Extract File FileSearchPanel.includeRadioButton.text=Include FileSearchPanel.excludeRadioButton.text=Exclude FileSearchPanel.knownFilesCheckbox.toolTipText= FileSearchPanel.knownFilesCheckbox.text=Hide known files GroupListPanel.groupKeyList.border.title=Groups -ResultsPanel.resultsSplitPane.toolTipText= FileSearchPanel.stepThreeLabel.text=Step 3: Choose display settings DocumentPanel.fileSizeLabel.toolTipText= DocumentPanel.isDeletedLabel.toolTipText= @@ -218,6 +216,7 @@ DiscoveryDialog.videosButton.text=Videos DiscoveryDialog.imagesButton.text=Images DiscoveryDialog.searchButton.text=Show DiscoveryDialog.cancelButton.text=Cancel +DetailsPanel.instancesList.border.title=Instances ResultsPanel.unableToCreate.text=Unable to create summary. ResultsPanel.viewFileInDir.name=View File in Directory VideoThumbnailPanel.bytes.text=bytes diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form index 058ed2dd31..32f78a9645 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.form @@ -16,9 +16,9 @@ - + - + @@ -26,7 +26,7 @@ - + @@ -34,10 +34,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java index c49cbe0edc..46be9cca8c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DetailsPanel.java @@ -1,11 +1,48 @@ /* - * 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. + * Autopsy + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.discovery; +import com.google.common.eventbus.Subscribe; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import org.sleuthkit.autopsy.actions.AddContentTagAction; +import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.corecomponents.DataContentPanel; +import org.sleuthkit.autopsy.corecomponents.TableFilterNode; +import org.sleuthkit.autopsy.datamodel.FileNode; +import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; +import org.sleuthkit.autopsy.directorytree.ViewContextAction; +import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction; +import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.TskCoreException; /** * @@ -13,7 +50,11 @@ import org.sleuthkit.autopsy.corecomponents.DataContentPanel; */ public class DetailsPanel extends javax.swing.JPanel { + private static final long serialVersionUID = 1L; + private final DataContentPanel dataContentPanel; + private final DefaultListModel instancesListModel = new DefaultListModel<>(); + private ListSelectionListener listener = null; /** * Creates new form DetailsPanel @@ -21,7 +62,95 @@ public class DetailsPanel extends javax.swing.JPanel { public DetailsPanel() { initComponents(); dataContentPanel = DataContentPanel.createInstance(); - detailsSplitPane.setBottomComponent(dataContentPanel); + + detailsSplitPane.setBottomComponent(dataContentPanel); + //Add the context menu when right clicking + instancesList.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + SwingUtilities.invokeLater(() -> { + instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint())); + Set files = new HashSet<>(); + files.add(instancesList.getSelectedValue()); + JPopupMenu menu = new JPopupMenu(); + menu.add(new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue())); + menu.add(new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(), new FileNode(instancesList.getSelectedValue()))); + menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue())); + menu.add(new DiscoveryExtractAction(files)); + menu.add(AddContentTagAction.getInstance().getMenuForContent(files)); + menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files)); + menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files)); + menu.show(instancesList, e.getPoint().x, e.getPoint().y); + }); + } + } + }); + listener = new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + if (!e.getValueIsAdjusting()) { + SwingUtilities.invokeLater(() -> { + AbstractFile file = getSelectedFile(); + if (file != null) { + dataContentPanel.setNode(new TableFilterNode(new FileNode(file), false)); + } else { + dataContentPanel.setNode(null); + } + }); + } + } + }; + instancesList.addListSelectionListener(listener); + } + + @Subscribe + void handleClearSelectionListener(DiscoveryEventUtils.ClearInstanceSelectionEvent clearEvent) { + instancesList.clearSelection(); + } + + /** + * Populate the instances list. + */ + @Subscribe + synchronized void handlePopulateInstancesListEvent(DiscoveryEventUtils.PopulateInstancesListEvent populateEvent) { + SwingUtilities.invokeLater(() -> { + List files = populateEvent.getInstances(); + if (files.isEmpty()) { + //if there are no files currently remove the current items without removing listener to cause content viewer to reset + instancesListModel.removeAllElements(); + //send fade out event + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(false)); + } else { + //remove listener so content viewer node is not set multiple times + instancesList.removeListSelectionListener(listener); + instancesListModel.removeAllElements(); + for (AbstractFile file : files) { + instancesListModel.addElement(file); + } + //add listener back to allow selection of first index to cause content viewer node to be set + instancesList.addListSelectionListener(listener); + if (!instancesListModel.isEmpty()) { + instancesList.setSelectedIndex(0); + } + //send fade in event + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.DetailsVisibleEvent(true)); + } + }); + } + + /** + * Get the AbstractFile for the item currently selected in the instances + * list. + * + * @return The AbstractFile which is currently selected. + */ + synchronized AbstractFile getSelectedFile() { + if (instancesList.getSelectedIndex() == -1) { + return null; + } else { + return instancesListModel.getElementAt(instancesList.getSelectedIndex()); + } } /** @@ -34,27 +163,91 @@ public class DetailsPanel extends javax.swing.JPanel { private void initComponents() { detailsSplitPane = new javax.swing.JSplitPane(); + javax.swing.JPanel instancesPanel = new javax.swing.JPanel(); + javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane(); + instancesList = new javax.swing.JList<>(); + detailsSplitPane.setDividerLocation(80); detailsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + detailsSplitPane.setMinimumSize(new java.awt.Dimension(200, 0)); + detailsSplitPane.setPreferredSize(new java.awt.Dimension(700, 500)); + + instancesPanel.setMinimumSize(new java.awt.Dimension(0, 60)); + instancesPanel.setPreferredSize(new java.awt.Dimension(700, 80)); + + instancesScrollPane.setPreferredSize(new java.awt.Dimension(775, 60)); + + instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(DetailsPanel.class, "DetailsPanel.instancesList.border.title"))); // NOI18N + instancesList.setModel(instancesListModel); + instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + instancesList.setCellRenderer(new InstancesCellRenderer()); + instancesList.setVisibleRowCount(2); + instancesScrollPane.setViewportView(instancesList); + + javax.swing.GroupLayout instancesPanelLayout = new javax.swing.GroupLayout(instancesPanel); + instancesPanel.setLayout(instancesPanelLayout); + instancesPanelLayout.setHorizontalGroup( + instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 775, Short.MAX_VALUE) + .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + instancesPanelLayout.setVerticalGroup( + instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 79, Short.MAX_VALUE) + .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE))) + ); + + detailsSplitPane.setTopComponent(instancesPanel); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 667, Short.MAX_VALUE) + .addGap(0, 777, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 667, Short.MAX_VALUE)) + .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 402, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE)) + .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JSplitPane detailsSplitPane; + private javax.swing.JList instancesList; // End of variables declaration//GEN-END:variables + + /** + * Cell renderer for the instances list. + */ + private class InstancesCellRenderer extends DefaultListCellRenderer { + + private static final long serialVersionUID = 1L; + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + String name = ""; + if (value instanceof AbstractFile) { + AbstractFile file = (AbstractFile) value; + try { + name = file.getUniquePath(); + } catch (TskCoreException ingored) { + name = file.getParentPath() + "/" + file.getName(); + } + + } + setText(name); + return this; + } + + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form index 0f36d5ae95..4f74b9ff75 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.form @@ -202,11 +202,14 @@ - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java index 9a1c45ccaa..70ca36cb2c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryDialog.java @@ -37,11 +37,19 @@ final class DiscoveryDialog extends javax.swing.JDialog { private static final Color SELECTED_COLOR = new Color(216, 230, 242); private static final Color UNSELECTED_COLOR = new Color(240, 240, 240); private SearchWorker searchWorker = null; + private static DiscoveryDialog discoveryDialog; - DiscoveryDialog() { + private DiscoveryDialog() { this(null, true); } + public static synchronized DiscoveryDialog getDiscoveryDialogInstance() { + if (discoveryDialog == null) { + discoveryDialog = new DiscoveryDialog(); + } + return discoveryDialog; + } + /** * Creates new form DiscoveryDialog */ @@ -100,7 +108,7 @@ final class DiscoveryDialog extends javax.swing.JDialog { jPanel1 = new javax.swing.JPanel(); searchButton = new javax.swing.JButton(); errorLabel = new javax.swing.JLabel(); - cancelButton = new javax.swing.JButton(); + javax.swing.JButton cancelButton = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -180,7 +188,6 @@ final class DiscoveryDialog extends javax.swing.JDialog { errorLabel.setForeground(new java.awt.Color(255, 0, 0)); org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(DiscoveryDialog.class, "DiscoveryDialog.cancelButton.text")); // NOI18N - cancelButton.setEnabled(false); cancelButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cancelButtonActionPerformed(evt); @@ -270,12 +277,9 @@ final class DiscoveryDialog extends javax.swing.JDialog { if (tc.isOpened() == false) { tc.open(); -// tc.updateSearchSettings(); -// displayErrorMessage(tc); } tc.resetTopComponent(); List filters = filterPanel.getFilters(); -// enableSearch(false); DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.SearchStartedEvent(filterPanel.getSelectedType())); // Get the grouping attribute and group sorting method @@ -300,10 +304,15 @@ final class DiscoveryDialog extends javax.swing.JDialog { tc.requestActive(); }//GEN-LAST:event_searchButtonActionPerformed + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed -// cancelSearch(); + this.setVisible(false); }//GEN-LAST:event_cancelButtonActionPerformed + void cancelSearch() { + filterPanel.cancelSearch(); + } + /** * The settings are valid so enable the Search button */ @@ -324,7 +333,6 @@ final class DiscoveryDialog extends javax.swing.JDialog { } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton cancelButton; private javax.swing.JButton documentsButton; private javax.swing.JLabel errorLabel; private javax.swing.JButton imagesButton; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java index bc0c8e32df..4151a09c4b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryEventUtils.java @@ -1,7 +1,7 @@ /* * Autopsy * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; import org.sleuthkit.autopsy.discovery.FileSearchData.FileType; +import org.sleuthkit.datamodel.AbstractFile; /** * Class to handle event bus and events for file discovery tool. @@ -70,6 +71,36 @@ final class DiscoveryEventUtils { } } + static final class ClearInstanceSelectionEvent { + + /** + * Construct a new ClearInstanceSelectionEvent. + */ + ClearInstanceSelectionEvent() { + //no arg constructor + } + } + + static final class PopulateInstancesListEvent { + + private final List instances; + + /** + * Construct a new PopulateInstancesListEvent. + */ + PopulateInstancesListEvent(List files) { + instances = files; + //no arg constructor + } + + /** + * @return the instances + */ + List getInstances() { + return Collections.unmodifiableList(instances); + } + } + /** * Event to signal the completion of a search being performed. */ @@ -332,4 +363,22 @@ final class DiscoveryEventUtils { } } + + static class DetailsVisibleEvent { + + private final boolean showDetailsArea; + + DetailsVisibleEvent(boolean isVisible) { + showDetailsArea = isVisible; + //no arg constructor + } + + /** + * @return the showDetailsArea + */ + boolean isShowDetailsArea() { + return showDetailsArea; + } + } + } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.form b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.form index df7946a5c2..b5cffa4a96 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.form @@ -2,8 +2,11 @@
+ + + - + @@ -16,16 +19,16 @@ - + - + - + @@ -38,13 +41,15 @@ - - + - + + + + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java index f17849c678..5179a2effd 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/DiscoveryTopComponent.java @@ -1,7 +1,7 @@ /* * Autopsy * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,21 +18,17 @@ */ package org.sleuthkit.autopsy.discovery; +import com.google.common.eventbus.Subscribe; +import java.awt.Graphics; import java.util.List; import java.util.stream.Collectors; -import javax.swing.SwingUtilities; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; +import javax.swing.JSplitPane; import org.openide.util.NbBundle; import org.openide.windows.Mode; import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.corecomponents.DataContentPanel; -import org.sleuthkit.autopsy.corecomponents.TableFilterNode; import org.sleuthkit.autopsy.coreutils.ThreadConfined; -import org.sleuthkit.autopsy.datamodel.FileNode; -import org.sleuthkit.datamodel.AbstractFile; /** * Create a dialog for displaying the file discovery tool @@ -45,10 +41,15 @@ public final class DiscoveryTopComponent extends TopComponent { private static final long serialVersionUID = 1L; private static final String PREFERRED_ID = "DiscoveryTopComponent"; // NON-NLS - private final FileSearchPanel fileSearchPanel; private final GroupListPanel groupListPanel; - private final DataContentPanel dataContentPanel; + private final DetailsPanel detailsPanel; private final ResultsPanel resultsPanel; + private int dividerLocation; + + private static final int ANIMATION_INCREMENT = 10; + private static final int RESULTS_AREA_SMALL_SIZE = 200; + + private SwingAnimator animator = null; /** * Creates new form FileDiscoveryDialog @@ -57,31 +58,14 @@ public final class DiscoveryTopComponent extends TopComponent { public DiscoveryTopComponent() { initComponents(); setName(Bundle.DiscoveryTopComponent_name()); - fileSearchPanel = new FileSearchPanel(); - dataContentPanel = DataContentPanel.createInstance(); - resultsPanel = new ResultsPanel(); groupListPanel = new GroupListPanel(); + resultsPanel = new ResultsPanel(); + detailsPanel = new DetailsPanel(); mainSplitPane.setLeftComponent(groupListPanel); rightSplitPane.setTopComponent(resultsPanel); - rightSplitPane.setBottomComponent(dataContentPanel); - //add list selection listener so the content viewer will be updated with the selected file - //when a file is selected in the results panel - resultsPanel.addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - if (!e.getValueIsAdjusting()) { - SwingUtilities.invokeLater(() -> { - AbstractFile file = resultsPanel.getSelectedFile(); - if (file != null) { - dataContentPanel.setNode(new TableFilterNode(new FileNode(file), false)); - } else { - dataContentPanel.setNode(null); - } - }); - } - } - }); - + rightSplitPane.setBottomComponent(detailsPanel); + rightSplitPane.setDividerLocation(1.0); + dividerLocation = rightSplitPane.getDividerLocation(); } /** @@ -108,19 +92,24 @@ public final class DiscoveryTopComponent extends TopComponent { DiscoveryEventUtils.getDiscoveryEventBus().register(this); DiscoveryEventUtils.getDiscoveryEventBus().register(resultsPanel); DiscoveryEventUtils.getDiscoveryEventBus().register(groupListPanel); - DiscoveryEventUtils.getDiscoveryEventBus().register(fileSearchPanel); + DiscoveryEventUtils.getDiscoveryEventBus().register(detailsPanel); } @Override protected void componentClosed() { - fileSearchPanel.cancelSearch(); + cancelCurrentSearch(); DiscoveryEventUtils.getDiscoveryEventBus().unregister(this); - DiscoveryEventUtils.getDiscoveryEventBus().unregister(fileSearchPanel); DiscoveryEventUtils.getDiscoveryEventBus().unregister(groupListPanel); DiscoveryEventUtils.getDiscoveryEventBus().unregister(resultsPanel); + DiscoveryEventUtils.getDiscoveryEventBus().unregister(detailsPanel); super.componentClosed(); } + private void cancelCurrentSearch() { + final DiscoveryDialog discDialog = DiscoveryDialog.getDiscoveryDialogInstance(); + discDialog.cancelSearch(); + } + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -131,18 +120,18 @@ public final class DiscoveryTopComponent extends TopComponent { private void initComponents() { mainSplitPane = new javax.swing.JSplitPane(); - rightSplitPane = new javax.swing.JSplitPane(); + rightSplitPane = new AnimatedSplitPane(); - setPreferredSize(new java.awt.Dimension(1400, 900)); + setMinimumSize(new java.awt.Dimension(199, 200)); + setPreferredSize(new java.awt.Dimension(1100, 700)); setLayout(new java.awt.BorderLayout()); - mainSplitPane.setDividerLocation(450); - mainSplitPane.setPreferredSize(new java.awt.Dimension(1400, 828)); + mainSplitPane.setDividerLocation(250); + mainSplitPane.setPreferredSize(new java.awt.Dimension(1100, 700)); - rightSplitPane.setDividerLocation(475); rightSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - rightSplitPane.setResizeWeight(0.5); - rightSplitPane.setPreferredSize(new java.awt.Dimension(1000, 828)); + rightSplitPane.setResizeWeight(1.0); + rightSplitPane.setPreferredSize(new java.awt.Dimension(800, 700)); mainSplitPane.setRightComponent(rightSplitPane); add(mainSplitPane, java.awt.BorderLayout.CENTER); @@ -159,10 +148,95 @@ public final class DiscoveryTopComponent extends TopComponent { .collect(Collectors.toList()); } + /** + * + * Fades this JPanel in. * + */ + @Subscribe + void handleDetailsVisibleEvent(DiscoveryEventUtils.DetailsVisibleEvent detailsVisibleEvent) { + if (animator != null && animator.isRunning()) { + animator.stop(); + } + if (detailsVisibleEvent.isShowDetailsArea()) { + animator = new SwingAnimator(new ShowDetailsAreaCallback()); + } else { + animator = new SwingAnimator(new HideDetailsAreaCallback()); + } + animator.start(); + } + /** + * + * Callback implementation for fading in + * + * @author Greg Cope + * + * + * + */ + private class ShowDetailsAreaCallback implements SwingAnimatorCallback { + + @Override + public void callback(Object caller) { + dividerLocation -= ANIMATION_INCREMENT; + repaint(); + } + + @Override + public boolean hasTerminated() { + if (dividerLocation <= RESULTS_AREA_SMALL_SIZE) { + dividerLocation = RESULTS_AREA_SMALL_SIZE; + return true; + } + return false; + } + + } + + /** + * + * Callback implementation to fade out + * + * @author Greg Cope + * + * + * + */ + private class HideDetailsAreaCallback implements SwingAnimatorCallback { + + @Override + public void callback(Object caller) { + dividerLocation += ANIMATION_INCREMENT; + repaint(); + } + + @Override + public boolean hasTerminated() { + if (dividerLocation >= rightSplitPane.getHeight()) { + dividerLocation = rightSplitPane.getHeight(); + return true; + } + return false; + } + + } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JSplitPane mainSplitPane; private javax.swing.JSplitPane rightSplitPane; // End of variables declaration//GEN-END:variables + private class AnimatedSplitPane extends JSplitPane { + + private static final long serialVersionUID = 1L; + + @Override + public void paintComponent(Graphics g) { + if (dividerLocation <= rightSplitPane.getHeight() && dividerLocation >= RESULTS_AREA_SMALL_SIZE) { + rightSplitPane.setDividerLocation(dividerLocation); + } + super.paintComponent(g); + } + + } + } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java b/Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java index 0a69539786..f72d25e22e 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/OpenDiscoveryAction.java @@ -1,7 +1,7 @@ /* * Autopsy * - * Copyright 2019 Basis Technology Corp. + * Copyright 2019-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -75,19 +75,10 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P @Override @SuppressWarnings("fallthrough") public void performAction() { - final DiscoveryDialog discDialog = new DiscoveryDialog(); + final DiscoveryDialog discDialog = DiscoveryDialog.getDiscoveryDialogInstance(); + discDialog.cancelSearch(); discDialog.setVisible(true); -// final DiscoveryTopComponent tc = DiscoveryTopComponent.getTopComponent(); -// if (tc != null) { -// if (tc.isOpened() == false) { -// tc.open(); -// tc.updateSearchSettings(); -// displayErrorMessage(tc); -// } -// tc.toFront(); -// tc.requestActive(); -// -// } + displayErrorMessage(discDialog); } /** @@ -96,7 +87,7 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P * * @param tc The Discovery Top component. */ - private void displayErrorMessage(DiscoveryTopComponent tc) { + private void displayErrorMessage(DiscoveryDialog discDialog) { //check if modules run and assemble message try { SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); @@ -113,7 +104,7 @@ public final class OpenDiscoveryAction extends CallableSystemAction implements P message += dsmodulesWrapper.getMessage(); } if (!message.isEmpty()) { - JOptionPane.showMessageDialog(tc, message, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog(discDialog, message, Bundle.OpenDiscoveryAction_resultsIncomplete_text(), JOptionPane.INFORMATION_MESSAGE); } } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.WARNING, "Exception while determining which modules have been run for Discovery", ex); diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form index 407e17c946..723888f04f 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.form @@ -2,8 +2,11 @@ + + + - + @@ -18,24 +21,7 @@ - - - - - - - - - - - - - - - - - - + @@ -44,11 +30,22 @@ + + + + + + + + + + + @@ -310,114 +307,22 @@ - + - - - - + + - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java index 7bd732d18a..3a82dd8d47 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ResultsPanel.java @@ -19,44 +19,25 @@ package org.sleuthkit.autopsy.discovery; import com.google.common.eventbus.Subscribe; -import java.awt.Component; import java.awt.Image; import java.awt.event.ItemEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListCellRenderer; -import javax.swing.DefaultListModel; -import javax.swing.JList; import javax.swing.JOptionPane; -import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.actions.AddContentTagAction; -import org.sleuthkit.autopsy.actions.DeleteFileContentTagAction; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.datamodel.FileNode; -import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; -import org.sleuthkit.autopsy.directorytree.ViewContextAction; -import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.autopsy.discovery.FileSearch.GroupKey; -import org.sleuthkit.autopsy.modules.hashdatabase.AddContentToHashDbAction; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.textsummarizer.TextSummary; -import java.awt.Graphics; /** * Panel for displaying of Discovery results and handling the paging of those @@ -80,16 +61,6 @@ public class ResultsPanel extends javax.swing.JPanel { private int groupSize = 0; private PageWorker pageWorker; private final List> resultContentWorkers = new ArrayList<>(); - private final DefaultListModel instancesListModel = new DefaultListModel<>(); - private ListSelectionListener listener = null; - - private int dividerLocation = 1; - - private static final int ANIMATION_INCREMENT = 10; - - private SwingAnimator fadeInAnimator = null; - - private SwingAnimator fadeOutAnimator = null; /** * Creates new form ResultsPanel. @@ -104,108 +75,42 @@ public class ResultsPanel extends javax.swing.JPanel { videoThumbnailViewer.addListSelectionListener((e) -> { if (resultType == FileSearchData.FileType.VIDEO) { if (!e.getValueIsAdjusting()) { - populateInstancesList(); + //send populateMesage + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected())); } else { - instancesList.clearSelection(); + //send clearSelection message + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent()); } } }); imageThumbnailViewer.addListSelectionListener((e) -> { if (resultType == FileSearchData.FileType.IMAGE) { if (!e.getValueIsAdjusting()) { - populateInstancesList(); + List files = getInstancesForSelected(); + //send populateMesage + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected())); } else { - instancesList.clearSelection(); + //send clearSelection message + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent()); } + } }); documentPreviewViewer.addListSelectionListener((e) -> { if (resultType == FileSearchData.FileType.DOCUMENTS) { if (!e.getValueIsAdjusting()) { - populateInstancesList(); + List files = getInstancesForSelected(); + //send populateMesage + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected())); } else { - instancesList.clearSelection(); - } - } - }); - //Add the context menu when right clicking - instancesList.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isRightMouseButton(e)) { - SwingUtilities.invokeLater(() -> { - instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint())); - Set files = new HashSet<>(); - files.add(instancesList.getSelectedValue()); - JPopupMenu menu = new JPopupMenu(); - menu.add(new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue())); - menu.add(new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(), new FileNode(instancesList.getSelectedValue()))); - menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue())); - menu.add(new DiscoveryExtractAction(files)); - menu.add(AddContentTagAction.getInstance().getMenuForContent(files)); - menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files)); - menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files)); - menu.show(instancesList, e.getPoint().x, e.getPoint().y); - }); + //send clearSelection message + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.ClearInstanceSelectionEvent()); } } }); } - /** - * Add a list selection listener to the instances list. - * - * @param listener The ListSelectionListener to add to the instances list. - */ - void addListSelectionListener(ListSelectionListener newListener) { - instancesList.removeListSelectionListener(listener); - listener = newListener; - instancesList.addListSelectionListener(listener); - } - - /** - * Populate the instances list. - */ - synchronized void populateInstancesList() { - SwingUtilities.invokeLater(() -> { - List files = getInstancesForSelected(); - if (files.isEmpty()) { - //if there are no files currently remove the current items without removing listener to cause content viewer to reset - instancesListModel.removeAllElements(); - fadeOut(); - } else { - //remove listener so content viewer node is not set multiple times - instancesList.removeListSelectionListener(listener); - instancesListModel.removeAllElements(); - for (AbstractFile file : files) { - instancesListModel.addElement(file); - } - //add listener back to allow selection of first index to cause content viewer node to be set - instancesList.addListSelectionListener(listener); - if (!instancesListModel.isEmpty()) { - instancesList.setSelectedIndex(0); - } - fadeIn(); - } - }); - } - - - /** - * Get the AbstractFile for the item currently selected in the instances - * list. - * - * @return The AbstractFile which is currently selected. - */ - synchronized AbstractFile getSelectedFile() { - if (instancesList.getSelectedIndex() == -1) { - return null; - } else { - return instancesListModel.getElementAt(instancesList.getSelectedIndex()); - } - } - /** * Get the list of all instances for the the currently selected item in the * results viewer area. @@ -237,7 +142,9 @@ public class ResultsPanel extends javax.swing.JPanel { @Subscribe void handlePageRetrievedEvent(DiscoveryEventUtils.PageRetrievedEvent pageRetrievedEvent) { SwingUtilities.invokeLater(() -> { - populateInstancesList(); + //send populateMesage + DiscoveryEventUtils.getDiscoveryEventBus().post(new DiscoveryEventUtils.PopulateInstancesListEvent(getInstancesForSelected())); + currentPage = pageRetrievedEvent.getPageNumber(); updateControls(); resetResultViewer(); @@ -437,15 +344,15 @@ public class ResultsPanel extends javax.swing.JPanel { javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); - resultsSplitPane = new javax.swing.JSplitPane(); - javax.swing.JPanel instancesPanel = new javax.swing.JPanel(); - javax.swing.JScrollPane instancesScrollPane = new javax.swing.JScrollPane(); - instancesList = new javax.swing.JList<>(); resultsViewerPanel = new javax.swing.JPanel(); - setPreferredSize(new java.awt.Dimension(777, 475)); + setMinimumSize(new java.awt.Dimension(700, 200)); + setPreferredSize(new java.awt.Dimension(700, 700)); + setLayout(new java.awt.BorderLayout()); pagingPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + pagingPanel.setMinimumSize(new java.awt.Dimension(400, 39)); + pagingPanel.setPreferredSize(new java.awt.Dimension(700, 39)); pagingPanel.setLayout(new java.awt.GridBagLayout()); previousPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N @@ -592,61 +499,12 @@ public class ResultsPanel extends javax.swing.JPanel { gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; pagingPanel.add(filler4, gridBagConstraints); - resultsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); - resultsSplitPane.setResizeWeight(1.0); - resultsSplitPane.setToolTipText(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.resultsSplitPane.toolTipText")); // NOI18N - resultsSplitPane.setOpaque(false); - resultsSplitPane.setPreferredSize(new java.awt.Dimension(777, 440)); + add(pagingPanel, java.awt.BorderLayout.PAGE_START); - instancesPanel.setPreferredSize(new java.awt.Dimension(775, 68)); - - instancesScrollPane.setPreferredSize(new java.awt.Dimension(775, 60)); - - instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ResultsPanel.class, "ResultsPanel.instancesList.border.title"))); // NOI18N - instancesList.setModel(instancesListModel); - instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - instancesList.setCellRenderer(new InstancesCellRenderer()); - instancesList.setVisibleRowCount(2); - instancesScrollPane.setViewportView(instancesList); - - javax.swing.GroupLayout instancesPanelLayout = new javax.swing.GroupLayout(instancesPanel); - instancesPanel.setLayout(instancesPanelLayout); - instancesPanelLayout.setHorizontalGroup( - instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 779, Short.MAX_VALUE) - .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - instancesPanelLayout.setVerticalGroup( - instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 433, Short.MAX_VALUE) - .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup() - .addGap(0, 0, 0) - .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 433, Short.MAX_VALUE))) - ); - - resultsSplitPane.setRightComponent(instancesPanel); - - resultsViewerPanel.setPreferredSize(new java.awt.Dimension(0, 380)); + resultsViewerPanel.setMinimumSize(new java.awt.Dimension(0, 160)); + resultsViewerPanel.setPreferredSize(new java.awt.Dimension(700, 700)); resultsViewerPanel.setLayout(new java.awt.BorderLayout()); - resultsSplitPane.setLeftComponent(resultsViewerPanel); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(pagingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(resultsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE) - .addGap(0, 0, 0)) - ); + add(resultsViewerPanel, java.awt.BorderLayout.CENTER); }// //GEN-END:initComponents /** @@ -729,11 +587,9 @@ public class ResultsPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel currentPageLabel; private javax.swing.JTextField gotoPageField; - private javax.swing.JList instancesList; private javax.swing.JButton nextPageButton; private javax.swing.JComboBox pageSizeComboBox; private javax.swing.JButton previousPageButton; - private javax.swing.JSplitPane resultsSplitPane; private javax.swing.JPanel resultsViewerPanel; // End of variables declaration//GEN-END:variables @@ -864,179 +720,4 @@ public class ResultsPanel extends javax.swing.JPanel { } - /** - * Cell renderer for the instances list. - */ - private class InstancesCellRenderer extends DefaultListCellRenderer { - - private static final long serialVersionUID = 1L; - - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - String name = ""; - if (value instanceof AbstractFile) { - AbstractFile file = (AbstractFile) value; - try { - name = file.getUniquePath(); - } catch (TskCoreException ingored) { - name = file.getParentPath() + "/" + file.getName(); - } - - } - setText(name); - return this; - } - - } - - /** - * - * Sets the alpha value - * - * @param a - * - */ - public void setDividerLocation(int a) { - - this.dividerLocation = a; - - } - - /** - * - * Fades this JPanel in. * - */ - public void fadeIn() { - - stop(); - - fadeInAnimator = new SwingAnimator(new FadeInCallback()); - - fadeInAnimator.start(); - - } - - /** - * - * Fades this JPanel out - * - */ - public void fadeOut() { - - stop(); - - fadeOutAnimator = new SwingAnimator(new FadeOutCallback()); - - fadeOutAnimator.start(); - - } - - /** - * - * Stops all animators. * - */ - private void stop() { - - if (fadeOutAnimator != null && fadeOutAnimator.isRunning()) { - - fadeOutAnimator.stop(); - - } - - if (fadeInAnimator != null && fadeInAnimator.isRunning()) { - - fadeInAnimator.stop(); - - } - - } - - @Override - public void paintComponent(Graphics g) { - - if (dividerLocation <= resultsSplitPane.getHeight() && dividerLocation >= (resultsSplitPane.getHeight() - 100)) { - resultsSplitPane.setDividerLocation(dividerLocation); - } - - super.paintComponent(g); - - } - - /** - * - * Callback implementation for fading in - * - * @author Greg Cope - * - * - * - */ - private class FadeInCallback implements SwingAnimatorCallback { - - @Override - - public void callback(Object caller) { - - dividerLocation -= ANIMATION_INCREMENT; - - repaint(); - - } - - @Override - - public boolean hasTerminated() { - - if (dividerLocation <= (resultsSplitPane.getHeight() - 100)) { - - dividerLocation = resultsSplitPane.getHeight() - 100; - System.out.println("FADE IN COMPLETE"); - return true; - - } - - return false; - - } - - } - - /** - * - * Callback implementation to fade out - * - * @author Greg Cope - * - * - * - */ - private class FadeOutCallback implements SwingAnimatorCallback { - - @Override - - public void callback(Object caller) { - - dividerLocation += ANIMATION_INCREMENT; - - repaint(); - - } - - @Override - - public boolean hasTerminated() { - - if (dividerLocation >= resultsSplitPane.getHeight()) { - - dividerLocation = resultsSplitPane.getHeight(); - System.out.println("FADE OUT COMPLETE"); - return true; - } - - return false; - } - - } - }