From ab3bf74e9c892a014d915db1fcd65a2cde7211d4 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 19 Mar 2021 09:51:33 -0400 Subject: [PATCH] 7328 checkbox list with existing class --- .../ui/AbstractDiscoveryFilterPanel.java | 43 +++-- .../discovery/ui/AbstractFiltersPanel.java | 6 +- .../discovery/ui/ArtifactTypeFilterPanel.form | 28 +--- .../discovery/ui/ArtifactTypeFilterPanel.java | 114 +++++-------- .../autopsy/discovery/ui/Bundle.properties | 2 + .../discovery/ui/Bundle.properties-MERGED | 3 + .../discovery/ui/CheckBoxCellRenderer.java | 48 ------ .../ui/CheckboxListSelectionModel.java | 133 --------------- .../discovery/ui/DataSourceFilterPanel.form | 57 +++---- .../discovery/ui/DataSourceFilterPanel.java | 151 ++++++++++-------- .../autopsy/discovery/ui/DateFilterPanel.java | 27 +++- .../discovery/ui/HashSetFilterPanel.form | 27 +--- .../discovery/ui/HashSetFilterPanel.java | 76 +++++---- .../ui/InterestingItemsFilterPanel.form | 32 +--- .../ui/InterestingItemsFilterPanel.java | 80 ++++++---- .../ui/KnownAccountTypeFilterPanel.java | 30 +++- .../ui/ObjectDetectedFilterPanel.form | 36 +---- .../ui/ObjectDetectedFilterPanel.java | 87 +++++----- .../discovery/ui/ParentFolderFilterPanel.java | 28 +++- .../ui/PastOccurrencesFilterPanel.form | 35 +--- .../ui/PastOccurrencesFilterPanel.java | 82 ++++++---- .../ui/PreviouslyNotableFilterPanel.form | 6 - .../ui/PreviouslyNotableFilterPanel.java | 27 +++- .../autopsy/discovery/ui/SizeFilterPanel.form | 38 +---- .../autopsy/discovery/ui/SizeFilterPanel.java | 83 ++++++---- .../discovery/ui/UserCreatedFilterPanel.java | 27 +++- .../autopsy/guiutils/CheckBoxListPanel.java | 25 ++- 27 files changed, 563 insertions(+), 768 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/discovery/ui/CheckBoxCellRenderer.java delete mode 100644 Core/src/org/sleuthkit/autopsy/discovery/ui/CheckboxListSelectionModel.java diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java index 7fc964ad52..45d8394568 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractDiscoveryFilterPanel.java @@ -25,6 +25,7 @@ import javax.swing.JLabel; import javax.swing.JList; import javax.swing.event.ListSelectionListener; import org.sleuthkit.autopsy.coreutils.ThreadConfined; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; /** * Abstract class extending JPanel for filter controls. @@ -54,14 +55,20 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel { abstract JCheckBox getCheckbox(); /** - * Get the list of values associated with this filter if one exists. If one - * does not exist this should return null. + * Get the array of list selection listeners associated with this filter. If + * a list does not exist this should return null. * - * @return The JList which contains the values available for selection for - * this filter. + * @return The array which contains the list selection listeners for this + * panel. */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - abstract JList getList(); + abstract ListSelectionListener[] getListSelectionListeners(); + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + abstract void addListSelectionListener(ListSelectionListener listener); + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + abstract void removeListSelectionListener(ListSelectionListener listener); /** * Get any additional text that should be displayed under the checkbox. If @@ -93,8 +100,8 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel { if (getCheckbox() != null) { getCheckbox().addActionListener(actionListener); } - if (getList() != null) { - getList().addListSelectionListener(listListener); + if (getListSelectionListeners() != null) { + addListSelectionListener(listListener); } } @@ -117,13 +124,25 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel { getCheckbox().removeActionListener(listener); } } - if (getList() != null) { - for (ListSelectionListener listener : getList().getListSelectionListeners()) { - getList().removeListSelectionListener(listener); - } - } + /* + * Should be overridden if a list is present and have something allong + * the lines of the following added after a call to the super. + * + * if (list != null) { for (ListSelectionListener listener : + * list.getListSelectionListeners()) { + * list.removeListSelectionListener(listener); } } + */ } + /** + * Get whether or not the filter has sufficient options to be used. + */ + abstract boolean isFilterSupported(); + + /** + * + */ + /** * Return whether or not this filter has a panel. * diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java index 44e6446d49..01839ca5c3 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/AbstractFiltersPanel.java @@ -228,7 +228,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li boolean isObjectsFilterSupported() { for (AbstractDiscoveryFilterPanel filter : filters) { if (filter instanceof ObjectDetectedFilterPanel) { - return filter.getList().getModel().getSize() > 0; + return filter.isFilterSupported(); } } return false; @@ -243,7 +243,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li boolean isHashSetFilterSupported() { for (AbstractDiscoveryFilterPanel filter : filters) { if (filter instanceof HashSetFilterPanel) { - return filter.getList().getModel().getSize() > 0; + return filter.isFilterSupported(); } } return false; @@ -258,7 +258,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li boolean isInterestingItemsFilterSupported() { for (AbstractDiscoveryFilterPanel filter : filters) { if (filter instanceof InterestingItemsFilterPanel) { - return filter.getList().getModel().getSize() > 0; + return filter.isFilterSupported(); } } return false; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form index e0d00591cc..9e9189ec68 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.form @@ -33,37 +33,13 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java index 7e9eed109a..6fcbb64195 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ArtifactTypeFilterPanel.java @@ -18,25 +18,25 @@ */ package org.sleuthkit.autopsy.discovery.ui; -import java.util.ArrayList; import java.util.List; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; -import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.SearchFiltering.ArtifactTypeFilter; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; import org.sleuthkit.datamodel.BlackboardArtifact; /** * Filter for selection of a specific Artifact type to limit results to. */ -class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { +final class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; + private static final CheckBoxListPanel artifactList = new CheckBoxListPanel<>(); /** * Creates new form ArtifactTypeFilterPanel @@ -45,7 +45,7 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { ArtifactTypeFilterPanel() { initComponents(); setUpArtifactTypeFilter(); - + add(artifactList); } /** @@ -53,12 +53,9 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpArtifactTypeFilter() { - int count = 0; - DefaultListModel artifactTypeModel = (DefaultListModel) artifactList.getModel(); - artifactTypeModel.removeAllElements(); + artifactList.clearList(); for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SearchData.Type.DOMAIN.getArtifactTypes()) { - artifactTypeModel.add(count, new ArtifactTypeItem(artifactType)); - count++; + artifactList.addElement(artifactType.getDisplayName(), null, artifactType); } } @@ -72,8 +69,6 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { artifactTypeCheckbox = new javax.swing.JCheckBox(); - artifactTypeScrollPane = new javax.swing.JScrollPane(); - artifactList = new javax.swing.JList<>(); org.openide.awt.Mnemonics.setLocalizedText(artifactTypeCheckbox, org.openide.util.NbBundle.getMessage(ArtifactTypeFilterPanel.class, "ArtifactTypeFilterPanel.artifactTypeCheckbox.text")); // NOI18N artifactTypeCheckbox.addActionListener(new java.awt.event.ActionListener() { @@ -84,26 +79,19 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { setPreferredSize(new java.awt.Dimension(27, 27)); - artifactTypeScrollPane.setPreferredSize(new java.awt.Dimension(27, 27)); - - artifactList.setModel(new DefaultListModel()); - artifactList.setEnabled(false); - artifactTypeScrollPane.setViewportView(artifactList); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(artifactTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 27, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(artifactTypeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 27, Short.MAX_VALUE) ); }// //GEN-END:initComponents private void artifactTypeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_artifactTypeCheckboxActionPerformed - artifactTypeScrollPane.setEnabled(artifactTypeCheckbox.isSelected()); artifactList.setEnabled(artifactTypeCheckbox.isSelected()); }//GEN-LAST:event_artifactTypeCheckboxActionPerformed @@ -112,13 +100,11 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { void configurePanel(boolean selected, int[] indicesSelected) { artifactTypeCheckbox.setSelected(selected); if (artifactTypeCheckbox.isEnabled() && artifactTypeCheckbox.isSelected()) { - artifactTypeScrollPane.setEnabled(true); artifactList.setEnabled(true); - if (indicesSelected != null) { - artifactList.setSelectedIndices(indicesSelected); - } +// if (indicesSelected != null) { +// artifactList.setSelectedIndices(indicesSelected); +// } } else { - artifactTypeScrollPane.setEnabled(false); artifactList.setEnabled(false); } } @@ -129,12 +115,6 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { return artifactTypeCheckbox; } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - @Override - JList getList() { - return artifactList; - } - @Override JLabel getAdditionalLabel() { return null; @@ -144,7 +124,7 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { @NbBundle.Messages({"ArtifactTypeFilterPanel.selectionNeeded.text=At least one Result type must be selected."}) @Override String checkForError() { - if (artifactTypeCheckbox.isSelected() && artifactList.getSelectedValuesList().isEmpty()) { + if (artifactTypeCheckbox.isSelected() && artifactList.getSelectedElements().isEmpty()) { return Bundle.ArtifactTypeFilterPanel_selectionNeeded_text(); } return ""; @@ -153,52 +133,46 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { - if (artifactTypeCheckbox.isSelected() && !artifactList.getSelectedValuesList().isEmpty()) { - List artifactTypeList = new ArrayList<>(); - for (ArtifactTypeItem item : artifactList.getSelectedValuesList()) { - artifactTypeList.add(item.getArtifactType()); - } + if (artifactTypeCheckbox.isSelected() && isFilterSupported()) { + List artifactTypeList = artifactList.getSelectedElements(); return new ArtifactTypeFilter(artifactTypeList); } return null; } - /** - * Utility class to allow us to display the AritfactType display name - * instead of the name. - */ - private class ArtifactTypeItem extends JCheckBox { - - private static final long serialVersionUID = 1L; - private final BlackboardArtifact.ARTIFACT_TYPE artifactType; - - /** - * Construct a new ArtifactTypeItem. - * - * @param ds The artifact type being wrapped. - */ - ArtifactTypeItem(BlackboardArtifact.ARTIFACT_TYPE artifactType) { - this.artifactType = artifactType; - } - - /** - * Get the ArtifactType represented by this ArtifactTypeItem. - * - * @return The ArtifactType represented by this ArtifactTypeItem. - */ - BlackboardArtifact.ARTIFACT_TYPE getArtifactType() { - return artifactType; - } - - @Override - public String toString() { - return artifactType.getDisplayName(); + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + @Override + void removeListeners() { + super.removeListeners(); + if (artifactList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + artifactList.removeListSelectionListener(listener); + } } } + @Override + ListSelectionListener[] getListSelectionListeners() { + return artifactList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + artifactList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + artifactList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return !artifactList.isEmpty(); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JList artifactList; private javax.swing.JCheckBox artifactTypeCheckbox; - private javax.swing.JScrollPane artifactTypeScrollPane; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties index 05913b59e4..4091fd984b 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties @@ -61,3 +61,5 @@ CookieDetailsPanel.jLabel2.text= PreviouslyNotableFilterPanel.text_1=Include only previously notable domains KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel +DataSourceFilterPanel.deselectAllButton.text=Deselect All +DataSourceFilterPanel.selectAllButton.text=Select All diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED index f24ec80db6..2140d16125 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/Bundle.properties-MERGED @@ -54,6 +54,7 @@ DocumentPanel.numberOfImages.noImages=No images DocumentPanel.numberOfImages.text=1 of {0} images DocumentWrapper.previewInitialValue=Preview not generated yet. DomainDetailsPanel.miniTimelineTitle.text=Timeline +DomainDetailsPanel.otherOccurrencesTab.title=Other Occurrences # {0} - startDate # {1} - endDate DomainSummaryPanel.activity.text=Activity: {0} to {1} @@ -174,6 +175,8 @@ CookieDetailsPanel.jLabel2.text= PreviouslyNotableFilterPanel.text_1=Include only previously notable domains KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel +DataSourceFilterPanel.deselectAllButton.text=Deselect All +DataSourceFilterPanel.selectAllButton.text=Select All VideoThumbnailPanel.bytes.text=bytes VideoThumbnailPanel.deleted.text=All instances of file are deleted. VideoThumbnailPanel.gigaBytes.text=GB diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/CheckBoxCellRenderer.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/CheckBoxCellRenderer.java deleted file mode 100644 index d25ae5ec5e..0000000000 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/CheckBoxCellRenderer.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Autopsy - * - * Copyright 2021 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.ui; - -import java.awt.Color; -import java.awt.Component; -import javax.swing.JCheckBox; -import javax.swing.JList; -import javax.swing.ListCellRenderer; - -class CheckboxCellRenderer implements ListCellRenderer { - private final JCheckBox checkboxToEnableList; - - - CheckboxCellRenderer(JCheckBox checkboxToEnableList){ - this.checkboxToEnableList = checkboxToEnableList; - } - - @Override - public Component getListCellRendererComponent(JList list, JCheckBox value, int index, boolean isSelected, boolean cellHasFocus) { - value.setEnabled(checkboxToEnableList.isSelected()); - Color background; - if (value.isSelected()) { - background = list.getSelectionBackground(); - } else { - background = list.getBackground(); - } - value.setBackground(background); - return value; - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/CheckboxListSelectionModel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/CheckboxListSelectionModel.java deleted file mode 100644 index 19fed95863..0000000000 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/CheckboxListSelectionModel.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Autopsy - * - * Copyright 2021 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.ui; - -import javax.swing.DefaultListSelectionModel; -import javax.swing.JCheckBox; - -final class CheckboxListSelectionModel extends DefaultListSelectionModel { - - private final javax.swing.JList list; - - CheckboxListSelectionModel(javax.swing.JList list) { - this.list = list; - } - - private static final long serialVersionUID = 1L; - - @Override - public void setSelectionInterval(int index0, int index1) { - setAnchorSelectionIndex(index0); - setLeadSelectionIndex(index1); - for (int i = 0; i < list.getModel().getSize(); i++) { - list.getModel().getElementAt(index1).setSelected(i >= index0 && i <= index1); - } - } - - @Override - public void addSelectionInterval(int index0, int index1) { - setAnchorSelectionIndex(index0); - setLeadSelectionIndex(index1); - for (int i = 0; i < list.getModel().getSize(); i++) { - if (i >= index0 && i <= index1) { - list.getModel().getElementAt(i).setSelected(true); - } - } - } - - @Override - public void removeSelectionInterval(int index0, int index1) { - setAnchorSelectionIndex(index0); - setLeadSelectionIndex(index1); - for (int i = 0; i < list.getModel().getSize(); i++) { - if (i >= index0 && i < index1) { - list.getModel().getElementAt(i).setSelected(false); - } - } - } - - @Override - public int getMinSelectionIndex() { - for (int i = 0; i < list.getModel().getSize(); i++) { - if (list.getModel().getElementAt(i).isSelected()) { - return i; - } - } - return -1; - } - - @Override - public int getMaxSelectionIndex() { - for (int i = list.getModel().getSize() - 1; i >= 0; i--) { - if (list.getModel().getElementAt(i).isSelected()) { - return i; - } - } - return -1; - } - - @Override - public boolean isSelectedIndex(int index) { - return list.getModel().getElementAt(index).isSelected(); - } - - @Override - public void clearSelection() { - for (int i = 0; i < list.getModel().getSize(); i++) { - list.getModel().getElementAt(i).setSelected(false); - } - } - - @Override - public boolean isSelectionEmpty() { - boolean isEmpty = true; - for (int i = 0; i < list.getModel().getSize(); i++) { - if (list.getModel().getElementAt(i).isSelected()) { - isEmpty = false; - break; - } - } - return isEmpty; - } - - @Override - public void insertIndexInterval(int index, int length, boolean before) { - for (int i = 0; i < list.getModel().getSize(); i++) { - if (i >= index && i < index + length) { - list.getModel().getElementAt(i).setSelected(true); - } - } - - } - - @Override - public void removeIndexInterval(int index0, int index1) { - for (int i = 0; i < list.getModel().getSize(); i++) { - if (i >= index0 && i < index1) { - list.getModel().getElementAt(i).setSelected(false); - } - } - } - - @Override - public Object clone() throws CloneNotSupportedException { - return super.clone(); //To change body of generated methods, choose Tools | Templates. - } - -} diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form index 3f2a9d4a1d..ee08bbbf33 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.form @@ -27,7 +27,7 @@ - + @@ -46,44 +46,47 @@ - + + + + + + - - + + + + + + - + - - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java index a5e903526f..3073b3bb2c 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DataSourceFilterPanel.java @@ -22,16 +22,15 @@ import java.util.Collections; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; -import java.util.stream.Collectors; -import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; @@ -42,6 +41,7 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; private final static Logger logger = Logger.getLogger(DataSourceFilterPanel.class.getName()); + private final CheckBoxListPanel dataSourceCheckBoxList = new CheckBoxListPanel<>(); /** * Creates new form DataSourceFilterPanel. @@ -50,8 +50,7 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel { DataSourceFilterPanel() { initComponents(); setUpDataSourceFilter(); - dataSourceList.setCellRenderer(new CheckboxCellRenderer(dataSourceCheckbox)); - dataSourceList.setSelectionModel(new CheckboxListSelectionModel(dataSourceList)); + add(dataSourceCheckBoxList); } /** @@ -63,8 +62,8 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { dataSourceCheckbox = new javax.swing.JCheckBox(); - dataSourceScrollPane = new javax.swing.JScrollPane(); - dataSourceList = new javax.swing.JList<>(); + selectAllButton = new javax.swing.JButton(); + deselectAllButton = new javax.swing.JButton(); org.openide.awt.Mnemonics.setLocalizedText(dataSourceCheckbox, org.openide.util.NbBundle.getMessage(DataSourceFilterPanel.class, "DataSourceFilterPanel.dataSourceCheckbox.text")); // NOI18N dataSourceCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); @@ -77,39 +76,69 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel { }); setMinimumSize(new java.awt.Dimension(250, 30)); - setPreferredSize(new java.awt.Dimension(250, 30)); + setPreferredSize(new java.awt.Dimension(250, 50)); setRequestFocusEnabled(false); - dataSourceScrollPane.setPreferredSize(new java.awt.Dimension(27, 27)); + org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(DataSourceFilterPanel.class, "DataSourceFilterPanel.selectAllButton.text")); // NOI18N + selectAllButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + selectAllButtonActionPerformed(evt); + } + }); - dataSourceList.setModel(new DefaultListModel()); - dataSourceList.setEnabled(false); - dataSourceList.setVisibleRowCount(5); - dataSourceScrollPane.setViewportView(dataSourceList); + org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(DataSourceFilterPanel.class, "DataSourceFilterPanel.deselectAllButton.text")); // NOI18N + deselectAllButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deselectAllButtonActionPerformed(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(dataSourceScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(selectAllButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(deselectAllButton) + .addGap(0, 45, Short.MAX_VALUE)) ); + + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deselectAllButton, selectAllButton}); + layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(dataSourceScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 0, 0)) + .addContainerGap(19, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(selectAllButton) + .addComponent(deselectAllButton)) + .addGap(6, 6, 6)) ); + + layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {deselectAllButton, selectAllButton}); + }// //GEN-END:initComponents private void dataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourceCheckboxActionPerformed - dataSourceList.setEnabled(dataSourceCheckbox.isSelected()); + dataSourceCheckBoxList.setEnabled(dataSourceCheckbox.isSelected()); + selectAllButton.setEnabled(dataSourceCheckbox.isSelected()); + deselectAllButton.setEnabled(dataSourceCheckbox.isSelected()); }//GEN-LAST:event_dataSourceCheckboxActionPerformed + private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed + dataSourceCheckBoxList.setSetAllSelected(true); + }//GEN-LAST:event_selectAllButtonActionPerformed + + private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed + dataSourceCheckBoxList.setSetAllSelected(false); + }//GEN-LAST:event_deselectAllButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox dataSourceCheckbox; - private javax.swing.JList dataSourceList; - private javax.swing.JScrollPane dataSourceScrollPane; + private javax.swing.JButton deselectAllButton; + private javax.swing.JButton selectAllButton; // End of variables declaration//GEN-END:variables @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @@ -117,14 +146,12 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel { void configurePanel(boolean selected, int[] indicesSelected) { dataSourceCheckbox.setSelected(selected); if (dataSourceCheckbox.isEnabled() && dataSourceCheckbox.isSelected()) { - dataSourceScrollPane.setEnabled(true); - dataSourceList.setEnabled(true); - if (indicesSelected != null) { - dataSourceList.setSelectedIndices(indicesSelected); - } + dataSourceCheckBoxList.setEnabled(true); +// if (indicesSelected != null) { +// dataSourceCheckBoxList.setSelectedIndices(indicesSelected); +// } } else { - dataSourceScrollPane.setEnabled(false); - dataSourceList.setEnabled(false); + dataSourceCheckBoxList.setEnabled(false); } } @@ -144,81 +171,67 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpDataSourceFilter() { - int count = 0; try { - DefaultListModel dsListModel = (DefaultListModel) dataSourceList.getModel(); - dsListModel.removeAllElements(); + dataSourceCheckBoxList.clearList(); List dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources(); Collections.sort(dataSources, (DataSource ds1, DataSource ds2) -> ds1.getName().compareToIgnoreCase(ds2.getName())); for (DataSource ds : dataSources) { - dsListModel.add(count, new DataSourceItem(ds)); - count++; + dataSourceCheckBoxList.addElement(ds.getName() + " (ID: " + ds.getId() + ")", null, ds); } } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error loading data sources", ex); dataSourceCheckbox.setEnabled(false); - dataSourceList.setEnabled(false); + dataSourceCheckBoxList.setEnabled(false); } } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - JList getList() { - return dataSourceList; + ListSelectionListener[] getListSelectionListeners() { + return dataSourceCheckBoxList.getListSelectionListeners(); } - /** - * Utility class to allow us to display the data source ID along with the - * name - */ - private final class DataSourceItem extends javax.swing.JCheckBox { + @Override + void addListSelectionListener(ListSelectionListener listener) { + dataSourceCheckBoxList.addListSelectionListener(listener); + } - private static final long serialVersionUID = 1L; + @Override + void removeListSelectionListener(ListSelectionListener listener) { + dataSourceCheckBoxList.removeListSelectionListener(listener); + } - private final DataSource ds; - - /** - * Construct a new DataSourceItem. - * - * @param ds The data source being wrapped. - */ - DataSourceItem(DataSource ds) { - super(ds.getName() + " (ID: " + ds.getId() + ")"); - this.ds = ds; - } - - /** - * Get the data source represented by this data source item. - * - * @return The data source represented by this data source item. - */ - DataSource getDataSource() { - return ds; - } - - @Override - public String toString() { - return ds.getName() + " (ID: " + ds.getId() + ")"; - } - + @Override + boolean isFilterSupported() { + return !dataSourceCheckBoxList.isEmpty(); } @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @NbBundle.Messages({"DataSourceFilterPanel.error.text=At least one data source must be selected."}) @Override String checkForError() { - if (dataSourceCheckbox.isSelected() && dataSourceList.getSelectedValuesList().isEmpty()) { + if (dataSourceCheckbox.isSelected() && dataSourceCheckBoxList.getSelectedElements().isEmpty()) { return Bundle.DataSourceFilterPanel_error_text(); } return ""; } + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + @Override + void removeListeners() { + super.removeListeners(); + if (dataSourceCheckBoxList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + dataSourceCheckBoxList.removeListSelectionListener(listener); + } + } + } + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { if (dataSourceCheckbox.isSelected()) { - List dataSources = dataSourceList.getSelectedValuesList().stream().map(t -> t.getDataSource()).collect(Collectors.toList()); + List dataSources = dataSourceCheckBoxList.getSelectedElements(); return new SearchFiltering.DataSourceFilter(dataSources); } return null; diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java index d2cc07c790..fc66965b07 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/DateFilterPanel.java @@ -29,7 +29,6 @@ import java.util.logging.Level; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; import javax.swing.JSpinner; import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; @@ -38,7 +37,6 @@ import org.sleuthkit.autopsy.communications.Utils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; -import org.sleuthkit.datamodel.TimelineManager; import org.sleuthkit.datamodel.TskCoreException; /** @@ -253,11 +251,6 @@ class DateFilterPanel extends AbstractDiscoveryFilterPanel { return dateFilterCheckBox; } - @Override - JList getList() { - return null; - } - @Override JLabel getAdditionalLabel() { return null; @@ -372,4 +365,24 @@ class DateFilterPanel extends AbstractDiscoveryFilterPanel { private javax.swing.JCheckBox startCheckBox; private com.github.lgooddatepicker.components.DatePicker startDatePicker; // End of variables declaration//GEN-END:variables + + @Override + ListSelectionListener[] getListSelectionListeners() { + return null; + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + boolean isFilterSupported() { + return true; + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form index 56c033db74..a5243941dc 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.form @@ -45,36 +45,13 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java index 0257352a16..631e4cdb5a 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/HashSetFilterPanel.java @@ -21,14 +21,14 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; -import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; @@ -40,6 +40,7 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; private final static Logger logger = Logger.getLogger(HashSetFilterPanel.class.getName()); + private static final CheckBoxListPanel hashSetList = new CheckBoxListPanel<>(); /** * Creates new form HashSetFilterPaenl. @@ -48,6 +49,7 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { HashSetFilterPanel() { initComponents(); setUpHashFilter(); + add(hashSetList); } /** @@ -55,15 +57,12 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpHashFilter() { - int count = 0; try { - DefaultListModel hashListModel = (DefaultListModel) hashSetList.getModel(); - hashListModel.removeAllElements(); + hashSetList.clearList(); List setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME); for (String name : setNames) { - hashListModel.add(count, name); - count++; + hashSetList.addElement(name, null, name); } } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error loading hash set names", ex); @@ -82,8 +81,6 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { hashSetCheckbox = new javax.swing.JCheckBox(); - hashSetScrollPane = new javax.swing.JScrollPane(); - hashSetList = new javax.swing.JList<>(); org.openide.awt.Mnemonics.setLocalizedText(hashSetCheckbox, org.openide.util.NbBundle.getMessage(HashSetFilterPanel.class, "HashSetFilterPanel.hashSetCheckbox.text")); // NOI18N hashSetCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); @@ -98,20 +95,15 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { setMinimumSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 30)); - hashSetList.setModel(new DefaultListModel()); - hashSetList.setEnabled(false); - hashSetList.setVisibleRowCount(3); - hashSetScrollPane.setViewportView(hashSetList); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hashSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(0, 250, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(hashSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE) + .addGap(0, 30, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -122,24 +114,20 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox hashSetCheckbox; - private javax.swing.JList hashSetList; - private javax.swing.JScrollPane hashSetScrollPane; // End of variables declaration//GEN-END:variables @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override void configurePanel(boolean selected, int[] indicesSelected) { - boolean hasHashSets = hashSetList.getModel().getSize() > 0; + boolean hasHashSets = isFilterSupported(); hashSetCheckbox.setEnabled(hasHashSets); hashSetCheckbox.setSelected(selected && hasHashSets); if (hashSetCheckbox.isEnabled() && hashSetCheckbox.isSelected()) { - hashSetScrollPane.setEnabled(true); hashSetList.setEnabled(true); - if (indicesSelected != null) { - hashSetList.setSelectedIndices(indicesSelected); - } +// if (indicesSelected != null) { +// hashSetList.setSelectedIndices(indicesSelected); +// } } else { - hashSetScrollPane.setEnabled(false); hashSetList.setEnabled(false); } } @@ -159,7 +147,7 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { @NbBundle.Messages({"HashSetFilterPanel.error.text=At least one hash set name must be selected."}) @Override String checkForError() { - if (hashSetCheckbox.isSelected() && hashSetList.getSelectedValuesList().isEmpty()) { + if (hashSetCheckbox.isSelected() && hashSetList.getSelectedElements().isEmpty()) { return Bundle.HashSetFilterPanel_error_text(); } return ""; @@ -167,16 +155,42 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - JList getList() { - return hashSetList; + AbstractFilter getFilter() { + if (hashSetCheckbox.isSelected()) { + List setList = hashSetList.getSelectedElements(); + return new SearchFiltering.InterestingFileSetFilter(setList); + } + return null; } @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - AbstractFilter getFilter() { - if (hashSetCheckbox.isSelected()) { - return new SearchFiltering.HashSetFilter(hashSetList.getSelectedValuesList()); + void removeListeners() { + super.removeListeners(); + if (hashSetList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + hashSetList.removeListSelectionListener(listener); + } } - return null; + } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return hashSetList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + hashSetList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + hashSetList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return !hashSetList.isEmpty(); } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form index c5a8660cdd..7d99c77344 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.form @@ -45,41 +45,13 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java index 184ddb1d29..e15b86d940 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/InterestingItemsFilterPanel.java @@ -21,14 +21,14 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; -import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; @@ -40,6 +40,7 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; private final static Logger logger = Logger.getLogger(InterestingItemsFilterPanel.class.getName()); + private static final CheckBoxListPanel interestingItemsList = new CheckBoxListPanel<>(); /** * Creates new form InterestingItemsFilterPanel. @@ -48,6 +49,7 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { InterestingItemsFilterPanel() { initComponents(); setUpInterestingItemsFilter(); + add(interestingItemsList); } /** @@ -55,15 +57,12 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpInterestingItemsFilter() { - int count = 0; try { - DefaultListModel intListModel = (DefaultListModel) interestingItemsList.getModel(); - intListModel.removeAllElements(); + interestingItemsList.clearList(); List setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME); for (String name : setNames) { - intListModel.add(count, name); - count++; + interestingItemsList.addElement(name, null, name); } } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error loading interesting file set names", ex); @@ -82,8 +81,6 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { interestingItemsCheckbox = new javax.swing.JCheckBox(); - interestingItemsScrollPane = new javax.swing.JScrollPane(); - interestingItemsList = new javax.swing.JList<>(); org.openide.awt.Mnemonics.setLocalizedText(interestingItemsCheckbox, org.openide.util.NbBundle.getMessage(InterestingItemsFilterPanel.class, "InterestingItemsFilterPanel.interestingItemsCheckbox.text")); // NOI18N interestingItemsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); @@ -98,22 +95,15 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { setMinimumSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 30)); - interestingItemsScrollPane.setPreferredSize(new java.awt.Dimension(27, 27)); - - interestingItemsList.setModel(new DefaultListModel()); - interestingItemsList.setEnabled(false); - interestingItemsList.setVisibleRowCount(2); - interestingItemsScrollPane.setViewportView(interestingItemsList); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(interestingItemsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(0, 250, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(interestingItemsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 88, Short.MAX_VALUE) + .addGap(0, 30, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -124,17 +114,15 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override void configurePanel(boolean selected, int[] indicesSelected) { - boolean hasInterestingItems = interestingItemsList.getModel().getSize() > 0; + boolean hasInterestingItems = isFilterSupported(); interestingItemsCheckbox.setEnabled(hasInterestingItems); interestingItemsCheckbox.setSelected(selected && hasInterestingItems); if (interestingItemsCheckbox.isEnabled() && interestingItemsCheckbox.isSelected()) { - interestingItemsScrollPane.setEnabled(true); interestingItemsList.setEnabled(true); - if (indicesSelected != null) { - interestingItemsList.setSelectedIndices(indicesSelected); - } +// if (indicesSelected != null) { +// interestingItemsList.setSelectedIndices(indicesSelected); +// } } else { - interestingItemsScrollPane.setEnabled(false); interestingItemsList.setEnabled(false); } } @@ -154,7 +142,7 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { @NbBundle.Messages({"InterestingItemsFilterPanel.error.text=At least one interesting file set name must be selected."}) @Override String checkForError() { - if (interestingItemsCheckbox.isSelected() && interestingItemsList.getSelectedValuesList().isEmpty()) { + if (interestingItemsCheckbox.isSelected() && interestingItemsList.getSelectedElements().isEmpty()) { return Bundle.InterestingItemsFilterPanel_error_text(); } return ""; @@ -163,22 +151,46 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox interestingItemsCheckbox; - private javax.swing.JList interestingItemsList; - private javax.swing.JScrollPane interestingItemsScrollPane; // End of variables declaration//GEN-END:variables - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - @Override - JList getList() { - return interestingItemsList; - } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { if (interestingItemsCheckbox.isSelected()) { - return new SearchFiltering.InterestingFileSetFilter(interestingItemsList.getSelectedValuesList()); + List itemsList = interestingItemsList.getSelectedElements(); + return new SearchFiltering.InterestingFileSetFilter(itemsList); } return null; } + + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + @Override + void removeListeners() { + super.removeListeners(); + if (interestingItemsList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + interestingItemsList.removeListSelectionListener(listener); + } + } + } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return interestingItemsList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + interestingItemsList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + interestingItemsList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return !interestingItemsList.isEmpty(); + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/KnownAccountTypeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/KnownAccountTypeFilterPanel.java index d6d52324cf..339a3cacb7 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/KnownAccountTypeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/KnownAccountTypeFilterPanel.java @@ -21,12 +21,13 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; /** - * Panel to allow filtering only domains with known account types (TSK_WEB_ACCOUNT_TYPE). + * Panel to allow filtering only domains with known account types + * (TSK_WEB_ACCOUNT_TYPE). */ final class KnownAccountTypeFilterPanel extends AbstractDiscoveryFilterPanel { @@ -97,11 +98,6 @@ final class KnownAccountTypeFilterPanel extends AbstractDiscoveryFilterPanel { private javax.swing.JCheckBox knownAccountType; // End of variables declaration//GEN-END:variables - @Override - JList getList() { - return null; - } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { @@ -115,4 +111,24 @@ final class KnownAccountTypeFilterPanel extends AbstractDiscoveryFilterPanel { boolean hasPanel() { return false; } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return null; + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + boolean isFilterSupported() { + return true; + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.form index f181a1b451..adaed82bf2 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.form @@ -48,45 +48,13 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java index 6ccde3712e..af9b74f577 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ObjectDetectedFilterPanel.java @@ -18,18 +18,17 @@ */ package org.sleuthkit.autopsy.discovery.ui; -import java.util.ArrayList; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.List; import java.util.logging.Level; -import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.TskCoreException; @@ -41,6 +40,7 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; private final static Logger logger = Logger.getLogger(ObjectDetectedFilterPanel.class.getName()); + private static final CheckBoxListPanel objectsList = new CheckBoxListPanel<>(); /** * Creates new form ObjectDetectedFilter. @@ -48,9 +48,8 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) ObjectDetectedFilterPanel() { initComponents(); - objectsList.setCellRenderer(new CheckboxCellRenderer(objectsCheckbox)); - objectsList.setSelectionModel(new CheckboxListSelectionModel(objectsList)); setUpObjectFilter(); + add(objectsList); } /** @@ -58,14 +57,11 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpObjectFilter() { - int count = 0; try { - DefaultListModel objListModel = (DefaultListModel) objectsList.getModel(); - objListModel.removeAllElements(); + objectsList.clearList(); List setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION); for (String name : setNames) { - objListModel.add(count, new JCheckBox(name)); - count++; + objectsList.addElement(name, null, null); } } catch (TskCoreException ex) { logger.log(Level.SEVERE, "Error loading object detected set names", ex); @@ -84,8 +80,6 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { objectsCheckbox = new javax.swing.JCheckBox(); - objectsScrollPane = new javax.swing.JScrollPane(); - objectsList = new javax.swing.JList<>(); org.openide.awt.Mnemonics.setLocalizedText(objectsCheckbox, org.openide.util.NbBundle.getMessage(ObjectDetectedFilterPanel.class, "ObjectDetectedFilterPanel.text")); // NOI18N objectsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); @@ -103,24 +97,15 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { setMinimumSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 30)); - objectsScrollPane.setName(""); // NOI18N - objectsScrollPane.setPreferredSize(new java.awt.Dimension(27, 27)); - - objectsList.setModel(new DefaultListModel()); - objectsList.setEnabled(false); - objectsList.setMaximumSize(new java.awt.Dimension(32767, 32767)); - objectsList.setVisibleRowCount(2); - objectsScrollPane.setViewportView(objectsList); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(objectsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(0, 250, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(objectsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE) + .addGap(0, 30, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -131,24 +116,20 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox objectsCheckbox; - private javax.swing.JList objectsList; - private javax.swing.JScrollPane objectsScrollPane; // End of variables declaration//GEN-END:variables @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override void configurePanel(boolean selected, int[] indicesSelected) { - boolean hasObjects = objectsList.getModel().getSize() > 0; + boolean hasObjects = isFilterSupported(); objectsCheckbox.setEnabled(hasObjects); objectsCheckbox.setSelected(selected && hasObjects); if (objectsCheckbox.isEnabled() && objectsCheckbox.isSelected()) { - objectsScrollPane.setEnabled(true); objectsList.setEnabled(true); - if (indicesSelected != null) { - objectsList.setSelectedIndices(indicesSelected); - } +// if (indicesSelected != null) { +// objectsList.setSelectedIndices(indicesSelected); +// } } else { - objectsScrollPane.setEnabled(false); objectsList.setEnabled(false); } } @@ -168,29 +149,51 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel { @NbBundle.Messages({"ObjectDetectedFilterPanel.error.text=At least one object type name must be selected."}) @Override String checkForError() { - if (objectsCheckbox.isSelected() && objectsList.getSelectedValuesList().isEmpty()) { + if (objectsCheckbox.isSelected() && objectsList.getSelectedElements().isEmpty()) { return Bundle.ObjectDetectedFilterPanel_error_text(); } return ""; } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - @Override - JList getList() { - return objectsList; - } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { if (objectsCheckbox.isSelected()) { - List objectDetectedList = new ArrayList<>(); - for (JCheckBox checkbox : objectsList.getSelectedValuesList()) { - objectDetectedList.add(checkbox.getName()); - } + List objectDetectedList = objectsList.getSelectedElements(); return new SearchFiltering.ObjectDetectionFilter(objectDetectedList); } return null; } + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + @Override + void removeListeners() { + super.removeListeners(); + if (objectsList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + objectsList.removeListSelectionListener(listener); + } + } + } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return objectsList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + objectsList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + objectsList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return !objectsList.isEmpty(); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java index 2a77c28873..4504d0d463 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/ParentFolderFilterPanel.java @@ -24,7 +24,7 @@ import java.util.List; import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; @@ -311,12 +311,6 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel { return results; } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) - @Override - JList getList() { - return parentList; - } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { @@ -325,4 +319,24 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel { } return null; } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return parentList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + parentList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + parentList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return true; + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form index bfe666aee3..322ccd65f9 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.form @@ -45,44 +45,13 @@ - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java index bedd0a24c8..bc17159f63 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PastOccurrencesFilterPanel.java @@ -18,18 +18,18 @@ */ package org.sleuthkit.autopsy.discovery.ui; -import javax.swing.DefaultListModel; +import java.util.List; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.SearchData; -import org.sleuthkit.autopsy.discovery.search.SearchData.Frequency; import org.sleuthkit.autopsy.discovery.search.SearchData.Type; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; /** * Panel to allow configuration of the Past Occurrences filter. @@ -38,6 +38,7 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; private final Type type; + private static final CheckBoxListPanel crFrequencyList = new CheckBoxListPanel<>(); /** * Creates new form PastOccurrencesFilterPanel. @@ -47,6 +48,7 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { initComponents(); this.type = type; setUpFrequencyFilter(); + add(crFrequencyList); } /** @@ -59,8 +61,6 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { pastOccurrencesCheckbox = new javax.swing.JCheckBox(); - crFrequencyScrollPane = new javax.swing.JScrollPane(); - crFrequencyList = new javax.swing.JList<>(); org.openide.awt.Mnemonics.setLocalizedText(pastOccurrencesCheckbox, org.openide.util.NbBundle.getMessage(PastOccurrencesFilterPanel.class, "PastOccurrencesFilterPanel.pastOccurrencesCheckbox.text")); // NOI18N pastOccurrencesCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); @@ -75,24 +75,15 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { setMinimumSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 30)); - crFrequencyScrollPane.setPreferredSize(new java.awt.Dimension(27, 27)); - - crFrequencyList.setModel(new DefaultListModel()); - crFrequencyList.setEnabled(false); - crFrequencyList.setVisibleRowCount(5); - crFrequencyScrollPane.setViewportView(crFrequencyList); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(crFrequencyScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addGap(0, 250, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(crFrequencyScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 0, 0)) + .addGap(0, 30, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -105,27 +96,23 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpFrequencyFilter() { - int count = 0; - DefaultListModel frequencyListModel = (DefaultListModel) crFrequencyList.getModel(); - frequencyListModel.removeAllElements(); + crFrequencyList.clearList(); if (!CentralRepository.isEnabled()) { if (type != Type.DOMAIN) { for (SearchData.Frequency freq : SearchData.Frequency.getOptionsForFilteringWithoutCr()) { - frequencyListModel.add(count, freq); + crFrequencyList.addElement(freq.toString(), null, freq); } } } else { for (SearchData.Frequency freq : SearchData.Frequency.getOptionsForFilteringWithCr()) { if (type != Type.DOMAIN || freq != SearchData.Frequency.KNOWN) { - frequencyListModel.add(count, freq); + crFrequencyList.addElement(freq.toString(), null, freq); } } } } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JList crFrequencyList; - private javax.swing.JScrollPane crFrequencyScrollPane; private javax.swing.JCheckBox pastOccurrencesCheckbox; // End of variables declaration//GEN-END:variables @@ -137,13 +124,11 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { pastOccurrencesCheckbox.setSelected(selected && canBeFilteredOn); if (pastOccurrencesCheckbox.isEnabled() && pastOccurrencesCheckbox.isSelected()) { - crFrequencyScrollPane.setEnabled(true); crFrequencyList.setEnabled(true); - if (indicesSelected != null) { - crFrequencyList.setSelectedIndices(indicesSelected); - } +// if (indicesSelected != null) { +// crFrequencyList.setSelectedIndices(indicesSelected); +// } } else { - crFrequencyScrollPane.setEnabled(false); crFrequencyList.setEnabled(false); } } @@ -163,7 +148,7 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { @NbBundle.Messages({"PastOccurrencesFilterPanel.error.text=At least one value in the past occurrence filter must be selected."}) @Override String checkForError() { - if (pastOccurrencesCheckbox.isSelected() && crFrequencyList.getSelectedValuesList().isEmpty()) { + if (pastOccurrencesCheckbox.isSelected() && crFrequencyList.getSelectedElements().isEmpty()) { return Bundle.PastOccurrencesFilterPanel_error_text(); } return ""; @@ -171,16 +156,43 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - JList getList() { - return crFrequencyList; + AbstractFilter getFilter() { + if (pastOccurrencesCheckbox.isSelected()) { + List frequencies = crFrequencyList.getSelectedElements(); + return new SearchFiltering.FrequencyFilter(frequencies); + } + return null; } @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - AbstractFilter getFilter() { - if (pastOccurrencesCheckbox.isSelected()) { - return new SearchFiltering.FrequencyFilter(crFrequencyList.getSelectedValuesList()); + void removeListeners() { + super.removeListeners(); + if (crFrequencyList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + crFrequencyList.removeListSelectionListener(listener); + } } - return null; } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return crFrequencyList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + crFrequencyList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + crFrequencyList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return !crFrequencyList.isEmpty(); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.form index 745ff3f4ab..9c7c879377 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.form @@ -7,17 +7,11 @@ - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.java index f72fb10c05..829884b899 100755 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/PreviouslyNotableFilterPanel.java @@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; @@ -103,11 +103,6 @@ final class PreviouslyNotableFilterPanel extends AbstractDiscoveryFilterPanel { private javax.swing.JCheckBox previouslyNotableCheckbox; // End of variables declaration//GEN-END:variables - @Override - JList getList() { - return null; - } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { @@ -121,4 +116,24 @@ final class PreviouslyNotableFilterPanel extends AbstractDiscoveryFilterPanel { boolean hasPanel() { return false; } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return null; + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + boolean isFilterSupported() { + return true; + } } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form index fd63ea077d..04703809ce 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.form @@ -48,47 +48,13 @@ - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java index e037f1f8ee..8e0b7c6b99 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/SizeFilterPanel.java @@ -21,15 +21,15 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import java.util.ArrayList; import java.util.List; -import javax.swing.DefaultListModel; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.SearchData.FileSize; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; +import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel; /** * Panel to allow configuration of the Size Filter. @@ -37,6 +37,7 @@ import org.sleuthkit.autopsy.discovery.search.SearchFiltering; final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { private static final long serialVersionUID = 1L; + private static final CheckBoxListPanel sizeList = new CheckBoxListPanel<>(); /** * Creates new form SizeFilterPanel. @@ -47,6 +48,7 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { SizeFilterPanel(SearchData.Type type) { initComponents(); setUpSizeFilter(type); + add(sizeList); } /** @@ -59,8 +61,6 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { private void initComponents() { sizeCheckbox = new javax.swing.JCheckBox(); - sizeScrollPane = new javax.swing.JScrollPane(); - sizeList = new javax.swing.JList<>(); org.openide.awt.Mnemonics.setLocalizedText(sizeCheckbox, org.openide.util.NbBundle.getMessage(SizeFilterPanel.class, "SizeFilterPanel.sizeCheckbox.text")); // NOI18N sizeCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); @@ -78,25 +78,15 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { setName(""); // NOI18N setPreferredSize(new java.awt.Dimension(250, 30)); - sizeScrollPane.setPreferredSize(new java.awt.Dimension(27, 27)); - - sizeList.setModel(new DefaultListModel()); - sizeList.setEnabled(false); - sizeList.setMaximumSize(new java.awt.Dimension(32767, 32767)); - sizeList.setVisibleRowCount(5); - sizeScrollPane.setViewportView(sizeList); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(sizeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 250, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(sizeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 0, 0)) + .addGap(0, 30, Short.MAX_VALUE) ); }// //GEN-END:initComponents @@ -107,8 +97,6 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox sizeCheckbox; - private javax.swing.JList sizeList; - private javax.swing.JScrollPane sizeScrollPane; // End of variables declaration//GEN-END:variables @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @@ -116,13 +104,11 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { void configurePanel(boolean selected, int[] indicesSelected) { sizeCheckbox.setSelected(selected); if (sizeCheckbox.isEnabled() && sizeCheckbox.isSelected()) { - sizeScrollPane.setEnabled(true); sizeList.setEnabled(true); - if (indicesSelected != null) { - sizeList.setSelectedIndices(indicesSelected); - } +// if (indicesSelected != null) { +// sizeList.setSelectedIndices(indicesSelected); +// } } else { - sizeScrollPane.setEnabled(false); sizeList.setEnabled(false); } } @@ -143,12 +129,12 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { */ @ThreadConfined(type = ThreadConfined.ThreadType.AWT) private void setUpSizeFilter(SearchData.Type fileType) { - int count = 0; - DefaultListModel sizeListModel = (DefaultListModel) sizeList.getModel(); - sizeListModel.removeAllElements(); + int insertIndex = 0; +// DefaultListModel sizeListModel = (DefaultListModel) sizeList.getModel(); + sizeList.removeAll(); if (null == fileType) { for (FileSize size : FileSize.values()) { - sizeListModel.add(count, size); + sizeList.addElement(size.toString(), null, size); } } else { List sizes; @@ -167,7 +153,7 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { break; } for (FileSize size : sizes) { - sizeListModel.add(count, size); + sizeList.addElement(size.toString(), null, size); } } } @@ -176,7 +162,7 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { @Override @ThreadConfined(type = ThreadConfined.ThreadType.AWT) String checkForError() { - if (sizeCheckbox.isSelected() && sizeList.getSelectedValuesList().isEmpty()) { + if (sizeCheckbox.isSelected() && sizeList.getSelectedElements().isEmpty()) { return Bundle.SizeFilterPanel_error_text(); } return ""; @@ -185,16 +171,43 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - JList getList() { - return sizeList; + AbstractFilter getFilter() { + if (sizeCheckbox.isSelected()) { + List fileSizes = sizeList.getSelectedElements(); + return new SearchFiltering.SizeFilter(fileSizes); + } + return null; } @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override - AbstractFilter getFilter() { - if (sizeCheckbox.isSelected()) { - return new SearchFiltering.SizeFilter(sizeList.getSelectedValuesList()); + void removeListeners() { + super.removeListeners(); + if (sizeList != null) { + for (ListSelectionListener listener : getListSelectionListeners()) { + sizeList.removeListSelectionListener(listener); + } } - return null; } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return sizeList.getListSelectionListeners(); + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + sizeList.addListSelectionListener(listener); + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + sizeList.removeListSelectionListener(listener); + } + + @Override + boolean isFilterSupported() { + return !sizeList.isEmpty(); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java index 10d976f7fe..5e3a6506c0 100644 --- a/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java +++ b/Core/src/org/sleuthkit/autopsy/discovery/ui/UserCreatedFilterPanel.java @@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.discovery.ui; import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import javax.swing.JCheckBox; import javax.swing.JLabel; -import javax.swing.JList; +import javax.swing.event.ListSelectionListener; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.discovery.search.SearchFiltering; @@ -98,11 +98,6 @@ final class UserCreatedFilterPanel extends AbstractDiscoveryFilterPanel { private javax.swing.JCheckBox userCreatedCheckbox; // End of variables declaration//GEN-END:variables - @Override - JList getList() { - return null; - } - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) @Override AbstractFilter getFilter() { @@ -116,4 +111,24 @@ final class UserCreatedFilterPanel extends AbstractDiscoveryFilterPanel { boolean hasPanel() { return false; } + + @Override + ListSelectionListener[] getListSelectionListeners() { + return null; + } + + @Override + void addListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + void removeListSelectionListener(ListSelectionListener listener) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + boolean isFilterSupported() { + return true; + } } diff --git a/Core/src/org/sleuthkit/autopsy/guiutils/CheckBoxListPanel.java b/Core/src/org/sleuthkit/autopsy/guiutils/CheckBoxListPanel.java index 46ee3f079a..7d06ce5bae 100755 --- a/Core/src/org/sleuthkit/autopsy/guiutils/CheckBoxListPanel.java +++ b/Core/src/org/sleuthkit/autopsy/guiutils/CheckBoxListPanel.java @@ -27,6 +27,7 @@ import java.util.Objects; import java.util.Set; import javax.swing.DefaultListModel; import javax.swing.Icon; +import javax.swing.event.ListSelectionListener; /** * A panel for showing any object in a check box list. @@ -54,7 +55,7 @@ public final class CheckBoxListPanel extends javax.swing.JPanel { * * @param displayName display name for the checkbox * @param icon - * @param obj Object that the checkbox represents + * @param obj Object that the checkbox represents */ public void addElement(String displayName, Icon icon, T obj) { ObjectCheckBox newCheckBox = new ObjectCheckBox<>(displayName, icon, true, obj); @@ -106,8 +107,8 @@ public final class CheckBoxListPanel extends javax.swing.JPanel { * Sets the selected items within the checkbox list panel. * * @param selected The items that should be selected. If the checkbox data - * is present in this list, it will be selected, otherwise it will be - * deselected. + * is present in this list, it will be selected, otherwise + * it will be deselected. */ public void setSelectedElements(List selected) { Set toSelect = selected == null ? Collections.emptySet() : new HashSet<>(selected); @@ -158,6 +159,18 @@ public final class CheckBoxListPanel extends javax.swing.JPanel { titleLabel.setIcon(icon); } + public void addListSelectionListener(ListSelectionListener listener) { + checkboxList.addListSelectionListener(listener); + } + + public void removeListSelectionListener(ListSelectionListener listener) { + checkboxList.removeListSelectionListener(listener); + } + + public ListSelectionListener[] getListSelectionListeners() { + return checkboxList.getListSelectionListeners(); + } + /** * 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 @@ -252,10 +265,10 @@ public final class CheckBoxListPanel extends javax.swing.JPanel { /** * Constructs a new ObjectCheckBox * - * @param displayName String to show as the check box label - * @param icon Icon to show before the check box (may be null) + * @param displayName String to show as the check box label + * @param icon Icon to show before the check box (may be null) * @param initialState Sets the initial state of the check box - * @param object Object that the check box represents. + * @param object Object that the check box represents. */ ObjectCheckBox(String displayName, Icon icon, boolean initialState, T object) { this.displayName = displayName;