7328 checkbox list with existing class

This commit is contained in:
William Schaefer 2021-03-19 09:51:33 -04:00
parent 365aadf4f0
commit ab3bf74e9c
27 changed files with 563 additions and 768 deletions

View File

@ -25,6 +25,7 @@ import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
/** /**
* Abstract class extending JPanel for filter controls. * Abstract class extending JPanel for filter controls.
@ -54,14 +55,20 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
abstract JCheckBox getCheckbox(); abstract JCheckBox getCheckbox();
/** /**
* Get the list of values associated with this filter if one exists. If one * Get the array of list selection listeners associated with this filter. If
* does not exist this should return null. * a list does not exist this should return null.
* *
* @return The JList which contains the values available for selection for * @return The array which contains the list selection listeners for this
* this filter. * panel.
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @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 * 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) { if (getCheckbox() != null) {
getCheckbox().addActionListener(actionListener); getCheckbox().addActionListener(actionListener);
} }
if (getList() != null) { if (getListSelectionListeners() != null) {
getList().addListSelectionListener(listListener); addListSelectionListener(listListener);
} }
} }
@ -117,13 +124,25 @@ abstract class AbstractDiscoveryFilterPanel extends javax.swing.JPanel {
getCheckbox().removeActionListener(listener); getCheckbox().removeActionListener(listener);
} }
} }
if (getList() != null) { /*
for (ListSelectionListener listener : getList().getListSelectionListeners()) { * Should be overridden if a list is present and have something allong
getList().removeListSelectionListener(listener); * 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. * Return whether or not this filter has a panel.
* *

View File

@ -228,7 +228,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
boolean isObjectsFilterSupported() { boolean isObjectsFilterSupported() {
for (AbstractDiscoveryFilterPanel filter : filters) { for (AbstractDiscoveryFilterPanel filter : filters) {
if (filter instanceof ObjectDetectedFilterPanel) { if (filter instanceof ObjectDetectedFilterPanel) {
return filter.getList().getModel().getSize() > 0; return filter.isFilterSupported();
} }
} }
return false; return false;
@ -243,7 +243,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
boolean isHashSetFilterSupported() { boolean isHashSetFilterSupported() {
for (AbstractDiscoveryFilterPanel filter : filters) { for (AbstractDiscoveryFilterPanel filter : filters) {
if (filter instanceof HashSetFilterPanel) { if (filter instanceof HashSetFilterPanel) {
return filter.getList().getModel().getSize() > 0; return filter.isFilterSupported();
} }
} }
return false; return false;
@ -258,7 +258,7 @@ abstract class AbstractFiltersPanel extends JPanel implements ActionListener, Li
boolean isInterestingItemsFilterSupported() { boolean isInterestingItemsFilterSupported() {
for (AbstractDiscoveryFilterPanel filter : filters) { for (AbstractDiscoveryFilterPanel filter : filters) {
if (filter instanceof InterestingItemsFilterPanel) { if (filter instanceof InterestingItemsFilterPanel) {
return filter.getList().getModel().getSize() > 0; return filter.isFilterSupported();
} }
} }
return false; return false;

View File

@ -33,37 +33,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="artifactTypeScrollPane" alignment="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="27" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="artifactTypeScrollPane" alignment="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="27" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="artifactTypeScrollPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[27, 27]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="artifactList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DefaultListModel&lt;ArtifactTypeItem&gt;()" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;ArtifactTypeItem&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -18,25 +18,25 @@
*/ */
package org.sleuthkit.autopsy.discovery.ui; package org.sleuthkit.autopsy.discovery.ui;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.SearchData;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering.ArtifactTypeFilter; import org.sleuthkit.autopsy.discovery.search.SearchFiltering.ArtifactTypeFilter;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
/** /**
* Filter for selection of a specific Artifact type to limit results to. * 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 long serialVersionUID = 1L;
private static final CheckBoxListPanel<BlackboardArtifact.ARTIFACT_TYPE> artifactList = new CheckBoxListPanel<>();
/** /**
* Creates new form ArtifactTypeFilterPanel * Creates new form ArtifactTypeFilterPanel
@ -45,7 +45,7 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
ArtifactTypeFilterPanel() { ArtifactTypeFilterPanel() {
initComponents(); initComponents();
setUpArtifactTypeFilter(); setUpArtifactTypeFilter();
add(artifactList);
} }
/** /**
@ -53,12 +53,9 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpArtifactTypeFilter() { private void setUpArtifactTypeFilter() {
int count = 0; artifactList.clearList();
DefaultListModel<ArtifactTypeItem> artifactTypeModel = (DefaultListModel<ArtifactTypeItem>) artifactList.getModel();
artifactTypeModel.removeAllElements();
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SearchData.Type.DOMAIN.getArtifactTypes()) { for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SearchData.Type.DOMAIN.getArtifactTypes()) {
artifactTypeModel.add(count, new ArtifactTypeItem(artifactType)); artifactList.addElement(artifactType.getDisplayName(), null, artifactType);
count++;
} }
} }
@ -72,8 +69,6 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
artifactTypeCheckbox = new javax.swing.JCheckBox(); 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 org.openide.awt.Mnemonics.setLocalizedText(artifactTypeCheckbox, org.openide.util.NbBundle.getMessage(ArtifactTypeFilterPanel.class, "ArtifactTypeFilterPanel.artifactTypeCheckbox.text")); // NOI18N
artifactTypeCheckbox.addActionListener(new java.awt.event.ActionListener() { artifactTypeCheckbox.addActionListener(new java.awt.event.ActionListener() {
@ -84,26 +79,19 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
setPreferredSize(new java.awt.Dimension(27, 27)); setPreferredSize(new java.awt.Dimension(27, 27));
artifactTypeScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
artifactList.setModel(new DefaultListModel<ArtifactTypeItem>());
artifactList.setEnabled(false);
artifactTypeScrollPane.setViewportView(artifactList);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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)
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void artifactTypeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_artifactTypeCheckboxActionPerformed private void artifactTypeCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_artifactTypeCheckboxActionPerformed
artifactTypeScrollPane.setEnabled(artifactTypeCheckbox.isSelected());
artifactList.setEnabled(artifactTypeCheckbox.isSelected()); artifactList.setEnabled(artifactTypeCheckbox.isSelected());
}//GEN-LAST:event_artifactTypeCheckboxActionPerformed }//GEN-LAST:event_artifactTypeCheckboxActionPerformed
@ -112,13 +100,11 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
void configurePanel(boolean selected, int[] indicesSelected) { void configurePanel(boolean selected, int[] indicesSelected) {
artifactTypeCheckbox.setSelected(selected); artifactTypeCheckbox.setSelected(selected);
if (artifactTypeCheckbox.isEnabled() && artifactTypeCheckbox.isSelected()) { if (artifactTypeCheckbox.isEnabled() && artifactTypeCheckbox.isSelected()) {
artifactTypeScrollPane.setEnabled(true);
artifactList.setEnabled(true); artifactList.setEnabled(true);
if (indicesSelected != null) { // if (indicesSelected != null) {
artifactList.setSelectedIndices(indicesSelected); // artifactList.setSelectedIndices(indicesSelected);
} // }
} else { } else {
artifactTypeScrollPane.setEnabled(false);
artifactList.setEnabled(false); artifactList.setEnabled(false);
} }
} }
@ -129,12 +115,6 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
return artifactTypeCheckbox; return artifactTypeCheckbox;
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
JList<?> getList() {
return artifactList;
}
@Override @Override
JLabel getAdditionalLabel() { JLabel getAdditionalLabel() {
return null; return null;
@ -144,7 +124,7 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
@NbBundle.Messages({"ArtifactTypeFilterPanel.selectionNeeded.text=At least one Result type must be selected."}) @NbBundle.Messages({"ArtifactTypeFilterPanel.selectionNeeded.text=At least one Result type must be selected."})
@Override @Override
String checkForError() { String checkForError() {
if (artifactTypeCheckbox.isSelected() && artifactList.getSelectedValuesList().isEmpty()) { if (artifactTypeCheckbox.isSelected() && artifactList.getSelectedElements().isEmpty()) {
return Bundle.ArtifactTypeFilterPanel_selectionNeeded_text(); return Bundle.ArtifactTypeFilterPanel_selectionNeeded_text();
} }
return ""; return "";
@ -153,52 +133,46 @@ class ArtifactTypeFilterPanel extends AbstractDiscoveryFilterPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
if (artifactTypeCheckbox.isSelected() && !artifactList.getSelectedValuesList().isEmpty()) { if (artifactTypeCheckbox.isSelected() && isFilterSupported()) {
List<BlackboardArtifact.ARTIFACT_TYPE> artifactTypeList = new ArrayList<>(); List<BlackboardArtifact.ARTIFACT_TYPE> artifactTypeList = artifactList.getSelectedElements();
for (ArtifactTypeItem item : artifactList.getSelectedValuesList()) {
artifactTypeList.add(item.getArtifactType());
}
return new ArtifactTypeFilter(artifactTypeList); return new ArtifactTypeFilter(artifactTypeList);
} }
return null; return null;
} }
/** @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
* Utility class to allow us to display the AritfactType display name @Override
* instead of the name. void removeListeners() {
*/ super.removeListeners();
private class ArtifactTypeItem extends JCheckBox { if (artifactList != null) {
for (ListSelectionListener listener : getListSelectionListeners()) {
private static final long serialVersionUID = 1L; artifactList.removeListSelectionListener(listener);
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();
} }
} }
@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 // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JList<ArtifactTypeItem> artifactList;
private javax.swing.JCheckBox artifactTypeCheckbox; private javax.swing.JCheckBox artifactTypeCheckbox;
private javax.swing.JScrollPane artifactTypeScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -61,3 +61,5 @@ CookieDetailsPanel.jLabel2.text=
PreviouslyNotableFilterPanel.text_1=Include only previously notable domains PreviouslyNotableFilterPanel.text_1=Include only previously notable domains
KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type
LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel
DataSourceFilterPanel.deselectAllButton.text=Deselect All
DataSourceFilterPanel.selectAllButton.text=Select All

View File

@ -54,6 +54,7 @@ DocumentPanel.numberOfImages.noImages=No images
DocumentPanel.numberOfImages.text=1 of {0} images DocumentPanel.numberOfImages.text=1 of {0} images
DocumentWrapper.previewInitialValue=Preview not generated yet. DocumentWrapper.previewInitialValue=Preview not generated yet.
DomainDetailsPanel.miniTimelineTitle.text=Timeline DomainDetailsPanel.miniTimelineTitle.text=Timeline
DomainDetailsPanel.otherOccurrencesTab.title=Other Occurrences
# {0} - startDate # {0} - startDate
# {1} - endDate # {1} - endDate
DomainSummaryPanel.activity.text=Activity: {0} to {1} DomainSummaryPanel.activity.text=Activity: {0} to {1}
@ -174,6 +175,8 @@ CookieDetailsPanel.jLabel2.text=
PreviouslyNotableFilterPanel.text_1=Include only previously notable domains PreviouslyNotableFilterPanel.text_1=Include only previously notable domains
KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type KnownAccountTypeFilterPanel.text_1=Include only domains with a known account type
LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel LoadingPanel.detailsLabel.AccessibleContext.accessibleName=detailsLabel
DataSourceFilterPanel.deselectAllButton.text=Deselect All
DataSourceFilterPanel.selectAllButton.text=Select All
VideoThumbnailPanel.bytes.text=bytes VideoThumbnailPanel.bytes.text=bytes
VideoThumbnailPanel.deleted.text=All instances of file are deleted. VideoThumbnailPanel.deleted.text=All instances of file are deleted.
VideoThumbnailPanel.gigaBytes.text=GB VideoThumbnailPanel.gigaBytes.text=GB

View File

@ -1,48 +0,0 @@
/*
* Autopsy
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<JCheckBox> {
private final JCheckBox checkboxToEnableList;
CheckboxCellRenderer(JCheckBox checkboxToEnableList){
this.checkboxToEnableList = checkboxToEnableList;
}
@Override
public Component getListCellRendererComponent(JList<? extends JCheckBox> 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;
}
}

View File

@ -1,133 +0,0 @@
/*
* Autopsy
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<? extends JCheckBox> list;
CheckboxListSelectionModel(javax.swing.JList<? extends JCheckBox> 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.
}
}

View File

@ -27,7 +27,7 @@
<Dimension value="[250, 30]"/> <Dimension value="[250, 30]"/>
</Property> </Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[250, 30]"/> <Dimension value="[250, 50]"/>
</Property> </Property>
<Property name="requestFocusEnabled" type="boolean" value="false"/> <Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties> </Properties>
@ -46,44 +46,47 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="dataSourceScrollPane" alignment="0" pref="300" max="32767" attributes="0"/> <Group type="102" attributes="0">
<Component id="selectAllButton" linkSize="3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="deselectAllButton" linkSize="3" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="45" max="32767" attributes="0"/>
</Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="dataSourceScrollPane" max="32767" attributes="0"/> <EmptySpace pref="19" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/> <Group type="103" groupAlignment="3" attributes="0">
<Component id="selectAllButton" linkSize="4" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deselectAllButton" linkSize="4" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JScrollPane" name="dataSourceScrollPane"> <Component class="javax.swing.JButton" name="selectAllButton">
<Properties> <Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<Dimension value="[27, 27]"/> <ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DataSourceFilterPanel.selectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<AuxValues> <Events>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectAllButtonActionPerformed"/>
</AuxValues> </Events>
</Component>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <Component class="javax.swing.JButton" name="deselectAllButton">
<SubComponents> <Properties>
<Component class="javax.swing.JList" name="dataSourceList"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<Properties> <ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="DataSourceFilterPanel.deselectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> </Property>
<Connection code="new DefaultListModel&lt;DataSourceItem&gt;()" type="code"/> </Properties>
</Property> <Events>
<Property name="enabled" type="boolean" value="false"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deselectAllButtonActionPerformed"/>
<Property name="visibleRowCount" type="int" value="5"/> </Events>
</Properties> </Component>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;DataSourceItem&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -22,16 +22,15 @@ import java.util.Collections;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -42,6 +41,7 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(DataSourceFilterPanel.class.getName()); private final static Logger logger = Logger.getLogger(DataSourceFilterPanel.class.getName());
private final CheckBoxListPanel<DataSource> dataSourceCheckBoxList = new CheckBoxListPanel<>();
/** /**
* Creates new form DataSourceFilterPanel. * Creates new form DataSourceFilterPanel.
@ -50,8 +50,7 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
DataSourceFilterPanel() { DataSourceFilterPanel() {
initComponents(); initComponents();
setUpDataSourceFilter(); setUpDataSourceFilter();
dataSourceList.setCellRenderer(new CheckboxCellRenderer(dataSourceCheckbox)); add(dataSourceCheckBoxList);
dataSourceList.setSelectionModel(new CheckboxListSelectionModel(dataSourceList));
} }
/** /**
@ -63,8 +62,8 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
dataSourceCheckbox = new javax.swing.JCheckBox(); dataSourceCheckbox = new javax.swing.JCheckBox();
dataSourceScrollPane = new javax.swing.JScrollPane(); selectAllButton = new javax.swing.JButton();
dataSourceList = new javax.swing.JList<>(); deselectAllButton = new javax.swing.JButton();
org.openide.awt.Mnemonics.setLocalizedText(dataSourceCheckbox, org.openide.util.NbBundle.getMessage(DataSourceFilterPanel.class, "DataSourceFilterPanel.dataSourceCheckbox.text")); // NOI18N 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)); dataSourceCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
@ -77,39 +76,69 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
}); });
setMinimumSize(new java.awt.Dimension(250, 30)); setMinimumSize(new java.awt.Dimension(250, 30));
setPreferredSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 50));
setRequestFocusEnabled(false); 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<DataSourceItem>()); org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(DataSourceFilterPanel.class, "DataSourceFilterPanel.deselectAllButton.text")); // NOI18N
dataSourceList.setEnabled(false); deselectAllButton.addActionListener(new java.awt.event.ActionListener() {
dataSourceList.setVisibleRowCount(5); public void actionPerformed(java.awt.event.ActionEvent evt) {
dataSourceScrollPane.setViewportView(dataSourceList); deselectAllButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(dataSourceScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap(19, Short.MAX_VALUE)
.addGap(0, 0, 0)) .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});
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void dataSourceCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourceCheckboxActionPerformed 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 }//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 // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox dataSourceCheckbox; private javax.swing.JCheckBox dataSourceCheckbox;
private javax.swing.JList<DataSourceItem> dataSourceList; private javax.swing.JButton deselectAllButton;
private javax.swing.JScrollPane dataSourceScrollPane; private javax.swing.JButton selectAllButton;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@ -117,14 +146,12 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
void configurePanel(boolean selected, int[] indicesSelected) { void configurePanel(boolean selected, int[] indicesSelected) {
dataSourceCheckbox.setSelected(selected); dataSourceCheckbox.setSelected(selected);
if (dataSourceCheckbox.isEnabled() && dataSourceCheckbox.isSelected()) { if (dataSourceCheckbox.isEnabled() && dataSourceCheckbox.isSelected()) {
dataSourceScrollPane.setEnabled(true); dataSourceCheckBoxList.setEnabled(true);
dataSourceList.setEnabled(true); // if (indicesSelected != null) {
if (indicesSelected != null) { // dataSourceCheckBoxList.setSelectedIndices(indicesSelected);
dataSourceList.setSelectedIndices(indicesSelected); // }
}
} else { } else {
dataSourceScrollPane.setEnabled(false); dataSourceCheckBoxList.setEnabled(false);
dataSourceList.setEnabled(false);
} }
} }
@ -144,81 +171,67 @@ final class DataSourceFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpDataSourceFilter() { private void setUpDataSourceFilter() {
int count = 0;
try { try {
DefaultListModel<DataSourceItem> dsListModel = (DefaultListModel<DataSourceItem>) dataSourceList.getModel(); dataSourceCheckBoxList.clearList();
dsListModel.removeAllElements();
List<DataSource> dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources(); List<DataSource> dataSources = Case.getCurrentCase().getSleuthkitCase().getDataSources();
Collections.sort(dataSources, (DataSource ds1, DataSource ds2) -> ds1.getName().compareToIgnoreCase(ds2.getName())); Collections.sort(dataSources, (DataSource ds1, DataSource ds2) -> ds1.getName().compareToIgnoreCase(ds2.getName()));
for (DataSource ds : dataSources) { for (DataSource ds : dataSources) {
dsListModel.add(count, new DataSourceItem(ds)); dataSourceCheckBoxList.addElement(ds.getName() + " (ID: " + ds.getId() + ")", null, ds);
count++;
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error loading data sources", ex); logger.log(Level.SEVERE, "Error loading data sources", ex);
dataSourceCheckbox.setEnabled(false); dataSourceCheckbox.setEnabled(false);
dataSourceList.setEnabled(false); dataSourceCheckBoxList.setEnabled(false);
} }
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
JList<?> getList() { ListSelectionListener[] getListSelectionListeners() {
return dataSourceList; return dataSourceCheckBoxList.getListSelectionListeners();
} }
/** @Override
* Utility class to allow us to display the data source ID along with the void addListSelectionListener(ListSelectionListener listener) {
* name dataSourceCheckBoxList.addListSelectionListener(listener);
*/ }
private final class DataSourceItem extends javax.swing.JCheckBox {
private static final long serialVersionUID = 1L; @Override
void removeListSelectionListener(ListSelectionListener listener) {
dataSourceCheckBoxList.removeListSelectionListener(listener);
}
private final DataSource ds; @Override
boolean isFilterSupported() {
/** return !dataSourceCheckBoxList.isEmpty();
* 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() + ")";
}
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@NbBundle.Messages({"DataSourceFilterPanel.error.text=At least one data source must be selected."}) @NbBundle.Messages({"DataSourceFilterPanel.error.text=At least one data source must be selected."})
@Override @Override
String checkForError() { String checkForError() {
if (dataSourceCheckbox.isSelected() && dataSourceList.getSelectedValuesList().isEmpty()) { if (dataSourceCheckbox.isSelected() && dataSourceCheckBoxList.getSelectedElements().isEmpty()) {
return Bundle.DataSourceFilterPanel_error_text(); return Bundle.DataSourceFilterPanel_error_text();
} }
return ""; 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) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
if (dataSourceCheckbox.isSelected()) { if (dataSourceCheckbox.isSelected()) {
List<DataSource> dataSources = dataSourceList.getSelectedValuesList().stream().map(t -> t.getDataSource()).collect(Collectors.toList()); List<DataSource> dataSources = dataSourceCheckBoxList.getSelectedElements();
return new SearchFiltering.DataSourceFilter(dataSources); return new SearchFiltering.DataSourceFilter(dataSources);
} }
return null; return null;

View File

@ -29,7 +29,6 @@ import java.util.logging.Level;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; 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.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.datamodel.TimelineManager;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -253,11 +251,6 @@ class DateFilterPanel extends AbstractDiscoveryFilterPanel {
return dateFilterCheckBox; return dateFilterCheckBox;
} }
@Override
JList<?> getList() {
return null;
}
@Override @Override
JLabel getAdditionalLabel() { JLabel getAdditionalLabel() {
return null; return null;
@ -372,4 +365,24 @@ class DateFilterPanel extends AbstractDiscoveryFilterPanel {
private javax.swing.JCheckBox startCheckBox; private javax.swing.JCheckBox startCheckBox;
private com.github.lgooddatepicker.components.DatePicker startDatePicker; private com.github.lgooddatepicker.components.DatePicker startDatePicker;
// End of variables declaration//GEN-END:variables // 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;
}
} }

View File

@ -45,36 +45,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="hashSetScrollPane" alignment="0" pref="300" max="32767" attributes="0"/> <EmptySpace min="0" pref="250" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="hashSetScrollPane" alignment="0" pref="60" max="32767" attributes="0"/> <EmptySpace min="0" pref="30" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="hashSetScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="hashSetList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DefaultListModel&lt;String&gt;()" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="visibleRowCount" type="int" value="3"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -21,14 +21,14 @@ package org.sleuthkit.autopsy.discovery.ui;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -40,6 +40,7 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(HashSetFilterPanel.class.getName()); private final static Logger logger = Logger.getLogger(HashSetFilterPanel.class.getName());
private static final CheckBoxListPanel<String> hashSetList = new CheckBoxListPanel<>();
/** /**
* Creates new form HashSetFilterPaenl. * Creates new form HashSetFilterPaenl.
@ -48,6 +49,7 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
HashSetFilterPanel() { HashSetFilterPanel() {
initComponents(); initComponents();
setUpHashFilter(); setUpHashFilter();
add(hashSetList);
} }
/** /**
@ -55,15 +57,12 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpHashFilter() { private void setUpHashFilter() {
int count = 0;
try { try {
DefaultListModel<String> hashListModel = (DefaultListModel<String>) hashSetList.getModel(); hashSetList.clearList();
hashListModel.removeAllElements();
List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME); BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
for (String name : setNames) { for (String name : setNames) {
hashListModel.add(count, name); hashSetList.addElement(name, null, name);
count++;
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error loading hash set names", ex); logger.log(Level.SEVERE, "Error loading hash set names", ex);
@ -82,8 +81,6 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
hashSetCheckbox = new javax.swing.JCheckBox(); 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 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)); hashSetCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
@ -98,20 +95,15 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
setMinimumSize(new java.awt.Dimension(250, 30)); setMinimumSize(new java.awt.Dimension(250, 30));
setPreferredSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 30));
hashSetList.setModel(new DefaultListModel<String>());
hashSetList.setEnabled(false);
hashSetList.setVisibleRowCount(3);
hashSetScrollPane.setViewportView(hashSetList);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(hashSetScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE) .addGap(0, 30, Short.MAX_VALUE)
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -122,24 +114,20 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox hashSetCheckbox; private javax.swing.JCheckBox hashSetCheckbox;
private javax.swing.JList<String> hashSetList;
private javax.swing.JScrollPane hashSetScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
void configurePanel(boolean selected, int[] indicesSelected) { void configurePanel(boolean selected, int[] indicesSelected) {
boolean hasHashSets = hashSetList.getModel().getSize() > 0; boolean hasHashSets = isFilterSupported();
hashSetCheckbox.setEnabled(hasHashSets); hashSetCheckbox.setEnabled(hasHashSets);
hashSetCheckbox.setSelected(selected && hasHashSets); hashSetCheckbox.setSelected(selected && hasHashSets);
if (hashSetCheckbox.isEnabled() && hashSetCheckbox.isSelected()) { if (hashSetCheckbox.isEnabled() && hashSetCheckbox.isSelected()) {
hashSetScrollPane.setEnabled(true);
hashSetList.setEnabled(true); hashSetList.setEnabled(true);
if (indicesSelected != null) { // if (indicesSelected != null) {
hashSetList.setSelectedIndices(indicesSelected); // hashSetList.setSelectedIndices(indicesSelected);
} // }
} else { } else {
hashSetScrollPane.setEnabled(false);
hashSetList.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."}) @NbBundle.Messages({"HashSetFilterPanel.error.text=At least one hash set name must be selected."})
@Override @Override
String checkForError() { String checkForError() {
if (hashSetCheckbox.isSelected() && hashSetList.getSelectedValuesList().isEmpty()) { if (hashSetCheckbox.isSelected() && hashSetList.getSelectedElements().isEmpty()) {
return Bundle.HashSetFilterPanel_error_text(); return Bundle.HashSetFilterPanel_error_text();
} }
return ""; return "";
@ -167,16 +155,42 @@ final class HashSetFilterPanel extends AbstractDiscoveryFilterPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
JList<?> getList() { AbstractFilter getFilter() {
return hashSetList; if (hashSetCheckbox.isSelected()) {
List<String> setList = hashSetList.getSelectedElements();
return new SearchFiltering.InterestingFileSetFilter(setList);
}
return null;
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { void removeListeners() {
if (hashSetCheckbox.isSelected()) { super.removeListeners();
return new SearchFiltering.HashSetFilter(hashSetList.getSelectedValuesList()); 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();
} }
} }

View File

@ -45,41 +45,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="interestingItemsScrollPane" pref="300" max="32767" attributes="0"/> <EmptySpace min="0" pref="250" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="interestingItemsScrollPane" alignment="0" pref="88" max="32767" attributes="0"/> <EmptySpace min="0" pref="30" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="interestingItemsScrollPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[27, 27]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="interestingItemsList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DefaultListModel&lt;String&gt;()" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="visibleRowCount" type="int" value="2"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -21,14 +21,14 @@ package org.sleuthkit.autopsy.discovery.ui;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -40,6 +40,7 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(InterestingItemsFilterPanel.class.getName()); private final static Logger logger = Logger.getLogger(InterestingItemsFilterPanel.class.getName());
private static final CheckBoxListPanel<String> interestingItemsList = new CheckBoxListPanel<>();
/** /**
* Creates new form InterestingItemsFilterPanel. * Creates new form InterestingItemsFilterPanel.
@ -48,6 +49,7 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
InterestingItemsFilterPanel() { InterestingItemsFilterPanel() {
initComponents(); initComponents();
setUpInterestingItemsFilter(); setUpInterestingItemsFilter();
add(interestingItemsList);
} }
/** /**
@ -55,15 +57,12 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpInterestingItemsFilter() { private void setUpInterestingItemsFilter() {
int count = 0;
try { try {
DefaultListModel<String> intListModel = (DefaultListModel<String>) interestingItemsList.getModel(); interestingItemsList.clearList();
intListModel.removeAllElements();
List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT, List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT,
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME); BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
for (String name : setNames) { for (String name : setNames) {
intListModel.add(count, name); interestingItemsList.addElement(name, null, name);
count++;
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error loading interesting file set names", ex); logger.log(Level.SEVERE, "Error loading interesting file set names", ex);
@ -82,8 +81,6 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
interestingItemsCheckbox = new javax.swing.JCheckBox(); 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 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)); interestingItemsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
@ -98,22 +95,15 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
setMinimumSize(new java.awt.Dimension(250, 30)); setMinimumSize(new java.awt.Dimension(250, 30));
setPreferredSize(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<String>());
interestingItemsList.setEnabled(false);
interestingItemsList.setVisibleRowCount(2);
interestingItemsScrollPane.setViewportView(interestingItemsList);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(interestingItemsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 88, Short.MAX_VALUE) .addGap(0, 30, Short.MAX_VALUE)
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -124,17 +114,15 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
void configurePanel(boolean selected, int[] indicesSelected) { void configurePanel(boolean selected, int[] indicesSelected) {
boolean hasInterestingItems = interestingItemsList.getModel().getSize() > 0; boolean hasInterestingItems = isFilterSupported();
interestingItemsCheckbox.setEnabled(hasInterestingItems); interestingItemsCheckbox.setEnabled(hasInterestingItems);
interestingItemsCheckbox.setSelected(selected && hasInterestingItems); interestingItemsCheckbox.setSelected(selected && hasInterestingItems);
if (interestingItemsCheckbox.isEnabled() && interestingItemsCheckbox.isSelected()) { if (interestingItemsCheckbox.isEnabled() && interestingItemsCheckbox.isSelected()) {
interestingItemsScrollPane.setEnabled(true);
interestingItemsList.setEnabled(true); interestingItemsList.setEnabled(true);
if (indicesSelected != null) { // if (indicesSelected != null) {
interestingItemsList.setSelectedIndices(indicesSelected); // interestingItemsList.setSelectedIndices(indicesSelected);
} // }
} else { } else {
interestingItemsScrollPane.setEnabled(false);
interestingItemsList.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."}) @NbBundle.Messages({"InterestingItemsFilterPanel.error.text=At least one interesting file set name must be selected."})
@Override @Override
String checkForError() { String checkForError() {
if (interestingItemsCheckbox.isSelected() && interestingItemsList.getSelectedValuesList().isEmpty()) { if (interestingItemsCheckbox.isSelected() && interestingItemsList.getSelectedElements().isEmpty()) {
return Bundle.InterestingItemsFilterPanel_error_text(); return Bundle.InterestingItemsFilterPanel_error_text();
} }
return ""; return "";
@ -163,22 +151,46 @@ final class InterestingItemsFilterPanel extends AbstractDiscoveryFilterPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox interestingItemsCheckbox; private javax.swing.JCheckBox interestingItemsCheckbox;
private javax.swing.JList<String> interestingItemsList;
private javax.swing.JScrollPane interestingItemsScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
JList<?> getList() {
return interestingItemsList;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
if (interestingItemsCheckbox.isSelected()) { if (interestingItemsCheckbox.isSelected()) {
return new SearchFiltering.InterestingFileSetFilter(interestingItemsList.getSelectedValuesList()); List<String> itemsList = interestingItemsList.getSelectedElements();
return new SearchFiltering.InterestingFileSetFilter(itemsList);
} }
return null; 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();
}
} }

View File

@ -21,12 +21,13 @@ package org.sleuthkit.autopsy.discovery.ui;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; 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 { final class KnownAccountTypeFilterPanel extends AbstractDiscoveryFilterPanel {
@ -97,11 +98,6 @@ final class KnownAccountTypeFilterPanel extends AbstractDiscoveryFilterPanel {
private javax.swing.JCheckBox knownAccountType; private javax.swing.JCheckBox knownAccountType;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@Override
JList<?> getList() {
return null;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
@ -115,4 +111,24 @@ final class KnownAccountTypeFilterPanel extends AbstractDiscoveryFilterPanel {
boolean hasPanel() { boolean hasPanel() {
return false; 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;
}
} }

View File

@ -48,45 +48,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="objectsScrollPane" alignment="0" pref="300" max="32767" attributes="0"/> <EmptySpace min="0" pref="250" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="objectsScrollPane" pref="64" max="32767" attributes="0"/> <EmptySpace min="0" pref="30" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="objectsScrollPane">
<Properties>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[27, 27]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="objectsList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DefaultListModel&lt;JCheckBox&gt;()" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 32767]"/>
</Property>
<Property name="visibleRowCount" type="int" value="2"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;JCheckBox&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -18,18 +18,17 @@
*/ */
package org.sleuthkit.autopsy.discovery.ui; package org.sleuthkit.autopsy.discovery.ui;
import java.util.ArrayList;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -41,6 +40,7 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(ObjectDetectedFilterPanel.class.getName()); private final static Logger logger = Logger.getLogger(ObjectDetectedFilterPanel.class.getName());
private static final CheckBoxListPanel<String> objectsList = new CheckBoxListPanel<>();
/** /**
* Creates new form ObjectDetectedFilter. * Creates new form ObjectDetectedFilter.
@ -48,9 +48,8 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
ObjectDetectedFilterPanel() { ObjectDetectedFilterPanel() {
initComponents(); initComponents();
objectsList.setCellRenderer(new CheckboxCellRenderer(objectsCheckbox));
objectsList.setSelectionModel(new CheckboxListSelectionModel(objectsList));
setUpObjectFilter(); setUpObjectFilter();
add(objectsList);
} }
/** /**
@ -58,14 +57,11 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpObjectFilter() { private void setUpObjectFilter() {
int count = 0;
try { try {
DefaultListModel<JCheckBox> objListModel = (DefaultListModel<JCheckBox>) objectsList.getModel(); objectsList.clearList();
objListModel.removeAllElements();
List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION); List<String> setNames = DiscoveryUiUtils.getSetNames(BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION);
for (String name : setNames) { for (String name : setNames) {
objListModel.add(count, new JCheckBox(name)); objectsList.addElement(name, null, null);
count++;
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error loading object detected set names", ex); logger.log(Level.SEVERE, "Error loading object detected set names", ex);
@ -84,8 +80,6 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
objectsCheckbox = new javax.swing.JCheckBox(); 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 org.openide.awt.Mnemonics.setLocalizedText(objectsCheckbox, org.openide.util.NbBundle.getMessage(ObjectDetectedFilterPanel.class, "ObjectDetectedFilterPanel.text")); // NOI18N
objectsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25)); objectsCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
@ -103,24 +97,15 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
setMinimumSize(new java.awt.Dimension(250, 30)); setMinimumSize(new java.awt.Dimension(250, 30));
setPreferredSize(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<JCheckBox>());
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); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(objectsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE) .addGap(0, 30, Short.MAX_VALUE)
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -131,24 +116,20 @@ final class ObjectDetectedFilterPanel extends AbstractDiscoveryFilterPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox objectsCheckbox; private javax.swing.JCheckBox objectsCheckbox;
private javax.swing.JList<JCheckBox> objectsList;
private javax.swing.JScrollPane objectsScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
void configurePanel(boolean selected, int[] indicesSelected) { void configurePanel(boolean selected, int[] indicesSelected) {
boolean hasObjects = objectsList.getModel().getSize() > 0; boolean hasObjects = isFilterSupported();
objectsCheckbox.setEnabled(hasObjects); objectsCheckbox.setEnabled(hasObjects);
objectsCheckbox.setSelected(selected && hasObjects); objectsCheckbox.setSelected(selected && hasObjects);
if (objectsCheckbox.isEnabled() && objectsCheckbox.isSelected()) { if (objectsCheckbox.isEnabled() && objectsCheckbox.isSelected()) {
objectsScrollPane.setEnabled(true);
objectsList.setEnabled(true); objectsList.setEnabled(true);
if (indicesSelected != null) { // if (indicesSelected != null) {
objectsList.setSelectedIndices(indicesSelected); // objectsList.setSelectedIndices(indicesSelected);
} // }
} else { } else {
objectsScrollPane.setEnabled(false);
objectsList.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."}) @NbBundle.Messages({"ObjectDetectedFilterPanel.error.text=At least one object type name must be selected."})
@Override @Override
String checkForError() { String checkForError() {
if (objectsCheckbox.isSelected() && objectsList.getSelectedValuesList().isEmpty()) { if (objectsCheckbox.isSelected() && objectsList.getSelectedElements().isEmpty()) {
return Bundle.ObjectDetectedFilterPanel_error_text(); return Bundle.ObjectDetectedFilterPanel_error_text();
} }
return ""; return "";
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
JList<?> getList() {
return objectsList;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
if (objectsCheckbox.isSelected()) { if (objectsCheckbox.isSelected()) {
List<String> objectDetectedList = new ArrayList<>(); List<String> objectDetectedList = objectsList.getSelectedElements();
for (JCheckBox checkbox : objectsList.getSelectedValuesList()) {
objectDetectedList.add(checkbox.getName());
}
return new SearchFiltering.ObjectDetectionFilter(objectDetectedList); return new SearchFiltering.ObjectDetectionFilter(objectDetectedList);
} }
return null; 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();
}
} }

View File

@ -24,7 +24,7 @@ import java.util.List;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
@ -311,12 +311,6 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
return results; return results;
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override
JList<?> getList() {
return parentList;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
@ -325,4 +319,24 @@ final class ParentFolderFilterPanel extends AbstractDiscoveryFilterPanel {
} }
return null; 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;
}
} }

View File

@ -45,44 +45,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="crFrequencyScrollPane" pref="300" max="32767" attributes="0"/> <EmptySpace min="0" pref="250" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <EmptySpace min="0" pref="30" max="32767" attributes="0"/>
<Component id="crFrequencyScrollPane" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="crFrequencyScrollPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[27, 27]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="crFrequencyList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DefaultListModel&lt;Frequency&gt;()" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="visibleRowCount" type="int" value="5"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;Frequency&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -18,18 +18,18 @@
*/ */
package org.sleuthkit.autopsy.discovery.ui; package org.sleuthkit.autopsy.discovery.ui;
import javax.swing.DefaultListModel; import java.util.List;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import org.sleuthkit.autopsy.discovery.search.SearchData; 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.SearchData.Type;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
/** /**
* Panel to allow configuration of the Past Occurrences filter. * 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 static final long serialVersionUID = 1L;
private final Type type; private final Type type;
private static final CheckBoxListPanel<SearchData.Frequency> crFrequencyList = new CheckBoxListPanel<>();
/** /**
* Creates new form PastOccurrencesFilterPanel. * Creates new form PastOccurrencesFilterPanel.
@ -47,6 +48,7 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
initComponents(); initComponents();
this.type = type; this.type = type;
setUpFrequencyFilter(); setUpFrequencyFilter();
add(crFrequencyList);
} }
/** /**
@ -59,8 +61,6 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
pastOccurrencesCheckbox = new javax.swing.JCheckBox(); 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 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)); pastOccurrencesCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
@ -75,24 +75,15 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
setMinimumSize(new java.awt.Dimension(250, 30)); setMinimumSize(new java.awt.Dimension(250, 30));
setPreferredSize(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<Frequency>());
crFrequencyList.setEnabled(false);
crFrequencyList.setVisibleRowCount(5);
crFrequencyScrollPane.setViewportView(crFrequencyList);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGap(0, 30, Short.MAX_VALUE)
.addComponent(crFrequencyScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -105,27 +96,23 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpFrequencyFilter() { private void setUpFrequencyFilter() {
int count = 0; crFrequencyList.clearList();
DefaultListModel<SearchData.Frequency> frequencyListModel = (DefaultListModel<SearchData.Frequency>) crFrequencyList.getModel();
frequencyListModel.removeAllElements();
if (!CentralRepository.isEnabled()) { if (!CentralRepository.isEnabled()) {
if (type != Type.DOMAIN) { if (type != Type.DOMAIN) {
for (SearchData.Frequency freq : SearchData.Frequency.getOptionsForFilteringWithoutCr()) { for (SearchData.Frequency freq : SearchData.Frequency.getOptionsForFilteringWithoutCr()) {
frequencyListModel.add(count, freq); crFrequencyList.addElement(freq.toString(), null, freq);
} }
} }
} else { } else {
for (SearchData.Frequency freq : SearchData.Frequency.getOptionsForFilteringWithCr()) { for (SearchData.Frequency freq : SearchData.Frequency.getOptionsForFilteringWithCr()) {
if (type != Type.DOMAIN || freq != SearchData.Frequency.KNOWN) { 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 // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JList<Frequency> crFrequencyList;
private javax.swing.JScrollPane crFrequencyScrollPane;
private javax.swing.JCheckBox pastOccurrencesCheckbox; private javax.swing.JCheckBox pastOccurrencesCheckbox;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ -137,13 +124,11 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
pastOccurrencesCheckbox.setSelected(selected && canBeFilteredOn); pastOccurrencesCheckbox.setSelected(selected && canBeFilteredOn);
if (pastOccurrencesCheckbox.isEnabled() && pastOccurrencesCheckbox.isSelected()) { if (pastOccurrencesCheckbox.isEnabled() && pastOccurrencesCheckbox.isSelected()) {
crFrequencyScrollPane.setEnabled(true);
crFrequencyList.setEnabled(true); crFrequencyList.setEnabled(true);
if (indicesSelected != null) { // if (indicesSelected != null) {
crFrequencyList.setSelectedIndices(indicesSelected); // crFrequencyList.setSelectedIndices(indicesSelected);
} // }
} else { } else {
crFrequencyScrollPane.setEnabled(false);
crFrequencyList.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."}) @NbBundle.Messages({"PastOccurrencesFilterPanel.error.text=At least one value in the past occurrence filter must be selected."})
@Override @Override
String checkForError() { String checkForError() {
if (pastOccurrencesCheckbox.isSelected() && crFrequencyList.getSelectedValuesList().isEmpty()) { if (pastOccurrencesCheckbox.isSelected() && crFrequencyList.getSelectedElements().isEmpty()) {
return Bundle.PastOccurrencesFilterPanel_error_text(); return Bundle.PastOccurrencesFilterPanel_error_text();
} }
return ""; return "";
@ -171,16 +156,43 @@ final class PastOccurrencesFilterPanel extends AbstractDiscoveryFilterPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
JList<?> getList() { AbstractFilter getFilter() {
return crFrequencyList; if (pastOccurrencesCheckbox.isSelected()) {
List<SearchData.Frequency> frequencies = crFrequencyList.getSelectedElements();
return new SearchFiltering.FrequencyFilter(frequencies);
}
return null;
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { void removeListeners() {
if (pastOccurrencesCheckbox.isSelected()) { super.removeListeners();
return new SearchFiltering.FrequencyFilter(crFrequencyList.getSelectedValuesList()); 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();
}
} }

View File

@ -7,17 +7,11 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="PreviouslyNotableFilterPanel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/discovery/ui/Bundle.properties" key="PreviouslyNotableFilterPanel.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[255, 25]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[0, 25]"/> <Dimension value="[0, 25]"/>
</Property> </Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/> <Property name="name" type="java.lang.String" value="" noResource="true"/>
<Property name="opaque" type="boolean" value="false"/> <Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[255, 25]"/>
</Property>
<Property name="requestFocusEnabled" type="boolean" value="false"/> <Property name="requestFocusEnabled" type="boolean" value="false"/>
</Properties> </Properties>
</Component> </Component>

View File

@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.discovery.ui;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
@ -103,11 +103,6 @@ final class PreviouslyNotableFilterPanel extends AbstractDiscoveryFilterPanel {
private javax.swing.JCheckBox previouslyNotableCheckbox; private javax.swing.JCheckBox previouslyNotableCheckbox;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@Override
JList<?> getList() {
return null;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
@ -121,4 +116,24 @@ final class PreviouslyNotableFilterPanel extends AbstractDiscoveryFilterPanel {
boolean hasPanel() { boolean hasPanel() {
return false; 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;
}
} }

View File

@ -48,47 +48,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="sizeScrollPane" max="32767" attributes="0"/> <EmptySpace min="0" pref="250" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <EmptySpace min="0" pref="30" max="32767" attributes="0"/>
<Component id="sizeScrollPane" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="sizeScrollPane">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[27, 27]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="sizeList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DefaultListModel&lt;FileSize&gt;()" type="code"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[32767, 32767]"/>
</Property>
<Property name="visibleRowCount" type="int" value="5"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;FileSize&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -21,15 +21,15 @@ package org.sleuthkit.autopsy.discovery.ui;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchData; import org.sleuthkit.autopsy.discovery.search.SearchData;
import org.sleuthkit.autopsy.discovery.search.SearchData.FileSize; import org.sleuthkit.autopsy.discovery.search.SearchData.FileSize;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
import org.sleuthkit.autopsy.guiutils.CheckBoxListPanel;
/** /**
* Panel to allow configuration of the Size Filter. * Panel to allow configuration of the Size Filter.
@ -37,6 +37,7 @@ import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
final class SizeFilterPanel extends AbstractDiscoveryFilterPanel { final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final CheckBoxListPanel<FileSize> sizeList = new CheckBoxListPanel<>();
/** /**
* Creates new form SizeFilterPanel. * Creates new form SizeFilterPanel.
@ -47,6 +48,7 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
SizeFilterPanel(SearchData.Type type) { SizeFilterPanel(SearchData.Type type) {
initComponents(); initComponents();
setUpSizeFilter(type); setUpSizeFilter(type);
add(sizeList);
} }
/** /**
@ -59,8 +61,6 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
private void initComponents() { private void initComponents() {
sizeCheckbox = new javax.swing.JCheckBox(); 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 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)); sizeCheckbox.setMaximumSize(new java.awt.Dimension(150, 25));
@ -78,25 +78,15 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
setName(""); // NOI18N setName(""); // NOI18N
setPreferredSize(new java.awt.Dimension(250, 30)); setPreferredSize(new java.awt.Dimension(250, 30));
sizeScrollPane.setPreferredSize(new java.awt.Dimension(27, 27));
sizeList.setModel(new DefaultListModel<FileSize>());
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); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGap(0, 30, Short.MAX_VALUE)
.addComponent(sizeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -107,8 +97,6 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox sizeCheckbox; private javax.swing.JCheckBox sizeCheckbox;
private javax.swing.JList<FileSize> sizeList;
private javax.swing.JScrollPane sizeScrollPane;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@ -116,13 +104,11 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
void configurePanel(boolean selected, int[] indicesSelected) { void configurePanel(boolean selected, int[] indicesSelected) {
sizeCheckbox.setSelected(selected); sizeCheckbox.setSelected(selected);
if (sizeCheckbox.isEnabled() && sizeCheckbox.isSelected()) { if (sizeCheckbox.isEnabled() && sizeCheckbox.isSelected()) {
sizeScrollPane.setEnabled(true);
sizeList.setEnabled(true); sizeList.setEnabled(true);
if (indicesSelected != null) { // if (indicesSelected != null) {
sizeList.setSelectedIndices(indicesSelected); // sizeList.setSelectedIndices(indicesSelected);
} // }
} else { } else {
sizeScrollPane.setEnabled(false);
sizeList.setEnabled(false); sizeList.setEnabled(false);
} }
} }
@ -143,12 +129,12 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
*/ */
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
private void setUpSizeFilter(SearchData.Type fileType) { private void setUpSizeFilter(SearchData.Type fileType) {
int count = 0; int insertIndex = 0;
DefaultListModel<FileSize> sizeListModel = (DefaultListModel<FileSize>) sizeList.getModel(); // DefaultListModel<FileSizeItem> sizeListModel = (DefaultListModel<FileSizeItem>) sizeList.getModel();
sizeListModel.removeAllElements(); sizeList.removeAll();
if (null == fileType) { if (null == fileType) {
for (FileSize size : FileSize.values()) { for (FileSize size : FileSize.values()) {
sizeListModel.add(count, size); sizeList.addElement(size.toString(), null, size);
} }
} else { } else {
List<SearchData.FileSize> sizes; List<SearchData.FileSize> sizes;
@ -167,7 +153,7 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
break; break;
} }
for (FileSize size : sizes) { for (FileSize size : sizes) {
sizeListModel.add(count, size); sizeList.addElement(size.toString(), null, size);
} }
} }
} }
@ -176,7 +162,7 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
@Override @Override
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
String checkForError() { String checkForError() {
if (sizeCheckbox.isSelected() && sizeList.getSelectedValuesList().isEmpty()) { if (sizeCheckbox.isSelected() && sizeList.getSelectedElements().isEmpty()) {
return Bundle.SizeFilterPanel_error_text(); return Bundle.SizeFilterPanel_error_text();
} }
return ""; return "";
@ -185,16 +171,43 @@ final class SizeFilterPanel extends AbstractDiscoveryFilterPanel {
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
JList<?> getList() { AbstractFilter getFilter() {
return sizeList; if (sizeCheckbox.isSelected()) {
List<FileSize> fileSizes = sizeList.getSelectedElements();
return new SearchFiltering.SizeFilter(fileSizes);
}
return null;
} }
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { void removeListeners() {
if (sizeCheckbox.isSelected()) { super.removeListeners();
return new SearchFiltering.SizeFilter(sizeList.getSelectedValuesList()); 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();
}
} }

View File

@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.discovery.ui;
import org.sleuthkit.autopsy.discovery.search.AbstractFilter; import org.sleuthkit.autopsy.discovery.search.AbstractFilter;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.event.ListSelectionListener;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.discovery.search.SearchFiltering; import org.sleuthkit.autopsy.discovery.search.SearchFiltering;
@ -98,11 +98,6 @@ final class UserCreatedFilterPanel extends AbstractDiscoveryFilterPanel {
private javax.swing.JCheckBox userCreatedCheckbox; private javax.swing.JCheckBox userCreatedCheckbox;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@Override
JList<?> getList() {
return null;
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override
AbstractFilter getFilter() { AbstractFilter getFilter() {
@ -116,4 +111,24 @@ final class UserCreatedFilterPanel extends AbstractDiscoveryFilterPanel {
boolean hasPanel() { boolean hasPanel() {
return false; 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;
}
} }

View File

@ -27,6 +27,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.event.ListSelectionListener;
/** /**
* A panel for showing any object in a check box list. * A panel for showing any object in a check box list.
@ -54,7 +55,7 @@ public final class CheckBoxListPanel<T> extends javax.swing.JPanel {
* *
* @param displayName display name for the checkbox * @param displayName display name for the checkbox
* @param icon * @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) { public void addElement(String displayName, Icon icon, T obj) {
ObjectCheckBox<T> newCheckBox = new ObjectCheckBox<>(displayName, icon, true, obj); ObjectCheckBox<T> newCheckBox = new ObjectCheckBox<>(displayName, icon, true, obj);
@ -106,8 +107,8 @@ public final class CheckBoxListPanel<T> extends javax.swing.JPanel {
* Sets the selected items within the checkbox list panel. * Sets the selected items within the checkbox list panel.
* *
* @param selected The items that should be selected. If the checkbox data * @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 * is present in this list, it will be selected, otherwise
* deselected. * it will be deselected.
*/ */
public void setSelectedElements(List<T> selected) { public void setSelectedElements(List<T> selected) {
Set<T> toSelect = selected == null ? Collections.emptySet() : new HashSet<>(selected); Set<T> toSelect = selected == null ? Collections.emptySet() : new HashSet<>(selected);
@ -158,6 +159,18 @@ public final class CheckBoxListPanel<T> extends javax.swing.JPanel {
titleLabel.setIcon(icon); 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. * 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 * WARNING: Do NOT modify this code. The content of this method is always
@ -252,10 +265,10 @@ public final class CheckBoxListPanel<T> extends javax.swing.JPanel {
/** /**
* Constructs a new ObjectCheckBox * Constructs a new ObjectCheckBox
* *
* @param displayName String to show as the check box label * @param displayName String to show as the check box label
* @param icon Icon to show before the check box (may be null) * @param icon Icon to show before the check box (may be null)
* @param initialState Sets the initial state of the check box * @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) { ObjectCheckBox(String displayName, Icon icon, boolean initialState, T object) {
this.displayName = displayName; this.displayName = displayName;