initial refactor of DataResult top component into an inner jpanel and outter tc

This commit is contained in:
adam-m 2013-01-22 15:49:48 -05:00
parent 7aee2f9554
commit 20124f8ff5
8 changed files with 553 additions and 285 deletions

View File

@ -19,7 +19,6 @@ OutputViewPanel.currentPageLabel.text=1
OutputViewPanel.pageLabel.text=Page:
OutputViewPanel.filePathLabel.text=FilePath
OutputViewPanel.nextPageButton.text=Next Page
DataResultTopComponent.directoryTablePath.text=directoryPath
DataContentViewerHex.filePathLabel.text=FilePath
DataContentViewerHex.pageLabel.text=Page:
DataContentViewerHex.currentPageLabel.text=1
@ -45,8 +44,6 @@ DataContentViewerString.totalPageLabel.text_1=100
DataContentViewerPicture.picLabel.text=[Picture goes Here]
DataContentViewerHex.pageLabel2.text=Page
DataContentViewerString.pageLabel2.text=Page
DataResultTopComponent.matchLabel.text=Results
DataResultTopComponent.numberMatchLabel.text=0
# Product Information panel
@ -104,3 +101,6 @@ GeneralPanel.keepCurrentViewerRB.text=Stay on the same file viewer
GeneralPanel.useBestViewerRB.toolTipText=For example, change from Hex to Media when a JPEG is selected.
GeneralPanel.keepCurrentViewerRB.toolTipText=For example, stay in Hex view when a JPEG is selected.
AdvancedConfigurationDialog.cancelButton.text=Cancel
DataResultPanel.directoryTablePath.text=directoryPath
DataResultPanel.numberMatchLabel.text=0
DataResultPanel.matchLabel.text=Results

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="directoryTablePath" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="518" max="32767" attributes="0"/>
<Component id="numberMatchLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="matchLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="dataResultTabbedPanel" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="3" attributes="0">
<Component id="numberMatchLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="matchLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="directoryTablePath" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="dataResultTabbedPanel" pref="334" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="directoryTablePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultPanel.directoryTablePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="numberMatchLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultPanel.numberMatchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="matchLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultPanel.matchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JTabbedPane" name="dataResultTabbedPanel">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,415 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013 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.corecomponents;
import java.awt.Cursor;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.nodes.Node;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResult;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
/**
* Data result panel component with its viewer tabs
*
* The component is a generic JPanel and it can be reused in other swing
* components or a TopComponent
*/
public class DataResultPanel extends javax.swing.JPanel implements DataResult, ChangeListener {
private Node rootNode;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
/**
* Name of property change fired when a file search result is closed
*/
public static String REMOVE_FILESEARCH = "RemoveFileSearchTopComponent";
private static String DEFAULT_PREFERRED_ID = "DataResultPanel";
// Different DataResultsViewers
private final List<UpdateWrapper> viewers = new ArrayList<UpdateWrapper>();
//custom content viewer to send selections to, or null if the main one
private DataContent customContentViewer;
private boolean isMain;
private String title;
/**
* Creates new form DataResultPanel
*/
private DataResultPanel() {
initComponents();
}
/**
* Creates new form DataResultPanel
*/
public DataResultPanel(boolean isMain, String title) {
this();
this.isMain = isMain;
this.title = title;
this.dataResultTabbedPanel.addChangeListener(this);
}
/**
* Create a new, custom data result panel, in addition to the application
* main one
*
* @param name unique name of the data result window, also used as title
* @param customContentViewer custom content viewer to send selection events
* to
*/
public DataResultPanel(String name, DataContentTopComponent customContentViewer) {
this(false, name);
//custom content viewer tc to setup for every result viewer
this.customContentViewer = customContentViewer; //TODO change to content panel
}
/**
* Creates a new non-default DataResult component
*
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
* @return
*/
public static DataResultPanel createInstance(String title, String pathText, Node givenNode, int totalMatches) {
DataResultPanel newDataResult = new DataResultPanel(false, title);
createInstanceCommon(pathText, givenNode, totalMatches, newDataResult);
return newDataResult;
}
/**
* Creates a new non-default DataResult component
*
* @param title Title of the component window
* @param customModeName custom mode to dock this custom TopComponent to
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
* @param dataContentWindow a handle to data content top component window to
* @return
*/
public static DataResultPanel createInstance(String title, String pathText, Node givenNode, int totalMatches, DataContentTopComponent dataContentWindow) {
DataResultPanel newDataResult = new DataResultPanel(title, dataContentWindow);
createInstanceCommon(pathText, givenNode, totalMatches, newDataResult);
return newDataResult;
}
private static void createInstanceCommon(String pathText, Node givenNode, int totalMatches, DataResultPanel newDataResult) {
newDataResult.numberMatchLabel.setText(Integer.toString(totalMatches));
// set the tree table view
newDataResult.setNode(givenNode);
newDataResult.setPath(pathText);
}
public void componentOpened() {
// Add all the DataContentViewer to the tabbed pannel.
// (Only when the it's opened at the first time: tabCount = 0)
int totalTabs = this.dataResultTabbedPanel.getTabCount();
if (totalTabs == 0) {
// find all dataContentViewer and add them to the tabbed pane
for (DataResultViewer factory : Lookup.getDefault().lookupAll(DataResultViewer.class)) {
DataResultViewer drv = factory.getInstance();
UpdateWrapper resultViewer = new UpdateWrapper(drv);
if (customContentViewer != null) {
//set custom content viewer to respond to events from this result viewer
resultViewer.setContentViewer(customContentViewer);
}
this.viewers.add(resultViewer);
this.dataResultTabbedPanel.addTab(drv.getTitle(), drv.getComponent());
}
}
if (this.preferredID().equals(DEFAULT_PREFERRED_ID)) {
// if no node selected on DataExplorer, clear the field
if (rootNode == null) {
setNode(rootNode);
}
}
}
public void componentClosed() {
pcs.firePropertyChange(REMOVE_FILESEARCH, "", this); // notify to remove this from the menu
// try to remove any references to this class
PropertyChangeListener[] pcl = pcs.getPropertyChangeListeners();
for (int i = 0; i < pcl.length; i++) {
pcs.removePropertyChangeListener(pcl[i]);
}
// clear all set nodes
for (UpdateWrapper drv : this.viewers) {
drv.setNode(null);
}
if (!this.isMain) {
for (UpdateWrapper drv : this.viewers) {
drv.clearComponent();
}
this.directoryTablePath.removeAll();
this.directoryTablePath = null;
this.numberMatchLabel.removeAll();
this.numberMatchLabel = null;
this.numberMatchLabel.removeAll();
this.numberMatchLabel = null;
this.setLayout(null);
this.pcs = null;
this.removeAll();
}
}
protected String preferredID() {
if (this.isMain) {
return DEFAULT_PREFERRED_ID;
} else {
return this.getName();
}
}
@Override
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(listener);
}
@Override
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(listener);
}
@Override
public String getPreferredID() {
return this.preferredID();
}
@Override
public void setNode(Node selectedNode) {
this.rootNode = selectedNode;
if (selectedNode != null) {
int childrenCount = selectedNode.getChildren().getNodesCount(true);
this.numberMatchLabel.setText(Integer.toString(childrenCount));
}
this.numberMatchLabel.setVisible(true);
this.numberMatchLabel.setVisible(true);
resetTabs(selectedNode);
//update/disable tabs based on if supported for this node
int drvC = 0;
for (UpdateWrapper drv : viewers) {
if (drv.isSupported(selectedNode)) {
dataResultTabbedPanel.setEnabledAt(drvC, true);
} else {
dataResultTabbedPanel.setEnabledAt(drvC, false);
}
++drvC;
}
// set the display on the current active tab
int currentActiveTab = this.dataResultTabbedPanel.getSelectedIndex();
if (currentActiveTab != -1) {
UpdateWrapper drv = viewers.get(currentActiveTab);
drv.setNode(selectedNode);
}
}
@Override
public void setTitle(String title) {
setName(title);
}
@Override
public void setPath(String pathText) {
this.directoryTablePath.setText(pathText);
}
@Override
public boolean isMain() {
return this.isMain;
}
public boolean canClose() {
return (!this.isMain) || !Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0; // only allow this window to be closed when there's no case opened or no image in this case
}
@Override
public void stateChanged(ChangeEvent e) {
JTabbedPane pane = (JTabbedPane) e.getSource();
// Get and set current selected tab
int currentTab = pane.getSelectedIndex();
if (currentTab != -1) {
UpdateWrapper drv = this.viewers.get(currentTab);
if (drv.isOutdated()) {
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
drv.setNode(rootNode);
} finally {
this.setCursor(null);
}
}
}
}
/**
* Resets the tabs based on the selected Node. If the selected node is null
* or not supported, disable that tab as well.
*
* @param selectedNode the selected content Node
*/
public void resetTabs(Node selectedNode) {
for (UpdateWrapper drv : this.viewers) {
drv.resetComponent();
}
}
public void setSelectedNodes(Node[] selected) {
for (UpdateWrapper drv : this.viewers) {
drv.setSelectedNodes(selected);
}
}
public Node getRootNode() {
return this.rootNode;
}
/**
* 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
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
directoryTablePath = new javax.swing.JLabel();
numberMatchLabel = new javax.swing.JLabel();
matchLabel = new javax.swing.JLabel();
dataResultTabbedPanel = new javax.swing.JTabbedPane();
org.openide.awt.Mnemonics.setLocalizedText(directoryTablePath, org.openide.util.NbBundle.getMessage(DataResultPanel.class, "DataResultPanel.directoryTablePath.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(numberMatchLabel, org.openide.util.NbBundle.getMessage(DataResultPanel.class, "DataResultPanel.numberMatchLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(matchLabel, org.openide.util.NbBundle.getMessage(DataResultPanel.class, "DataResultPanel.matchLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(directoryTablePath)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 518, Short.MAX_VALUE)
.addComponent(numberMatchLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(matchLabel))
.addComponent(dataResultTabbedPanel)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(numberMatchLabel)
.addComponent(matchLabel))
.addComponent(directoryTablePath))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 334, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTabbedPane dataResultTabbedPanel;
private javax.swing.JLabel directoryTablePath;
private javax.swing.JLabel matchLabel;
private javax.swing.JLabel numberMatchLabel;
// End of variables declaration//GEN-END:variables
private static class UpdateWrapper {
private DataResultViewer wrapped;
private boolean outdated;
UpdateWrapper(DataResultViewer wrapped) {
this.wrapped = wrapped;
this.outdated = true;
}
void setNode(Node selectedNode) {
this.wrapped.setNode(selectedNode);
this.outdated = false;
}
void resetComponent() {
this.wrapped.resetComponent();
this.outdated = true;
}
void clearComponent() {
this.wrapped.clearComponent();
this.outdated = true;
}
boolean isOutdated() {
return this.outdated;
}
void setSelectedNodes(Node[] selected) {
this.wrapped.setSelectedNodes(selected);
}
boolean isSupported(Node selectedNode) {
return this.wrapped.isSupported(selectedNode);
}
void setContentViewer(DataContent contentViewer) {
this.wrapped.setContentViewer(contentViewer);
}
}
/**
*
* @param numMatches
*/
public void setNumMatches(int numMatches) {
this.numberMatchLabel.setText(Integer.toString(numMatches));
}
}

View File

@ -16,57 +16,13 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="directoryTablePath" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="855" max="32767" attributes="0"/>
<Component id="numberMatchLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="matchLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="dataResultTabbedPanel" alignment="0" pref="967" max="32767" attributes="0"/>
<EmptySpace min="0" pref="967" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="matchLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="numberMatchLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="directoryTablePath" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="dataResultTabbedPanel" pref="565" max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="579" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="directoryTablePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultTopComponent.directoryTablePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="matchLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultTopComponent.matchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="numberMatchLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataResultTopComponent.numberMatchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JTabbedPane" name="dataResultTabbedPanel">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -42,23 +42,12 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Top component which displays result (top-right editor mode by default).
*/
public class DataResultTopComponent extends TopComponent implements DataResult, ChangeListener {
public class DataResultTopComponent extends TopComponent implements DataResult {
private static final Logger logger = Logger.getLogger(DataResultTopComponent.class.getName());
private Node rootNode;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private DataResultPanel dataResultPanel; //embedded component with all the logic
private boolean isMain;
private String customModeName;
private static final String DEFAULT_MODE = "editor";
private static String DEFAULT_PREFERRED_ID = "DataResultTopComponent";
/**
* Name of property change fired when a file search result is closed
*/
public static String REMOVE_FILESEARCH = "RemoveFileSearchTopComponent";
// Different DataResultsViewers
private List<UpdateWrapper> viewers = new ArrayList<UpdateWrapper>();
//custom content viewer to send selections to, or null if the main one
private DataContent customContentViewer;
/**
* Create a new data result top component
@ -71,16 +60,11 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
super();
initComponents();
setToolTipText(NbBundle.getMessage(DataResultTopComponent.class, "HINT_NodeTableTopComponent"));
setTitle(title); // set the title
this.isMain = isMain;
this.customModeName = null;
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.valueOf(isMain)); // set option to close compoment in GUI
putClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED, true);
putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, true);
this.dataResultPanel = new DataResultPanel(isMain, title);
customizeComponent(isMain, title);
this.dataResultTabbedPanel.addChangeListener(this);
}
/**
@ -93,57 +77,32 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
* to
*/
public DataResultTopComponent(String name, String mode, DataContentTopComponent customContentViewer) {
this(false, name);
super();
this.customModeName = mode;
customizeComponent(isMain, name);;
//custom content viewer tc to setup for every result viewer
this.customContentViewer = customContentViewer;
this.customModeName = mode;
dataResultPanel = new DataResultPanel(name, customContentViewer);
}
private static class UpdateWrapper {
private void customizeComponent(boolean isMain, String title) {
this.isMain = isMain;
this.customModeName = null;
private DataResultViewer wrapped;
private boolean outdated;
setToolTipText(NbBundle.getMessage(DataResultTopComponent.class, "HINT_NodeTableTopComponent"));
UpdateWrapper(DataResultViewer wrapped) {
this.wrapped = wrapped;
this.outdated = true;
}
setTitle(title); // set the title
void setNode(Node selectedNode) {
this.wrapped.setNode(selectedNode);
this.outdated = false;
}
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.valueOf(isMain)); // set option to close compoment in GUI
putClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED, true);
putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, true);
void resetComponent() {
this.wrapped.resetComponent();
this.outdated = true;
}
void clearComponent() {
this.wrapped.clearComponent();
this.outdated = true;
}
boolean isOutdated() {
return this.outdated;
}
void setSelectedNodes(Node[] selected) {
this.wrapped.setSelectedNodes(selected);
}
boolean isSupported(Node selectedNode) {
return this.wrapped.isSupported(selectedNode);
}
void setContentViewer(DataContent contentViewer) {
this.wrapped.setContentViewer(contentViewer);
}
}
private static void createInstanceCommon(String pathText, Node givenNode, int totalMatches, DataResultTopComponent newDataResult) {
newDataResult.numberMatchLabel.setText(Integer.toString(totalMatches));
newDataResult.setNumMatches(totalMatches);
newDataResult.open(); // open it first so the component can be initialized
@ -195,46 +154,18 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
directoryTablePath = new javax.swing.JLabel();
matchLabel = new javax.swing.JLabel();
numberMatchLabel = new javax.swing.JLabel();
dataResultTabbedPanel = new javax.swing.JTabbedPane();
org.openide.awt.Mnemonics.setLocalizedText(directoryTablePath, org.openide.util.NbBundle.getMessage(DataResultTopComponent.class, "DataResultTopComponent.directoryTablePath.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(matchLabel, org.openide.util.NbBundle.getMessage(DataResultTopComponent.class, "DataResultTopComponent.matchLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(numberMatchLabel, org.openide.util.NbBundle.getMessage(DataResultTopComponent.class, "DataResultTopComponent.numberMatchLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(directoryTablePath)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 855, Short.MAX_VALUE)
.addComponent(numberMatchLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(matchLabel))
.addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 967, Short.MAX_VALUE)
.addGap(0, 967, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(matchLabel)
.addComponent(numberMatchLabel))
.addComponent(directoryTablePath))
.addGap(0, 0, 0)
.addComponent(dataResultTabbedPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 565, Short.MAX_VALUE))
.addGap(0, 579, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTabbedPane dataResultTabbedPanel;
private javax.swing.JLabel directoryTablePath;
private javax.swing.JLabel matchLabel;
private javax.swing.JLabel numberMatchLabel;
// End of variables declaration//GEN-END:variables
@Override
@ -273,86 +204,30 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
@Override
public void componentOpened() {
// Add all the DataContentViewer to the tabbed pannel.
// (Only when the it's opened at the first time: tabCount = 0)
int totalTabs = this.dataResultTabbedPanel.getTabCount();
if (totalTabs == 0) {
// find all dataContentViewer and add them to the tabbed pane
for (DataResultViewer factory : Lookup.getDefault().lookupAll(DataResultViewer.class)) {
DataResultViewer drv = factory.getInstance();
UpdateWrapper resultViewer = new UpdateWrapper(drv);
if (customContentViewer != null) {
//set custom content viewer to respond to events from this result viewer
resultViewer.setContentViewer(customContentViewer);
}
this.viewers.add(resultViewer);
this.dataResultTabbedPanel.addTab(drv.getTitle(), drv.getComponent());
}
}
if (this.preferredID().equals(DataResultTopComponent.DEFAULT_PREFERRED_ID)) {
// if no node selected on DataExplorer, clear the field
if (rootNode == null) {
setNode(rootNode);
}
}
this.dataResultPanel.componentOpened();
}
@Override
public void componentClosed() {
pcs.firePropertyChange(REMOVE_FILESEARCH, "", this); // notify to remove this from the menu
// try to remove any references to this class
PropertyChangeListener[] pcl = pcs.getPropertyChangeListeners();
for (int i = 0; i < pcl.length; i++) {
pcs.removePropertyChangeListener(pcl[i]);
}
// clear all set nodes
for (UpdateWrapper drv : this.viewers) {
drv.setNode(null);
}
if (!this.isMain) {
for (UpdateWrapper drv : this.viewers) {
drv.clearComponent();
}
this.directoryTablePath.removeAll();
this.directoryTablePath = null;
this.matchLabel.removeAll();
this.matchLabel = null;
this.numberMatchLabel.removeAll();
this.numberMatchLabel = null;
this.setLayout(null);
this.pcs = null;
this.removeAll();
}
dataResultPanel.componentClosed();
}
@Override
protected String preferredID() {
if (this.isMain) {
return DEFAULT_PREFERRED_ID;
} else {
return this.getName();
}
return this.getName();
}
@Override
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(listener);
}
@Override
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(listener);
}
// @Override
// public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
// dataResultPanel.addPropertyChangeListener(listener);
// }
//
// @Override
// public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
// dataResultPanel.removePropertyChangeListener(listener);
// }
@Override
public String getPreferredID() {
@ -361,35 +236,7 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
@Override
public void setNode(Node selectedNode) {
this.rootNode = selectedNode;
if (selectedNode != null) {
int childrenCount = selectedNode.getChildren().getNodesCount(true);
this.numberMatchLabel.setText(Integer.toString(childrenCount));
}
this.numberMatchLabel.setVisible(true);
this.matchLabel.setVisible(true);
resetTabs(selectedNode);
//update/disable tabs based on if supported for this node
int drvC = 0;
for (UpdateWrapper drv : viewers) {
if (drv.isSupported(selectedNode)) {
dataResultTabbedPanel.setEnabledAt(drvC, true);
} else {
dataResultTabbedPanel.setEnabledAt(drvC, false);
}
++drvC;
}
// set the display on the current active tab
int currentActiveTab = this.dataResultTabbedPanel.getSelectedIndex();
if (currentActiveTab != -1) {
UpdateWrapper drv = viewers.get(currentActiveTab);
drv.setNode(selectedNode);
}
dataResultPanel.setNode(selectedNode);
}
@Override
@ -399,12 +246,12 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
@Override
public void setPath(String pathText) {
this.directoryTablePath.setText(pathText);
dataResultPanel.setPath(pathText);
}
@Override
public boolean isMain() {
return this.isMain;
return isMain;
}
@Override
@ -412,26 +259,6 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
return (!this.isMain) || !Case.existsCurrentCase() || Case.getCurrentCase().getRootObjectsCount() == 0; // only allow this window to be closed when there's no case opened or no image in this case
}
@Override
public void stateChanged(ChangeEvent e) {
JTabbedPane pane = (JTabbedPane) e.getSource();
// Get and set current selected tab
int currentTab = pane.getSelectedIndex();
if (currentTab != -1) {
UpdateWrapper drv = this.viewers.get(currentTab);
if (drv.isOutdated()) {
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
drv.setNode(rootNode);
} finally {
this.setCursor(null);
}
}
}
}
/**
* Resets the tabs based on the selected Node. If the selected node is null
* or not supported, disable that tab as well.
@ -440,18 +267,18 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
*/
public void resetTabs(Node selectedNode) {
for (UpdateWrapper drv : this.viewers) {
drv.resetComponent();
}
dataResultPanel.resetTabs(selectedNode);
}
public void setSelectedNodes(Node[] selected) {
for (UpdateWrapper drv : this.viewers) {
drv.setSelectedNodes(selected);
}
dataResultPanel.setSelectedNodes(selected);
}
public Node getRootNode() {
return this.rootNode;
return dataResultPanel.getRootNode();
}
void setNumMatches(int matches) {
this.dataResultPanel.setNumMatches(matches);
}
}

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.corecomponents;
import java.awt.Cursor;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.dnd.DnDConstants;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
@ -58,7 +59,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
OutlineView ov = ((OutlineView) this.tableScrollPanel);
ov.setAllowedDragActions(DnDConstants.ACTION_NONE);
ov.setAllowedDropActions(DnDConstants.ACTION_NONE );
ov.setAllowedDropActions(DnDConstants.ACTION_NONE);
// only allow one item to be selected at a time
ov.getOutline().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
@ -85,11 +86,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
@Override
public void nodeSelected(Node selectedNode) {
}
/**
* 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
@ -246,7 +244,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
em.setRootContext(root);
OutlineView ov = ((OutlineView) this.tableScrollPanel);
final OutlineView ov = ((OutlineView) this.tableScrollPanel);
propertiesAcc.clear();
@ -296,9 +294,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
int startColumn = 1;
ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// get the fontmetrics
//FontMetrics metrics = ttv.getGraphics().getFontMetrics();
FontMetrics metrics = ov.getGraphics().getFontMetrics();
// get first 100 rows values for the table
Object[][] content = null;
@ -306,6 +302,10 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
if (content != null) {
// get the fontmetrics
final Graphics graphics = ov.getGraphics();
final FontMetrics metrics = graphics.getFontMetrics();
// for the "Name" column
int nodeColWidth = Math.min(getMaxColumnWidth(0, metrics, margin, 40, firstColumnLabel, content), 250); // Note: 40 is the width of the icon + node lines. Change this value if those values change!
ov.getOutline().getColumnModel().getColumn(0).setPreferredWidth(nodeColWidth);
@ -324,10 +324,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
}
} else {
final OutlineView ov = ((OutlineView) this.tableScrollPanel);
Node emptyNode = new AbstractNode(Children.LEAF);
em.setRootContext(emptyNode); // make empty node
((OutlineView) this.tableScrollPanel).getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
((OutlineView) this.tableScrollPanel).setPropertyColumns(); // set the empty property header
ov.getOutline().setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
ov.setPropertyColumns(); // set the empty property header
}
} finally {
this.setCursor(null);
@ -436,6 +437,4 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
super.clearComponent();
}
}

View File

@ -32,10 +32,8 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -50,6 +48,7 @@ import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.windows.TopComponent;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
@ -80,7 +79,7 @@ public class FileSearchPanel extends javax.swing.JPanel {
Object newValue = evt.getNewValue();
// if the one of the "FileSearchResult" window is closed
if (changed.equals(DataResultTopComponent.REMOVE_FILESEARCH)) {
if (changed.equals(DataResultPanel.REMOVE_FILESEARCH)) {
searchResults.remove((DataResultTopComponent) newValue);
}
}

View File

@ -29,7 +29,6 @@ import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -48,6 +47,7 @@ import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataExplorer;
import org.sleuthkit.autopsy.corecomponents.DataResultPanel;
import org.sleuthkit.autopsy.corecomponents.DataResultTopComponent;
import org.sleuthkit.autopsy.corecomponents.TableFilterNode;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
@ -285,7 +285,7 @@ public final class FileSearchTopComponent extends TopComponent implements DataEx
Object newValue = evt.getNewValue();
// if the one of the "FileSearchResult" window is closed
if (changed.equals(DataResultTopComponent.REMOVE_FILESEARCH)) {
if (changed.equals(DataResultPanel.REMOVE_FILESEARCH)) {
searchResults.remove((DataResultTopComponent) newValue);
}