19 package org.sleuthkit.autopsy.discovery.ui;
 
   21 import com.google.common.eventbus.Subscribe;
 
   22 import java.awt.Component;
 
   23 import java.awt.event.MouseAdapter;
 
   24 import java.awt.event.MouseEvent;
 
   25 import java.util.HashSet;
 
   26 import java.util.List;
 
   28 import javax.swing.DefaultListCellRenderer;
 
   29 import javax.swing.DefaultListModel;
 
   30 import javax.swing.JList;
 
   31 import javax.swing.JPopupMenu;
 
   32 import javax.swing.SwingUtilities;
 
   33 import javax.swing.event.ListSelectionEvent;
 
   34 import javax.swing.event.ListSelectionListener;
 
   52 final class FileDetailsPanel 
extends javax.swing.JPanel {
 
   54     private static final long serialVersionUID = 1L;
 
   56     private final DataContentPanel dataContentPanel;
 
   57     private final DefaultListModel<AbstractFile> instancesListModel = 
new DefaultListModel<>();
 
   58     private final ListSelectionListener listener;
 
   63     @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
 
   66         dataContentPanel = DataContentPanel.createInstance();
 
   67         detailsSplitPane.setBottomComponent(dataContentPanel);
 
   69         instancesList.addMouseListener(
new MouseAdapter() {
 
   71             public void mousePressed(MouseEvent e) {
 
   72                 if (SwingUtilities.isRightMouseButton(e)) {
 
   73                     instancesList.setSelectedIndex(instancesList.locationToIndex(e.getPoint()));
 
   74                     Set<AbstractFile> files = 
new HashSet<>();
 
   75                     files.add(instancesList.getSelectedValue());
 
   76                     JPopupMenu menu = 
new JPopupMenu();
 
   77                     menu.add(
new ViewContextAction(Bundle.ResultsPanel_viewFileInDir_name(), instancesList.getSelectedValue()));
 
   78                     menu.add(
new ExternalViewerAction(Bundle.ResultsPanel_openInExternalViewer_name(), 
new FileNode(instancesList.getSelectedValue())));
 
   79                     menu.add(ViewFileInTimelineAction.createViewFileAction(instancesList.getSelectedValue()));
 
   80                     menu.add(
new DiscoveryExtractAction(files));
 
   81                     menu.add(AddContentTagAction.getInstance().getMenuForContent(files));
 
   82                     menu.add(DeleteFileContentTagAction.getInstance().getMenuForFiles(files));
 
   83                     menu.add(AddContentToHashDbAction.getInstance().getMenuForFiles(files));
 
   84                     menu.show(instancesList, e.getPoint().x, e.getPoint().y);
 
   88         listener = 
new ListSelectionListener() {
 
   90             public void valueChanged(ListSelectionEvent e) {
 
   91                 if (!e.getValueIsAdjusting()) {
 
   92                     AbstractFile file = getSelectedFile();
 
   94                         dataContentPanel.setNode(
new TableFilterNode(
new FileNode(file), 
false));
 
   96                         dataContentPanel.setNode(null);
 
  101         instancesList.addListSelectionListener(listener);
 
  112     void handleClearSelectionListener(DiscoveryEventUtils.ClearInstanceSelectionEvent clearEvent) {
 
  113         SwingUtilities.invokeLater(() -> {
 
  114             instancesList.clearSelection();
 
  125     void handlePopulateInstancesListEvent(DiscoveryEventUtils.PopulateInstancesListEvent populateEvent) {
 
  126         List<AbstractFile> files = populateEvent.getInstances();
 
  127         SwingUtilities.invokeLater(() -> {
 
  128             if (files.isEmpty()) {
 
  130                 instancesListModel.removeAllElements();
 
  132                 DiscoveryEventUtils.getDiscoveryEventBus().post(
new DiscoveryEventUtils.DetailsVisibleEvent(
false));
 
  135                 instancesList.removeListSelectionListener(listener);
 
  136                 instancesListModel.removeAllElements();
 
  137                 for (AbstractFile file : files) {
 
  138                     instancesListModel.addElement(file);
 
  141                 instancesList.addListSelectionListener(listener);
 
  142                 if (!instancesListModel.isEmpty()) {
 
  143                     instancesList.setSelectedIndex(0);
 
  146                 DiscoveryEventUtils.getDiscoveryEventBus().post(
new DiscoveryEventUtils.DetailsVisibleEvent(
true));
 
  157     @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
 
  158     AbstractFile getSelectedFile() {
 
  159         if (instancesList.getSelectedIndex() == -1) {
 
  162             return instancesListModel.getElementAt(instancesList.getSelectedIndex());
 
  171     @SuppressWarnings(
"unchecked")
 
  173     private 
void initComponents() {
 
  175         detailsSplitPane = 
new javax.swing.JSplitPane();
 
  176         javax.swing.JPanel instancesPanel = 
new javax.swing.JPanel();
 
  177         javax.swing.JScrollPane instancesScrollPane = 
new javax.swing.JScrollPane();
 
  178         instancesList = 
new javax.swing.JList<>();
 
  180         detailsSplitPane.setDividerLocation(80);
 
  181         detailsSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
 
  182         detailsSplitPane.setMinimumSize(
new java.awt.Dimension(200, 0));
 
  183         detailsSplitPane.setPreferredSize(
new java.awt.Dimension(700, 500));
 
  185         instancesPanel.setMinimumSize(
new java.awt.Dimension(0, 60));
 
  186         instancesPanel.setPreferredSize(
new java.awt.Dimension(700, 80));
 
  188         instancesScrollPane.setPreferredSize(
new java.awt.Dimension(775, 60));
 
  190         instancesList.setBorder(javax.swing.BorderFactory.createTitledBorder(
org.openide.util.NbBundle.getMessage(FileDetailsPanel.class, 
"FileDetailsPanel.instancesList.border.title"))); 
 
  191         instancesList.setModel(instancesListModel);
 
  192         instancesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
 
  193         instancesList.setCellRenderer(
new InstancesCellRenderer());
 
  194         instancesList.setVisibleRowCount(2);
 
  195         instancesScrollPane.setViewportView(instancesList);
 
  197         javax.swing.GroupLayout instancesPanelLayout = 
new javax.swing.GroupLayout(instancesPanel);
 
  198         instancesPanel.setLayout(instancesPanelLayout);
 
  199         instancesPanelLayout.setHorizontalGroup(
 
  200             instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  201             .addGap(0, 775, Short.MAX_VALUE)
 
  202             .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  203                 .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  205         instancesPanelLayout.setVerticalGroup(
 
  206             instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  207             .addGap(0, 79, Short.MAX_VALUE)
 
  208             .addGroup(instancesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  209                 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, instancesPanelLayout.createSequentialGroup()
 
  211                     .addComponent(instancesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)))
 
  214         detailsSplitPane.setTopComponent(instancesPanel);
 
  216         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  217         this.setLayout(layout);
 
  218         layout.setHorizontalGroup(
 
  219             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  220             .addGap(0, 777, Short.MAX_VALUE)
 
  221             .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  222                 .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  224         layout.setVerticalGroup(
 
  225             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  226             .addGap(0, 402, Short.MAX_VALUE)
 
  227             .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  228                 .addComponent(detailsSplitPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  234     private javax.swing.JSplitPane detailsSplitPane;
 
  235     private javax.swing.JList<AbstractFile> instancesList;
 
  243         private static final long serialVersionUID = 1L;
 
  248             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
 
  251                 AbstractFile file = (AbstractFile) value;
 
Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)