From 21bb53b223450fdb2d61f8243f67e017b416daf7 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 23 Apr 2018 17:11:39 -0400 Subject: [PATCH] Complete new documentation of core result viewers --- .../DataResultViewer.java | 141 +++++++++++------ .../AbstractDataResultViewer.java | 76 ++++----- .../corecomponents/DataResultViewerTable.java | 146 +++++++++--------- .../DataResultViewerThumbnail.java | 144 ++++++++--------- 4 files changed, 262 insertions(+), 245 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java index d88c979844..a5ace28245 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponentinterfaces/DataResultViewer.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-17 Basis Technology Corp. + * Copyright 2012-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,76 +22,117 @@ import java.awt.Component; import org.openide.nodes.Node; /** - * Interface for the different viewers that show a set of nodes in the - * DataResult area. AbstractDataResultViewer has default implementations for the - * action handlers. + * An interface for result viewers. A result viewer uses a Swing component to + * provide a view of the application data represented by a given NetBeans node. + * Result viewers typically appear in a result view (a DataResultTopComponent) + * docked into the upper right hand side of the main application window. + * + * Typically, a result viewer is a JPanel that displays the child nodes of the + * given node using a NetBeans explorer view as a child component. Such a result + * viewer should use the explorer manager of the ancestor top component to + * connect the lookups of the nodes displayed in the NetBeans explorer view to + * the actions global context. It is strongly recommended that this type of + * result viewer extends the abstract base class AbstractDataResultViewer, which + * will handle some key aspects of working with the ancestor top component's + * explorer manager. + * + * This interface is an extension point, so classes that implement it should + * provide an appropriate ServiceProvider annotation. * */ public interface DataResultViewer { /** - * Set the root node to display in this viewer. When called with null, must - * clear all references to previous nodes. - */ - public void setNode(Node selectedNode); - - /** - * Gets the title of this viewer - */ - public String getTitle(); - - /** - * Get a new instance of DataResultViewer + * Creates a new instance of this result viewer, which allows the + * application to use the capability provided by this result viewer in more + * than one result view. This is done by using the default instance of this + * result viewer as a "factory" for creating other instances. */ public DataResultViewer createInstance(); /** - * Get the Swing component (i.e. JPanel) for this viewer + * Indicates whether this result viewer is able to provide a meaningful view + * of the application data represented by a given node. Typically, indicates + * whether or not this result viewer can use the given node as the root node + * of its child explorer view component. + * + * @param node The node. + * + * @return True or false. + */ + public boolean isSupported(Node node); + + /** + * Sets the node for which this result viewer should provide a view of the + * underlying application data. Typically, this means using the given node + * as the root node of this result viewer's child explorer view component. + * + * @param node The node, may be null. If null, the call to this method is + * equivalent to a call to resetComponent. + */ + public void setNode(Node node); + + /** + * Requests selection of the given child nodes of the node passed to + * setNode. This method should be implemented as a no-op for result viewers + * that do not display the child nodes of a given root node using a NetBeans + * explorer view set up to use a given explorer manager. + * + * @param selectedNodes The child nodes to select. + */ + default public void setSelectedNodes(Node[] selectedNodes) { + } + + /** + * Gets the title of this result viewer. + * + * @return The title. + */ + public String getTitle(); + + /** + * Gets the Swing component for this viewer. + * + * @return The component. */ public Component getComponent(); /** - * Resets the viewer. + * Resets the state of the Swing component for this viewer to its default + * state. */ - public void resetComponent(); + default public void resetComponent() { + } /** - * Frees the objects that have been allocated by this viewer, in preparation - * for permanently disposing of it. + * Frees any resources tha have been allocated by this result viewer, in + * preparation for permanently disposing of it. */ - public void clearComponent(); + default public void clearComponent() { + } /** - * Expand node, if supported by the viewed + * Sets the node for which this result viewer should provide a view of the + * underlying application data model object, and expands the node. * - * @param n Node to expand - */ - public void expandNode(Node n); - - /** - * Select the given node array - */ - public void setSelectedNodes(Node[] selected); - - /** - * Checks whether the currently selected root node is supported by this - * viewer + * @param node The node. * - * @param selectedNode the selected node - * - * @return True if supported, else false - */ - public boolean isSupported(Node selectedNode); - - /** - * Set a custom content viewer to respond to selection events from this - * result viewer. If not set, the default content viewer is used - * - * @param contentViewer content viewer to respond to selection events from - * this viewer - * - * @deprecated All implementations of this in the standard DataResultViewers are now no-ops. + * @deprecated This API is not used by the application. */ @Deprecated - public void setContentViewer(DataContent contentViewer); + default public void expandNode(Node node) { + } + + /** + * Sets a custom content viewer to which nodes selected in this result + * viewer should be pushed via DataContent.setNode. + * + * @param contentViewer The content viewer. + * + * @deprecated This API is not used by the application. + */ + @Deprecated + default public void setContentViewer(DataContent contentViewer) { + } + } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java index 715973aa7d..fdabf16ac0 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AbstractDataResultViewer.java @@ -23,65 +23,49 @@ import java.beans.PropertyVetoException; import java.util.logging.Level; import javax.swing.JPanel; import org.openide.explorer.ExplorerManager; -import org.openide.explorer.ExplorerManager.Provider; import org.openide.nodes.Node; -import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent; import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer; import org.sleuthkit.autopsy.coreutils.Logger; /** - * Provides a JPanel base class that provides a default implementation of the - * ExplorerManager.Provider interface and selected methods of - * theDataResultViewer interface. The ExplorerManager.Provider interface is - * implemented to supply an explorer manager to subclasses and their child - * components. The explorer manager is expected to be the explorer manager of a - * top component that exposes a lookup maintained by the explorer manager to the - * actions global context. This connects the nodes displayed in the result - * viewer to the actions global context. The explorer manager may be either - * supplied during construction or discovered at runtime. + * An abstract base class for an implementation of the result viewer interface + * that is a JPanel that displays the child nodes of a given node using a + * NetBeans explorer view as a child component. Such a result viewer should use + * the explorer manager of an ancestor top component to connect the lookups of + * the nodes displayed in the NetBeans explorer view to the actions global + * context. This class handles some key aspects of working with the ancestor top + * component's explorer manager. + * + * Instances of this class can be supplied with the top component's explorer + * manager during construction, but the typical use case is for the result + * viewer to find the ancestor top component's explorer manager at runtime. + * + * IMPORTANT: If the result viewer is going to find the ancestor top component's + * explorer manager at runtime, the first call to the getExplorerManager method + * of this class must be made AFTER the component hierarchy is fully + * constructed. + * */ -abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, Provider { +public abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, ExplorerManager.Provider { private static final Logger logger = Logger.getLogger(AbstractDataResultViewer.class.getName()); private transient ExplorerManager explorerManager; /** - * Constructs a JPanel base class instance that provides a default - * implementation of selected methods of the DataResultViewer and - * ExplorerManager.Provider interfaces. The explorer manager of this viewer - * will be discovered at runtime. - */ - AbstractDataResultViewer() { - } - - /** - * Constructs a JPanel base class instance that provides a default - * implementation of selected methods of the DataResultViewer and - * ExplorerManager.Provider interfaces. + * Constructs an abstract base class for an implementation of the result + * viewer interface that is a JPanel that displays the child nodes of the + * given node using a NetBeans explorer view as a child component. * - * @param explorerManager + * @param explorerManager The explorer manager to use in the NetBeans + * explorer view child component of this result + * viewer, may be null. If null, the explorer manager + * will be discovered the first time + * getExplorerManager is called. */ - AbstractDataResultViewer(ExplorerManager explorerManager) { + public AbstractDataResultViewer(ExplorerManager explorerManager) { this.explorerManager = explorerManager; } - @Override - public void clearComponent() { - } - - @Override - public void expandNode(Node n) { - } - - @Override - public void resetComponent() { - } - - @Override - public Component getComponent() { - return this; - } - @Override public ExplorerManager getExplorerManager() { if (this.explorerManager == null) { @@ -95,13 +79,13 @@ abstract class AbstractDataResultViewer extends JPanel implements DataResultView try { this.getExplorerManager().setSelectedNodes(selected); } catch (PropertyVetoException ex) { - logger.log(Level.WARNING, "Couldn't set selected nodes.", ex); //NON-NLS + logger.log(Level.SEVERE, "Couldn't set selected nodes", ex); //NON-NLS } } - @Deprecated @Override - public void setContentViewer(DataContent contentViewer) { + public Component getComponent() { + return this; } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java index 42aa2b727d..ca0185ce29 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerTable.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2012 - 2018 Basis Technology Corp. + * Copyright 2012-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -67,8 +67,14 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo; /** - * A tabular results viewer that displays the children of a given root node + * A tabular result viewer that displays the children of the given root node * using an OutlineView. + * + * Instances of this class should use the explorer manager of an ancestor top + * component to connect the lookups of the nodes displayed in the OutlineView to + * the actions global context. The explorer manager can be supplied during + * construction, but the typical use case is for the result viewer to find the + * ancestor top component's explorer manager at runtime. */ @ServiceProvider(service = DataResultViewer.class) public final class DataResultViewerTable extends AbstractDataResultViewer { @@ -79,56 +85,52 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { static private final Color TAGGED_ROW_COLOR = new Color(255, 255, 195); private static final Logger logger = Logger.getLogger(DataResultViewerTable.class.getName()); private final String title; - private Outline outline; - private TableListener outlineViewListener; - private Node currentRootNode; - private final Map columnMap = new HashMap<>(); - private final Map> propertiesMap = new TreeMap<>(); + private final Map columnMap; + private final Map> propertiesMap; + private final Outline outline; + private final TableListener outlineViewListener; + private Node rootNode; /** - * Constructs a tabular results viewer that displays the children of a given - * root node using an OutlineView. + * Constructs a tabular result viewer that displays the children of the + * given root node using an OutlineView. The viewer should have an ancestor + * top component to connect the lookups of the nodes displayed in the + * OutlineView to the actions global context. The explorer manager will be + * discovered at runtime. */ public DataResultViewerTable() { - super(); - this.title = Bundle.DataResultViewerTable_title(); - initialize(); + this(null, Bundle.DataResultViewerTable_title()); } /** - * Constructs a tabular results viewer that displays the children of a given - * root node using an OutlineView, with a given explorer manager. + * Constructs a tabular result viewer that displays the children of a given + * root node using an OutlineView. The viewer should have an ancestor top + * component to connect the lookups of the nodes displayed in the + * OutlineView to the actions global context. * - * @param explorerManager The explorer manager. + * @param explorerManager The explorer manager of the ancestor top + * component. */ public DataResultViewerTable(ExplorerManager explorerManager) { this(explorerManager, Bundle.DataResultViewerTable_title()); } /** - * Constructs a tabular results viewer that displays the children of a given - * root node using an OutlineView, with a given explorer manager, and a - * custom title. + * Constructs a tabular result viewer that displays the children of a given + * root node using an OutlineView with a given title. The viewer should have + * an ancestor top component to connect the lookups of the nodes displayed + * in the OutlineView to the actions global context. * - * @param explorerManager The explorer manager. - * @param title The custom title. + * @param explorerManager The explorer manager of the ancestor top + * component. + * @param title The title. */ public DataResultViewerTable(ExplorerManager explorerManager, String title) { super(explorerManager); this.title = title; - initialize(); - } + this.columnMap = new HashMap<>(); + this.propertiesMap = new TreeMap<>(); -// @Override -// public void addNotify() { -// super.addNotify(); -// initialize(); -// } - - /* - * Initializes this tabular results viewer. - */ - private void initialize() { /* * Execute the code generated by the GUI builder. */ @@ -159,13 +161,13 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { } /** - * Creates a new instance of a tabular results viewer that displays the + * Creates a new instance of a tabular result viewer that displays the * children of a given root node using an OutlineView. This method exists to * make it possible to use the default service provider instance of this * class in the "main" results view of the application, while using distinct * instances in other places in the UI. * - * @return A new instance of a tabular results viewer, + * @return A new instance of a tabular result viewer, */ @Override public DataResultViewer createInstance() { @@ -173,7 +175,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { } /** - * Gets the title of this tabular results viewer. + * Gets the title of this tabular result viewer. */ @Override @NbBundle.Messages("DataResultViewerTable.title=Table") @@ -195,7 +197,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { } /** - * Sets the current root node of this tabular results viewer. + * Sets the current root node of this tabular result viewer. * * @param rootNode The node to set as the current root node, possibly null. */ @@ -225,8 +227,8 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { * case database round trips. */ if (rootNode != null && rootNode.getChildren().getNodesCount() > 0) { - currentRootNode = rootNode; - this.getExplorerManager().setRootContext(currentRootNode); + this.rootNode = rootNode; + this.getExplorerManager().setRootContext(this.rootNode); setupTable(); } else { Node emptyNode = new AbstractNode(Children.LEAF); @@ -241,7 +243,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { } /** - * Sets up the Outline view of this tabular results viewer by creating + * Sets up the Outline view of this tabular result viewer by creating * column headers based on the children of the current root node. The * persisted column order, sorting and visibility is used. */ @@ -310,10 +312,10 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { * it. */ SwingUtilities.invokeLater(() -> { - if (currentRootNode instanceof TableFilterNode) { - NodeSelectionInfo selectedChildInfo = ((TableFilterNode) currentRootNode).getChildNodeSelectionInfo(); + if (rootNode instanceof TableFilterNode) { + NodeSelectionInfo selectedChildInfo = ((TableFilterNode) rootNode).getChildNodeSelectionInfo(); if (null != selectedChildInfo) { - Node[] childNodes = currentRootNode.getChildren().getNodes(true); + Node[] childNodes = rootNode.getChildren().getNodes(true); for (int i = 0; i < childNodes.length; ++i) { Node childNode = childNodes[i]; if (selectedChildInfo.matches(childNode)) { @@ -325,7 +327,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { break; } } - ((TableFilterNode) currentRootNode).setChildNodeSelectionInfo(null); + ((TableFilterNode) rootNode).setChildNodeSelectionInfo(null); } } }); @@ -339,7 +341,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { /* * Populates the column map for the child OutlineView of this tabular - * results viewer with references to the column objects for use when + * result viewer with references to the column objects for use when * loading/storing the visibility info. */ private void populateColumnMap() { @@ -361,7 +363,7 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { * viewer. */ private void setColumnWidths() { - if (currentRootNode.getChildren().getNodesCount() != 0) { + if (rootNode.getChildren().getNodesCount() != 0) { final Graphics graphics = outlineView.getGraphics(); if (graphics != null) { final FontMetrics metrics = graphics.getFontMetrics(); @@ -419,14 +421,14 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { /** * Persists the current column visibility information for the child - * OutlineView of this tabular results viewer using a preferences file. + * OutlineView of this tabular result viewer using a preferences file. */ private synchronized void storeColumnVisibility() { - if (currentRootNode == null || propertiesMap.isEmpty()) { + if (rootNode == null || propertiesMap.isEmpty()) { return; } - if (currentRootNode instanceof TableFilterNode) { - TableFilterNode tfn = (TableFilterNode) currentRootNode; + if (rootNode instanceof TableFilterNode) { + TableFilterNode tfn = (TableFilterNode) rootNode; final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class); final ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel(); for (Map.Entry entry : columnMap.entrySet()) { @@ -445,14 +447,14 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { /** * Persists the current column ordering for the child OutlineView of this - * tabular results viewer using a preferences file. + * tabular result viewer using a preferences file. */ private synchronized void storeColumnOrder() { - if (currentRootNode == null || propertiesMap.isEmpty()) { + if (rootNode == null || propertiesMap.isEmpty()) { return; } - if (currentRootNode instanceof TableFilterNode) { - TableFilterNode tfn = (TableFilterNode) currentRootNode; + if (rootNode instanceof TableFilterNode) { + TableFilterNode tfn = (TableFilterNode) rootNode; final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class); // Store the current order of the columns into settings for (Map.Entry> entry : propertiesMap.entrySet()) { @@ -465,11 +467,11 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { * Persists the current column sorting information using a preferences file. */ private synchronized void storeColumnSorting() { - if (currentRootNode == null || propertiesMap.isEmpty()) { + if (rootNode == null || propertiesMap.isEmpty()) { return; } - if (currentRootNode instanceof TableFilterNode) { - final TableFilterNode tfn = ((TableFilterNode) currentRootNode); + if (rootNode instanceof TableFilterNode) { + final TableFilterNode tfn = ((TableFilterNode) rootNode); final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class); ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel(); for (Map.Entry entry : columnMap.entrySet()) { @@ -497,11 +499,11 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { * it cannot set the sort on columns that have not been added to the table. */ private synchronized void loadColumnSorting() { - if (currentRootNode == null || propertiesMap.isEmpty()) { + if (rootNode == null || propertiesMap.isEmpty()) { return; } - if (currentRootNode instanceof TableFilterNode) { - final TableFilterNode tfn = (TableFilterNode) currentRootNode; + if (rootNode instanceof TableFilterNode) { + final TableFilterNode tfn = (TableFilterNode) rootNode; final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class); //organize property sorting information, sorted by rank TreeSet sortInfos = new TreeSet<>(Comparator.comparing(ColumnSortInfo::getRank)); @@ -523,12 +525,12 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { * preferences file. */ private synchronized void loadColumnVisibility() { - if (currentRootNode == null || propertiesMap.isEmpty()) { + if (rootNode == null || propertiesMap.isEmpty()) { return; } - if (currentRootNode instanceof TableFilterNode) { + if (rootNode instanceof TableFilterNode) { final Preferences preferences = NbPreferences.forModule(DataResultViewerTable.class); - final TableFilterNode tfn = ((TableFilterNode) currentRootNode); + final TableFilterNode tfn = ((TableFilterNode) rootNode); ETableColumnModel columnModel = (ETableColumnModel) outline.getColumnModel(); for (Map.Entry> entry : propertiesMap.entrySet()) { final String propName = entry.getValue().getName(); @@ -549,14 +551,14 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { */ private synchronized List> loadColumnOrder() { - List> props = ResultViewerPersistence.getAllChildProperties(currentRootNode, 100); + List> props = ResultViewerPersistence.getAllChildProperties(rootNode, 100); // If node is not table filter node, use default order for columns - if (!(currentRootNode instanceof TableFilterNode)) { + if (!(rootNode instanceof TableFilterNode)) { return props; } - final TableFilterNode tfn = ((TableFilterNode) currentRootNode); + final TableFilterNode tfn = ((TableFilterNode) rootNode); propertiesMap.clear(); /* @@ -593,16 +595,6 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { return new ArrayList<>(propertiesMap.values()); } - /** - * Expands a given child node of the current root node. - * - * @param node Node to expand - */ - @Override - public void expandNode(Node node) { - outlineView.expandNode(node); - } - /** * Frees the resources that have been allocated by this tabular results * viewer, in preparation for permanently disposing of it. @@ -782,8 +774,8 @@ public final class DataResultViewerTable extends AbstractDataResultViewer { Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); // only override the color if a node is not selected - if (currentRootNode != null && !isSelected) { - Node node = currentRootNode.getChildren().getNodeAt(table.convertRowIndexToModel(row)); + if (rootNode != null && !isSelected) { + Node node = rootNode.getChildren().getNodeAt(table.convertRowIndexToModel(row)); boolean tagFound = false; if (node != null) { Node.PropertySet[] propSets = node.getPropertySets(); diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java index fd4727ca7b..b1d268c5a4 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultViewerThumbnail.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2012-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,66 +60,67 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskCoreException; /** - * A thumbnail viewer for the results view, with paging support. + * A thumbnail result viewer, with paging support, that displays the children of + * the given root node using an IconView. The paging is intended to reduce + * memory footprint by loading no more than two humdred images at a time. * - * The paging is intended to reduce memory footprint by load only up to - * (currently) 200 images at a time. This works whether or not the underlying - * content nodes are being lazy loaded or not. - * - * TODO (JIRA-2658): Fix DataResultViewer extension point. When this is done, - * restore implementation of DataResultViewerTable as a DataResultViewer service - * provider. + * Instances of this class should use the explorer manager of an ancestor top + * component to connect the lookups of the nodes displayed in the IconView to + * the actions global context. The explorer manager can be supplied during + * construction, but the typical use case is for the result viewer to find the + * ancestor top component's explorer manager at runtime. */ @ServiceProvider(service = DataResultViewer.class) public final class DataResultViewerThumbnail extends AbstractDataResultViewer { private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(DataResultViewerThumbnail.class.getName()); - private int curPage; - private int totalPages; - private int curPageImages; - private int thumbSize = ImageUtils.ICON_SIZE_MEDIUM; private final PageUpdater pageUpdater = new PageUpdater(); - private TableFilterNode tfn; - private ThumbnailViewChildren tvc; + private TableFilterNode rootNode; + private ThumbnailViewChildren rootNodeChildren; private NodeSelectionListener selectionListener; + private int currentPage; + private int totalPages; + private int currentPageImages; + private int thumbSize = ImageUtils.ICON_SIZE_MEDIUM; /** - * Constructs a thumbnail viewer for the results view, with paging support, - * that is NOT compatible with node multiple selection actions. + * Constructs a thumbnail result viewer, with paging support, that displays + * the children of the given root node using an IconView. The viewer should + * have an ancestor top component to connect the lookups of the nodes + * displayed in the IconView to the actions global context. The explorer + * manager will be discovered at runtime. */ public DataResultViewerThumbnail() { - super(); - initialize(); + this(null); } /** - * Constructs a thumbnail viewer for the results view, with paging support, - * that is compatible with node multiple selection actions. + * Constructs a thumbnail result viewer, with paging support, that displays + * the children of the given root node using an IconView. The viewer should + * have an ancestor top component to connect the lookups of the nodes + * displayed in the IconView to the actions global context. * - * @param explorerManager The shared ExplorerManager for the result viewers. + * @param explorerManager The explorer manager of the ancestor top + * component. */ - public DataResultViewerThumbnail(ExplorerManager explorerManager) { - super(explorerManager); - initialize(); - } - - @NbBundle.Messages({"DataResultViewerThumbnail.thumbnailSizeComboBox.small=Small Thumbnails", + @NbBundle.Messages({ + "DataResultViewerThumbnail.thumbnailSizeComboBox.small=Small Thumbnails", "DataResultViewerThumbnail.thumbnailSizeComboBox.medium=Medium Thumbnails", "DataResultViewerThumbnail.thumbnailSizeComboBox.large=Large Thumbnails" }) - private void initialize() { + public DataResultViewerThumbnail(ExplorerManager explorerManager) { + super(explorerManager); initComponents(); iconView.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); -// this.getExplorerManager().addPropertyChangeListener(new ExplorerManagerNodeSelectionListener()); - thumbnailSizeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>( - new String[]{Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_small(), - Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_medium(), - Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_large()})); + thumbnailSizeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{ + Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_small(), + Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_medium(), + Bundle.DataResultViewerThumbnail_thumbnailSizeComboBox_large()})); thumbnailSizeComboBox.setSelectedIndex(1); - curPage = -1; + currentPage = -1; totalPages = 0; - curPageImages = 0; + currentPageImages = 0; } /** @@ -315,7 +316,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { private void sortButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sortButtonActionPerformed List> childProperties = ResultViewerPersistence.getAllChildProperties(this.getExplorerManager().getRootContext(), 100); - SortChooser sortChooser = new SortChooser(childProperties, ResultViewerPersistence.loadSortCriteria(tfn)); + SortChooser sortChooser = new SortChooser(childProperties, ResultViewerPersistence.loadSortCriteria(rootNode)); DialogDescriptor dialogDescriptor = new DialogDescriptor(sortChooser, sortChooser.getDialogTitle()); Dialog createDialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor); createDialog.setVisible(true); @@ -336,8 +337,8 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { Node.Property prop = childProperties.get(i); String propName = prop.getName(); SortCriterion criterion = criteriaMap.get(prop); - final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(tfn, propName); - final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(tfn, propName); + final String columnSortOrderKey = ResultViewerPersistence.getColumnSortOrderKey(rootNode, propName); + final String columnSortRankKey = ResultViewerPersistence.getColumnSortRankKey(rootNode, propName); if (criterion != null) { preferences.putBoolean(columnSortOrderKey, criterion.getSortOrder() == SortOrder.ASCENDING); @@ -347,7 +348,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { preferences.remove(columnSortRankKey); } } - setNode(tfn); //this is just to force a refresh + setNode(rootNode); //this is just to force a refresh } }//GEN-LAST:event_sortButtonActionPerformed @@ -383,26 +384,26 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { if (selectionListener == null) { this.getExplorerManager().addPropertyChangeListener(new NodeSelectionListener()); // RJCTODO: remove listener on cleanup } - if (tvc != null) { - tvc.cancelLoadingThumbnails(); + if (rootNodeChildren != null) { + rootNodeChildren.cancelLoadingThumbnails(); } try { if (givenNode != null) { - tfn = (TableFilterNode) givenNode; + rootNode = (TableFilterNode) givenNode; /* * Wrap the given node in a ThumbnailViewChildren that will * produce ThumbnailPageNodes with ThumbnailViewNode children * from the child nodes of the given node. */ - tvc = new ThumbnailViewChildren(givenNode, thumbSize); - final Node root = new AbstractNode(tvc); + rootNodeChildren = new ThumbnailViewChildren(givenNode, thumbSize); + final Node root = new AbstractNode(rootNodeChildren); pageUpdater.setRoot(root); root.addNodeListener(pageUpdater); this.getExplorerManager().setRootContext(root); } else { - tfn = null; - tvc = null; + rootNode = null; + rootNodeChildren = null; Node emptyNode = new AbstractNode(Children.LEAF); this.getExplorerManager().setRootContext(emptyNode); iconView.setBackground(Color.BLACK); @@ -426,8 +427,8 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { public void resetComponent() { super.resetComponent(); this.totalPages = 0; - this.curPage = -1; - curPageImages = 0; + this.currentPage = -1; + currentPageImages = 0; updateControls(); } @@ -439,15 +440,15 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { } private void nextPage() { - if (curPage < totalPages) { - curPage++; + if (currentPage < totalPages) { + currentPage++; switchPage(); } } private void previousPage() { - if (curPage > 1) { - curPage--; + if (currentPage > 1) { + currentPage--; switchPage(); } } @@ -469,7 +470,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { return; } - curPage = newPage; + currentPage = newPage; switchPage(); } @@ -494,9 +495,9 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { progress.switchToIndeterminate(); ExplorerManager explorerManager = DataResultViewerThumbnail.this.getExplorerManager(); Node root = explorerManager.getRootContext(); - Node pageNode = root.getChildren().getNodeAt(curPage - 1); + Node pageNode = root.getChildren().getNodeAt(currentPage - 1); explorerManager.setExploredContext(pageNode); - curPageImages = pageNode.getChildren().getNodesCount(); + currentPageImages = pageNode.getChildren().getNodesCount(); return null; } @@ -539,20 +540,19 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { sortLabel.setText(DataResultViewerThumbnail_sortLabel_text()); } else { - pageNumLabel.setText( - NbBundle.getMessage(this.getClass(), "DataResultViewerThumbnail.pageNumbers.curOfTotal", - Integer.toString(curPage), Integer.toString(totalPages))); - final int imagesFrom = (curPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE + 1; - final int imagesTo = curPageImages + (curPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE; + pageNumLabel.setText(NbBundle.getMessage(this.getClass(), "DataResultViewerThumbnail.pageNumbers.curOfTotal", + Integer.toString(currentPage), Integer.toString(totalPages))); + final int imagesFrom = (currentPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE + 1; + final int imagesTo = currentPageImages + (currentPage - 1) * ThumbnailViewChildren.IMAGES_PER_PAGE; imagesRangeLabel.setText(imagesFrom + "-" + imagesTo); - pageNextButton.setEnabled(!(curPage == totalPages)); - pagePrevButton.setEnabled(!(curPage == 1)); + pageNextButton.setEnabled(!(currentPage == totalPages)); + pagePrevButton.setEnabled(!(currentPage == 1)); goToPageField.setEnabled(totalPages > 1); sortButton.setEnabled(true); thumbnailSizeComboBox.setEnabled(true); - if (tfn != null) { - String sortString = ResultViewerPersistence.loadSortCriteria(tfn).stream() + if (rootNode != null) { + String sortString = ResultViewerPersistence.loadSortCriteria(rootNode).stream() .map(SortCriterion::toString) .collect(Collectors.joining(" ")); sortString = StringUtils.defaultIfBlank(sortString, "---"); @@ -583,30 +583,30 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { totalPages = root.getChildren().getNodesCount(); if (totalPages == 0) { - curPage = -1; + currentPage = -1; updateControls(); return; } - if (curPage == -1 || curPage > totalPages) { - curPage = 1; + if (currentPage == -1 || currentPage > totalPages) { + currentPage = 1; } //force load the curPage node - final Node pageNode = root.getChildren().getNodeAt(curPage - 1); + final Node pageNode = root.getChildren().getNodeAt(currentPage - 1); //em.setSelectedNodes(new Node[]{pageNode}); if (pageNode != null) { pageNode.addNodeListener(new NodeListener() { @Override public void childrenAdded(NodeMemberEvent nme) { - curPageImages = pageNode.getChildren().getNodesCount(); + currentPageImages = pageNode.getChildren().getNodesCount(); updateControls(); } @Override public void childrenRemoved(NodeMemberEvent nme) { - curPageImages = 0; + currentPageImages = 0; updateControls(); } @@ -632,7 +632,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer { @Override public void childrenRemoved(NodeMemberEvent nme) { totalPages = 0; - curPage = -1; + currentPage = -1; updateControls(); }