From 73b39c6360d84f02275b9b716e461f7d85bf5f41 Mon Sep 17 00:00:00 2001 From: esaunders Date: Mon, 8 Apr 2019 16:19:11 -0400 Subject: [PATCH 1/5] Added BaseChildFactory class that can provide paging and filtering support to subclasses. --- .../autopsy/core/UserPreferences.java | 19 ++ .../autopsy/datamodel/BaseChildFactory.java | 223 ++++++++++++++++++ .../datamodel/KnownAndSlackFilter.java | 60 +++++ 3 files changed, 302 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 9efcce9f7d..b58e310fe0 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -76,6 +76,7 @@ public final class UserPreferences { public static final String DISPLAY_TRANSLATED_NAMES = "DisplayTranslatedNames"; public static final String EXTERNAL_HEX_EDITOR_PATH = "ExternalHexEditorPath"; public static final String SOLR_MAX_JVM_SIZE = "SolrMaxJVMSize"; + public static final String RESULTS_TABLE_PAGE_SIZE = "ResultsTablePageSize"; // Prevent instantiation. private UserPreferences() { @@ -491,6 +492,24 @@ public final class UserPreferences { preferences.putInt(SOLR_MAX_JVM_SIZE, maxSize); } + /** + * Get the maximum number of results to display in a result table. + * + * @return Saved value or default (0) which indicates no max. + */ + public static int getResultsTablePageSize() { + return preferences.getInt(RESULTS_TABLE_PAGE_SIZE, 0); + } + + /** + * Set the maximum number of results to display in a result table. + * + * @param pageSize + */ + public static void setResultsTablePageSize(int pageSize) { + preferences.putInt(RESULTS_TABLE_PAGE_SIZE, pageSize); + } + /** * Set the HdX path. * diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java new file mode 100644 index 0000000000..c192d88a98 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java @@ -0,0 +1,223 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.openide.nodes.ChildFactory; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.datamodel.Content; + +/** + * Abstract child factory that provides paging and filtering functionality + * to subclasses. + * @param + */ +public abstract class BaseChildFactory extends ChildFactory.Detachable { + + private final Predicate filter; + private boolean isPageChangeEvent; + + private final PagingSupport pagingSupport; + + /** + * This static map is used to facilitate communication between the UI + * and the child factory. + */ + public static Map nodeNameToEventBusMap = new ConcurrentHashMap<>(); + + public BaseChildFactory(String nodeName) { + pagingSupport = new PagingSupport(nodeName); + isPageChangeEvent = false; + filter = new KnownAndSlackFilter<>(); + } + + @Override + protected void addNotify() { + onAdd(); + pagingSupport.initialize(); + } + + @Override + protected void removeNotify() { + onRemove(); + pagingSupport.destroy(); + } + + /** + * Subclasses implement this to construct a collection of keys. + * @return + */ + protected abstract List makeKeys(); + + /** + * Subclasses implement this to initialize any required resources. + */ + protected abstract void onAdd(); + + /** + * Subclasses implement this to clean up any resources they + * acquired in onAdd() + */ + protected abstract void onRemove(); + + @Override + protected boolean createKeys(List toPopulate) { + // For page chage events we simply return the previously calculated + // keys, otherwise we make a new set of keys. + if (!isPageChangeEvent) { + List allKeys = makeKeys(); + + // Filter keys + allKeys.stream().filter(filter).collect(Collectors.toList()); + + pagingSupport.splitKeysIntoPages(allKeys); + } + + toPopulate.addAll(pagingSupport.getCurrentPage()); + + // Reset page change event flag + isPageChangeEvent = false; + + return true; + } + + /** + * Class that supplies paging related functionality to the base + * child factory class. + */ + class PagingSupport { + + private final String nodeName; + private final int pageSize; + private int currentPage; + private List> pages; + private EventBus bus; + + /** + * Construct PagingSupport instance for the given node name. + * @param nodeName Name of the node in the tree for which results + * are being displayed. The node name is used to allow communication + * between the UI and the ChildFactory via an EventBus. + */ + PagingSupport(String nodeName) { + pageSize = UserPreferences.getResultsTablePageSize(); + this.currentPage = 1; + pages = new ArrayList<>(); + this.nodeName = nodeName; + } + + void initialize() { + if (pageSize > 0) { + // Only configure an EventBus if paging functionality is enabled. + bus = new EventBus(nodeName); + nodeNameToEventBusMap.put(bus.identifier(), bus); + bus.register(this); + } + } + + void destroy() { + if (bus != null) { + nodeNameToEventBusMap.remove(bus.identifier()); + bus.unregister(this); + bus.post(new PagingDestroyedEvent()); + bus = null; + } + } + + /** + * Get the list of keys at the current page. + * @return List of keys. + */ + List getCurrentPage() { + if (pages.size() > 0) { + return pages.get(currentPage - 1); + } + + return Collections.emptyList(); + } + + /** + * Split the given collection of keys into pages based on page size. + * @param keys + */ + void splitKeysIntoPages(List keys) { + int oldPageCount = pages.size(); + + /** + * If pageSize is set split keys into pages, + * otherwise create a single page containing all keys. + */ + pages = Lists.partition(keys, pageSize > 0 ? pageSize : keys.size()); + if (pages.size() != oldPageCount) { + // Number of pages has changed so we need to send out a notification. + bus.post(new PageCountChangeEvent(pages.size())); + } + } + + @Subscribe + private void subscribeToPageChange(PageChangeEvent event) { + // Receives page change events from UI components and + // triggers a refresh in the child factory. + if (event != null) { + currentPage = event.getPageNumber(); + isPageChangeEvent = true; + refresh(true); + } + } + } + + public static class PageChangeEvent { + + private final int pageNumber; + + public PageChangeEvent(int newPageNumber) { + pageNumber = newPageNumber; + } + + public int getPageNumber() { + return pageNumber; + } + } + + public static class PageCountChangeEvent { + + private final int pageCount; + + public PageCountChangeEvent(int newPageCount) { + pageCount = newPageCount; + } + + public int getPageCount() { + return pageCount; + } + } + + public static class PagingDestroyedEvent { + + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java b/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java new file mode 100644 index 0000000000..2d780328be --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java @@ -0,0 +1,60 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2019 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import java.util.function.Predicate; +import org.openide.util.Exceptions; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.datamodel.TskData; + +/** + * + */ +class KnownAndSlackFilter implements Predicate { + + @Override + public boolean test(T t) { + AbstractFile af = null; + + if (t instanceof BlackboardArtifact) { + try { + af = ((BlackboardArtifact) (t)).getSleuthkitCase().getAbstractFileById(((BlackboardArtifact) t).getObjectID()); + } catch (TskCoreException ex) { + Exceptions.printStackTrace(ex); + } + } else if (t instanceof AbstractFile) { + af = (AbstractFile) t; + } + + if (af != null) { + if (af.getKnown() == TskData.FileKnown.KNOWN && UserPreferences.hideKnownFilesInViewsTree()) { + return false; + } + if (af.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) && UserPreferences.hideSlackFilesInViewsTree()) { + return false; + } + } + + return true; + } +} From 07a375bd12047f17dd6e03596e87accb4d64d2ae Mon Sep 17 00:00:00 2001 From: esaunders Date: Mon, 8 Apr 2019 16:56:36 -0400 Subject: [PATCH 2/5] Moved event classes to make them accessible. --- .../corecomponents/DataResultViewerTable.java | 290 +++++++++++++++++- .../autopsy/datamodel/BaseChildFactory.java | 123 ++++---- 2 files changed, 346 insertions(+), 67 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index bf18c4b831..a6acc8f9ec 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.corecomponents; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; import java.awt.Component; import java.awt.Cursor; import java.awt.FontMetrics; @@ -26,6 +28,7 @@ import java.awt.dnd.DnDConstants; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.FeatureDescriptor; +import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -38,6 +41,8 @@ import java.util.TreeSet; import java.util.logging.Level; import java.util.prefs.Preferences; import javax.swing.ImageIcon; +import javax.swing.InputVerifier; +import javax.swing.JComponent; import javax.swing.JTable; import javax.swing.ListSelectionModel; import static javax.swing.SwingConstants.CENTER; @@ -61,6 +66,10 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Node.Property; +import org.openide.nodes.NodeEvent; +import org.openide.nodes.NodeListener; +import org.openide.nodes.NodeMemberEvent; +import org.openide.nodes.NodeReorderEvent; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; @@ -70,6 +79,10 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; +import org.sleuthkit.autopsy.datamodel.BaseChildFactory; +import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageChangeEvent; +import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageCountChangeEvent; +import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PagingDestroyedEvent; /** * A tabular result viewer that displays the children of the given root node @@ -95,7 +108,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false)); private static final ImageIcon NOTABLE_ICON_SCORE = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false)); @NbBundle.Messages("DataResultViewerTable.firstColLbl=Name") - static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl(); + static protected final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl(); private final String title; private final Map columnMap; private final Map> propertiesMap; @@ -103,6 +116,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private final TableListener outlineViewListener; private final IconRendererTableListener iconRendererListener; private Node rootNode; + private final Map pagingSupportMap = new HashMap<>(); + private PagingSupport pagingSupport = null; /** * Constructs a tabular result viewer that displays the children of the @@ -144,11 +159,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer { this.columnMap = new HashMap<>(); this.propertiesMap = new TreeMap<>(); + this.pagingSupport = new PagingSupport(); + /* * Execute the code generated by the GUI builder. */ initComponents(); + this.pagingSupport.updateControls(); + /* * Configure the child OutlineView (explorer view) component. */ @@ -252,6 +271,40 @@ public class DataResultViewerTable extends AbstractDataResultViewer { */ if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) { this.rootNode = rootNode; + pagingSupport = pagingSupportMap.get(rootNode.getName()); + if (pagingSupport == null) { + EventBus bus = BaseChildFactory.nodeNameToEventBusMap.get(rootNode.getName()); + pagingSupport = new PagingSupport(); + pagingSupport.registerWithEventBus(bus); + pagingSupportMap.put(rootNode.getName(), pagingSupport); + } + pagingSupport.updateControls(); + + rootNode.addNodeListener(new NodeListener() { + @Override + public void childrenAdded(NodeMemberEvent nme) { + SwingUtilities.invokeLater(() -> { + setCursor(null); + }); + } + + @Override + public void childrenRemoved(NodeMemberEvent nme) { + } + + @Override + public void childrenReordered(NodeReorderEvent nre) { + } + + @Override + public void nodeDestroyed(NodeEvent ne) { + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + } + }); + this.getExplorerManager().setRootContext(this.rootNode); setupTable(); } else { @@ -665,6 +718,107 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } } + private class PagingSupport { + + private int currentPage; + private int totalPages; + private EventBus eb; + + PagingSupport() { + currentPage = 1; + totalPages = 0; + eb = null; + } + + void reset() { + currentPage = 1; + totalPages = 0; + + if (eb != null) { + eb.unregister(this); + eb = null; + } + updateControls(); + } + + void registerWithEventBus(EventBus bus) { + if (eb == bus) { + return; + } + + if (bus != null) { + eb = bus; + eb.register(this); + } + + updateControls(); + } + + void nextPage() { + currentPage++; + postPageChangeEvent(); + } + + void previousPage() { + currentPage--; + postPageChangeEvent(); + } + + void gotoPage() { + currentPage = Integer.decode(gotoPageTextField.getText()); + postPageChangeEvent(); + } + + void postPageChangeEvent() { + if (eb != null) { + eb.post(new PageChangeEvent(currentPage)); + setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + updateControls(); + } + + boolean isValidPage() { + if (gotoPageTextField.getText().length() > 0) { + Integer value = Integer.decode(gotoPageTextField.getText()); + return value >= 1 && value <= totalPages; + } else { + return true; + } + } + + @Subscribe + public void subscribeToPageCountChange(PageCountChangeEvent event) { + if (event != null) { + totalPages = event.getPageCount(); + updateControls(); + } + } + + @Subscribe + public void subscribeToPagingDestroyedEvent(PagingDestroyedEvent event) { + if (eb != null) { + pagingSupportMap.remove(eb.identifier()); + } + } + + private void updateControls() { + if (totalPages == 0) { + pagePrevButton.setEnabled(false); + pageNextButton.setEnabled(false); + pageNumLabel.setText(""); + gotoPageTextField.setText(""); + gotoPageTextField.setEnabled(false); + } else { + pageNumLabel.setText(NbBundle.getMessage(this.getClass(), "DataResultViewerThumbnail.pageNumbers.curOfTotal", + Integer.toString(currentPage), Integer.toString(totalPages))); + + pageNextButton.setEnabled(!(currentPage == totalPages)); + pagePrevButton.setEnabled(!(currentPage == 1)); + gotoPageTextField.setEnabled(true); + } + } + } + /** * Listener which sets the custom icon renderer on columns which contain * icons instead of text when a column is added. @@ -1033,21 +1187,133 @@ public class DataResultViewerTable extends AbstractDataResultViewer { // //GEN-BEGIN:initComponents private void initComponents() { + pageLabel = new javax.swing.JLabel(); + pageNumLabel = new javax.swing.JLabel(); + pagesLabel = new javax.swing.JLabel(); + pagePrevButton = new javax.swing.JButton(); + pageNextButton = new javax.swing.JButton(); outlineView = new OutlineView(DataResultViewerTable.FIRST_COLUMN_LABEL); + gotoPageLabel = new javax.swing.JLabel(); + gotoPageTextField = new javax.swing.JTextField(); + + pageLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pageLabel.text")); // NOI18N + + pageNumLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pageNumLabel.text")); // NOI18N + + pagesLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pagesLabel.text")); // NOI18N + + pagePrevButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N + pagePrevButton.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pagePrevButton.text")); // NOI18N + pagePrevButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N + pagePrevButton.setFocusable(false); + pagePrevButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + pagePrevButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + pagePrevButton.setPreferredSize(new java.awt.Dimension(55, 23)); + pagePrevButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N + pagePrevButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + pagePrevButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + pagePrevButtonActionPerformed(evt); + } + }); + + pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N + pageNextButton.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pageNextButton.text")); // NOI18N + pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N + pageNextButton.setFocusable(false); + pageNextButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); + pageNextButton.setMaximumSize(new java.awt.Dimension(27, 23)); + pageNextButton.setMinimumSize(new java.awt.Dimension(27, 23)); + pageNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N + pageNextButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + pageNextButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + pageNextButtonActionPerformed(evt); + } + }); + + gotoPageLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.gotoPageLabel.text")); // NOI18N + + gotoPageTextField.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.gotoPageTextField.text")); // NOI18N + gotoPageTextField.setInputVerifier(new InputVerifier() { + @Override + public boolean verify(JComponent input) { + return pagingSupport.isValidPage(); + }}); + gotoPageTextField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + gotoPageTextFieldActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(373, Short.MAX_VALUE) + .addComponent(pageLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(pagesLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(gotoPageLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {pageNextButton, pagePrevButton}); + + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(pageLabel) + .addComponent(pageNumLabel) + .addComponent(pagesLabel) + .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(gotoPageLabel) + .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 324, Short.MAX_VALUE) + .addContainerGap()) + ); + + layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {pageNextButton, pagePrevButton}); + + }// //GEN-END:initComponents + + private void pagePrevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pagePrevButtonActionPerformed + pagingSupport.previousPage(); + }//GEN-LAST:event_pagePrevButtonActionPerformed + + private void pageNextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pageNextButtonActionPerformed + pagingSupport.nextPage(); + }//GEN-LAST:event_pageNextButtonActionPerformed + + private void gotoPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoPageTextFieldActionPerformed + pagingSupport.gotoPage(); + }//GEN-LAST:event_gotoPageTextFieldActionPerformed - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 691, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE) - ); - }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel gotoPageLabel; + private javax.swing.JTextField gotoPageTextField; private org.openide.explorer.view.OutlineView outlineView; + private javax.swing.JLabel pageLabel; + private javax.swing.JButton pageNextButton; + private javax.swing.JLabel pageNumLabel; + private javax.swing.JButton pagePrevButton; + private javax.swing.JLabel pagesLabel; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java index c192d88a98..44033ba0b5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java @@ -33,8 +33,9 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.datamodel.Content; /** - * Abstract child factory that provides paging and filtering functionality - * to subclasses. + * Abstract child factory that provides paging and filtering functionality to + * subclasses. + * * @param */ public abstract class BaseChildFactory extends ChildFactory.Detachable { @@ -45,8 +46,8 @@ public abstract class BaseChildFactory extends ChildFactory.D private final PagingSupport pagingSupport; /** - * This static map is used to facilitate communication between the UI - * and the child factory. + * This static map is used to facilitate communication between the UI and + * the child factory. */ public static Map nodeNameToEventBusMap = new ConcurrentHashMap<>(); @@ -59,9 +60,9 @@ public abstract class BaseChildFactory extends ChildFactory.D @Override protected void addNotify() { onAdd(); - pagingSupport.initialize(); + pagingSupport.initialize(); } - + @Override protected void removeNotify() { onRemove(); @@ -70,7 +71,8 @@ public abstract class BaseChildFactory extends ChildFactory.D /** * Subclasses implement this to construct a collection of keys. - * @return + * + * @return */ protected abstract List makeKeys(); @@ -78,10 +80,10 @@ public abstract class BaseChildFactory extends ChildFactory.D * Subclasses implement this to initialize any required resources. */ protected abstract void onAdd(); - + /** - * Subclasses implement this to clean up any resources they - * acquired in onAdd() + * Subclasses implement this to clean up any resources they acquired in + * onAdd() */ protected abstract void onRemove(); @@ -94,7 +96,7 @@ public abstract class BaseChildFactory extends ChildFactory.D // Filter keys allKeys.stream().filter(filter).collect(Collectors.toList()); - + pagingSupport.splitKeysIntoPages(allKeys); } @@ -107,8 +109,45 @@ public abstract class BaseChildFactory extends ChildFactory.D } /** - * Class that supplies paging related functionality to the base - * child factory class. + * Event used to let subscribers know that the user has + * navigated to a different page. + */ + public static class PageChangeEvent { + + private final int pageNumber; + + public PageChangeEvent(int newPageNumber) { + pageNumber = newPageNumber; + } + + public int getPageNumber() { + return pageNumber; + } + } + + /** + * Event used to let subscribers know that the number of + * pages has changed. + */ + public static class PageCountChangeEvent { + + private final int pageCount; + + public PageCountChangeEvent(int newPageCount) { + pageCount = newPageCount; + } + + public int getPageCount() { + return pageCount; + } + } + + public static class PagingDestroyedEvent { + } + + /** + * Class that supplies paging related functionality to the base child + * factory class. */ class PagingSupport { @@ -120,9 +159,11 @@ public abstract class BaseChildFactory extends ChildFactory.D /** * Construct PagingSupport instance for the given node name. - * @param nodeName Name of the node in the tree for which results - * are being displayed. The node name is used to allow communication - * between the UI and the ChildFactory via an EventBus. + * + * @param nodeName Name of the node in the tree for which results are + * being displayed. The node name is used to allow + * communication between the UI and the ChildFactory via + * an EventBus. */ PagingSupport(String nodeName) { pageSize = UserPreferences.getResultsTablePageSize(); @@ -130,14 +171,14 @@ public abstract class BaseChildFactory extends ChildFactory.D pages = new ArrayList<>(); this.nodeName = nodeName; } - + void initialize() { if (pageSize > 0) { // Only configure an EventBus if paging functionality is enabled. bus = new EventBus(nodeName); nodeNameToEventBusMap.put(bus.identifier(), bus); bus.register(this); - } + } } void destroy() { @@ -146,31 +187,33 @@ public abstract class BaseChildFactory extends ChildFactory.D bus.unregister(this); bus.post(new PagingDestroyedEvent()); bus = null; - } + } } - + /** * Get the list of keys at the current page. + * * @return List of keys. */ List getCurrentPage() { if (pages.size() > 0) { return pages.get(currentPage - 1); } - + return Collections.emptyList(); } - + /** * Split the given collection of keys into pages based on page size. - * @param keys + * + * @param keys */ void splitKeysIntoPages(List keys) { int oldPageCount = pages.size(); /** - * If pageSize is set split keys into pages, - * otherwise create a single page containing all keys. + * If pageSize is set split keys into pages, otherwise create a + * single page containing all keys. */ pages = Lists.partition(keys, pageSize > 0 ? pageSize : keys.size()); if (pages.size() != oldPageCount) { @@ -190,34 +233,4 @@ public abstract class BaseChildFactory extends ChildFactory.D } } } - - public static class PageChangeEvent { - - private final int pageNumber; - - public PageChangeEvent(int newPageNumber) { - pageNumber = newPageNumber; - } - - public int getPageNumber() { - return pageNumber; - } - } - - public static class PageCountChangeEvent { - - private final int pageCount; - - public PageCountChangeEvent(int newPageCount) { - pageCount = newPageCount; - } - - public int getPageCount() { - return pageCount; - } - } - - public static class PagingDestroyedEvent { - - } } From 81e0823ba8e19bf044c348ab51aab9eb329bc462 Mon Sep 17 00:00:00 2001 From: esaunders Date: Tue, 9 Apr 2019 16:47:37 -0400 Subject: [PATCH 3/5] Reverted DataResultViewerTable to original state and added a comment to KnownAndSlackFilter. --- .../corecomponents/DataResultViewerTable.java | 290 +----------------- .../datamodel/KnownAndSlackFilter.java | 3 +- 2 files changed, 14 insertions(+), 279 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index a6acc8f9ec..bf18c4b831 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -18,8 +18,6 @@ */ package org.sleuthkit.autopsy.corecomponents; -import com.google.common.eventbus.EventBus; -import com.google.common.eventbus.Subscribe; import java.awt.Component; import java.awt.Cursor; import java.awt.FontMetrics; @@ -28,7 +26,6 @@ import java.awt.dnd.DnDConstants; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.FeatureDescriptor; -import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -41,8 +38,6 @@ import java.util.TreeSet; import java.util.logging.Level; import java.util.prefs.Preferences; import javax.swing.ImageIcon; -import javax.swing.InputVerifier; -import javax.swing.JComponent; import javax.swing.JTable; import javax.swing.ListSelectionModel; import static javax.swing.SwingConstants.CENTER; @@ -66,10 +61,6 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.nodes.Node.Property; -import org.openide.nodes.NodeEvent; -import org.openide.nodes.NodeListener; -import org.openide.nodes.NodeMemberEvent; -import org.openide.nodes.NodeReorderEvent; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; @@ -79,10 +70,6 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.datamodel.NodeProperty; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; -import org.sleuthkit.autopsy.datamodel.BaseChildFactory; -import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageChangeEvent; -import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PageCountChangeEvent; -import org.sleuthkit.autopsy.datamodel.BaseChildFactory.PagingDestroyedEvent; /** * A tabular result viewer that displays the children of the given root node @@ -108,7 +95,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false)); private static final ImageIcon NOTABLE_ICON_SCORE = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false)); @NbBundle.Messages("DataResultViewerTable.firstColLbl=Name") - static protected final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl(); + static private final String FIRST_COLUMN_LABEL = Bundle.DataResultViewerTable_firstColLbl(); private final String title; private final Map columnMap; private final Map> propertiesMap; @@ -116,8 +103,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { private final TableListener outlineViewListener; private final IconRendererTableListener iconRendererListener; private Node rootNode; - private final Map pagingSupportMap = new HashMap<>(); - private PagingSupport pagingSupport = null; /** * Constructs a tabular result viewer that displays the children of the @@ -159,15 +144,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer { this.columnMap = new HashMap<>(); this.propertiesMap = new TreeMap<>(); - this.pagingSupport = new PagingSupport(); - /* * Execute the code generated by the GUI builder. */ initComponents(); - this.pagingSupport.updateControls(); - /* * Configure the child OutlineView (explorer view) component. */ @@ -271,40 +252,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { */ if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) { this.rootNode = rootNode; - pagingSupport = pagingSupportMap.get(rootNode.getName()); - if (pagingSupport == null) { - EventBus bus = BaseChildFactory.nodeNameToEventBusMap.get(rootNode.getName()); - pagingSupport = new PagingSupport(); - pagingSupport.registerWithEventBus(bus); - pagingSupportMap.put(rootNode.getName(), pagingSupport); - } - pagingSupport.updateControls(); - - rootNode.addNodeListener(new NodeListener() { - @Override - public void childrenAdded(NodeMemberEvent nme) { - SwingUtilities.invokeLater(() -> { - setCursor(null); - }); - } - - @Override - public void childrenRemoved(NodeMemberEvent nme) { - } - - @Override - public void childrenReordered(NodeReorderEvent nre) { - } - - @Override - public void nodeDestroyed(NodeEvent ne) { - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - } - }); - this.getExplorerManager().setRootContext(this.rootNode); setupTable(); } else { @@ -718,107 +665,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer { } } - private class PagingSupport { - - private int currentPage; - private int totalPages; - private EventBus eb; - - PagingSupport() { - currentPage = 1; - totalPages = 0; - eb = null; - } - - void reset() { - currentPage = 1; - totalPages = 0; - - if (eb != null) { - eb.unregister(this); - eb = null; - } - updateControls(); - } - - void registerWithEventBus(EventBus bus) { - if (eb == bus) { - return; - } - - if (bus != null) { - eb = bus; - eb.register(this); - } - - updateControls(); - } - - void nextPage() { - currentPage++; - postPageChangeEvent(); - } - - void previousPage() { - currentPage--; - postPageChangeEvent(); - } - - void gotoPage() { - currentPage = Integer.decode(gotoPageTextField.getText()); - postPageChangeEvent(); - } - - void postPageChangeEvent() { - if (eb != null) { - eb.post(new PageChangeEvent(currentPage)); - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - } - updateControls(); - } - - boolean isValidPage() { - if (gotoPageTextField.getText().length() > 0) { - Integer value = Integer.decode(gotoPageTextField.getText()); - return value >= 1 && value <= totalPages; - } else { - return true; - } - } - - @Subscribe - public void subscribeToPageCountChange(PageCountChangeEvent event) { - if (event != null) { - totalPages = event.getPageCount(); - updateControls(); - } - } - - @Subscribe - public void subscribeToPagingDestroyedEvent(PagingDestroyedEvent event) { - if (eb != null) { - pagingSupportMap.remove(eb.identifier()); - } - } - - private void updateControls() { - if (totalPages == 0) { - pagePrevButton.setEnabled(false); - pageNextButton.setEnabled(false); - pageNumLabel.setText(""); - gotoPageTextField.setText(""); - gotoPageTextField.setEnabled(false); - } else { - pageNumLabel.setText(NbBundle.getMessage(this.getClass(), "DataResultViewerThumbnail.pageNumbers.curOfTotal", - Integer.toString(currentPage), Integer.toString(totalPages))); - - pageNextButton.setEnabled(!(currentPage == totalPages)); - pagePrevButton.setEnabled(!(currentPage == 1)); - gotoPageTextField.setEnabled(true); - } - } - } - /** * Listener which sets the custom icon renderer on columns which contain * icons instead of text when a column is added. @@ -1187,133 +1033,21 @@ public class DataResultViewerTable extends AbstractDataResultViewer { // //GEN-BEGIN:initComponents private void initComponents() { - pageLabel = new javax.swing.JLabel(); - pageNumLabel = new javax.swing.JLabel(); - pagesLabel = new javax.swing.JLabel(); - pagePrevButton = new javax.swing.JButton(); - pageNextButton = new javax.swing.JButton(); outlineView = new OutlineView(DataResultViewerTable.FIRST_COLUMN_LABEL); - gotoPageLabel = new javax.swing.JLabel(); - gotoPageTextField = new javax.swing.JTextField(); - - pageLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pageLabel.text")); // NOI18N - - pageNumLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pageNumLabel.text")); // NOI18N - - pagesLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pagesLabel.text")); // NOI18N - - pagePrevButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N - pagePrevButton.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pagePrevButton.text")); // NOI18N - pagePrevButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N - pagePrevButton.setFocusable(false); - pagePrevButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - pagePrevButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - pagePrevButton.setPreferredSize(new java.awt.Dimension(55, 23)); - pagePrevButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N - pagePrevButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - pagePrevButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - pagePrevButtonActionPerformed(evt); - } - }); - - pageNextButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N - pageNextButton.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.pageNextButton.text")); // NOI18N - pageNextButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N - pageNextButton.setFocusable(false); - pageNextButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - pageNextButton.setMargin(new java.awt.Insets(2, 0, 2, 0)); - pageNextButton.setMaximumSize(new java.awt.Dimension(27, 23)); - pageNextButton.setMinimumSize(new java.awt.Dimension(27, 23)); - pageNextButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N - pageNextButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - pageNextButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - pageNextButtonActionPerformed(evt); - } - }); - - gotoPageLabel.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.gotoPageLabel.text")); // NOI18N - - gotoPageTextField.setText(org.openide.util.NbBundle.getMessage(DataResultViewerTable.class, "DataResultViewerTable.gotoPageTextField.text")); // NOI18N - gotoPageTextField.setInputVerifier(new InputVerifier() { - @Override - public boolean verify(JComponent input) { - return pagingSupport.isValidPage(); - }}); - gotoPageTextField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - gotoPageTextFieldActionPerformed(evt); - } - }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(373, Short.MAX_VALUE) - .addComponent(pageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(pagesLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(gotoPageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); - - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {pageNextButton, pagePrevButton}); - - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) - .addComponent(pageLabel) - .addComponent(pageNumLabel) - .addComponent(pagesLabel) - .addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(gotoPageLabel) - .addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 324, Short.MAX_VALUE) - .addContainerGap()) - ); - - layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {pageNextButton, pagePrevButton}); - - }// //GEN-END:initComponents - - private void pagePrevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pagePrevButtonActionPerformed - pagingSupport.previousPage(); - }//GEN-LAST:event_pagePrevButtonActionPerformed - - private void pageNextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pageNextButtonActionPerformed - pagingSupport.nextPage(); - }//GEN-LAST:event_pageNextButtonActionPerformed - - private void gotoPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoPageTextFieldActionPerformed - pagingSupport.gotoPage(); - }//GEN-LAST:event_gotoPageTextFieldActionPerformed + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 691, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 366, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel gotoPageLabel; - private javax.swing.JTextField gotoPageTextField; private org.openide.explorer.view.OutlineView outlineView; - private javax.swing.JLabel pageLabel; - private javax.swing.JButton pageNextButton; - private javax.swing.JLabel pageNumLabel; - private javax.swing.JButton pagePrevButton; - private javax.swing.JLabel pagesLabel; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java b/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java index 2d780328be..5c97a5a044 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/KnownAndSlackFilter.java @@ -28,7 +28,8 @@ import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; /** - * + * Predicate that can be used to filter known and/or slack files from + * Content collections based on user preferences. */ class KnownAndSlackFilter implements Predicate { From 7b1cb3e1d156f5f73436190136049a934eed412a Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 10 Apr 2019 17:45:05 -0400 Subject: [PATCH 4/5] Codacy fixes. --- .../org/sleuthkit/autopsy/datamodel/BaseChildFactory.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java index 44033ba0b5..8c97208c04 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java @@ -53,6 +53,7 @@ public abstract class BaseChildFactory extends ChildFactory.D public BaseChildFactory(String nodeName) { pagingSupport = new PagingSupport(nodeName); + pagingSupport.initialize(); isPageChangeEvent = false; filter = new KnownAndSlackFilter<>(); } @@ -60,7 +61,6 @@ public abstract class BaseChildFactory extends ChildFactory.D @Override protected void addNotify() { onAdd(); - pagingSupport.initialize(); } @Override @@ -142,6 +142,10 @@ public abstract class BaseChildFactory extends ChildFactory.D } } + /** + * Event used to let subscribers know that paging is no + * longer required. + */ public static class PagingDestroyedEvent { } @@ -196,7 +200,7 @@ public abstract class BaseChildFactory extends ChildFactory.D * @return List of keys. */ List getCurrentPage() { - if (pages.size() > 0) { + if (pages.isEmpty()) { return pages.get(currentPage - 1); } From f54c9aa2ffb0f7252333933a4b73e0c36ff612b8 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 17 Apr 2019 11:48:16 -0400 Subject: [PATCH 5/5] Removed PagingSupport.destroy() and fixed bug in PagingSupport.getCurrentPage(). --- .../autopsy/datamodel/BaseChildFactory.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java index 8c97208c04..555d59b33c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BaseChildFactory.java @@ -66,7 +66,6 @@ public abstract class BaseChildFactory extends ChildFactory.D @Override protected void removeNotify() { onRemove(); - pagingSupport.destroy(); } /** @@ -179,28 +178,23 @@ public abstract class BaseChildFactory extends ChildFactory.D void initialize() { if (pageSize > 0) { // Only configure an EventBus if paging functionality is enabled. - bus = new EventBus(nodeName); - nodeNameToEventBusMap.put(bus.identifier(), bus); + if (nodeNameToEventBusMap.containsKey(nodeName)) { + bus = nodeNameToEventBusMap.get(nodeName); + } else { + bus = new EventBus(nodeName); + nodeNameToEventBusMap.put(bus.identifier(), bus); + } bus.register(this); } } - void destroy() { - if (bus != null) { - nodeNameToEventBusMap.remove(bus.identifier()); - bus.unregister(this); - bus.post(new PagingDestroyedEvent()); - bus = null; - } - } - /** * Get the list of keys at the current page. * * @return List of keys. */ List getCurrentPage() { - if (pages.isEmpty()) { + if (!pages.isEmpty()) { return pages.get(currentPage - 1); }