Autopsy  4.19.3
Graphical digital forensics platform for The Sleuth Kit and other tools.
VideoThumbnailPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy
3  *
4  * Copyright 2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.discovery.ui;
20 
21 import java.awt.Color;
22 import java.awt.Component;
23 import java.awt.Dimension;
24 import java.awt.Image;
25 import java.awt.GridBagConstraints;
26 import java.awt.Point;
27 import java.awt.event.MouseEvent;
28 import java.util.concurrent.TimeUnit;
29 import javax.swing.ImageIcon;
30 import javax.swing.JComponent;
31 import javax.swing.JLabel;
32 import javax.swing.JList;
33 import javax.swing.ListCellRenderer;
34 import org.openide.util.NbBundle.Messages;
36 
40 final class VideoThumbnailPanel extends javax.swing.JPanel implements ListCellRenderer<VideoThumbnailsWrapper> {
41 
42  private static final int GAP_SIZE = 4;
43  private static final Color SELECTION_COLOR = new Color(0, 120, 215);
44  private static final int BYTE_UNIT_CONVERSION = 1000;
45  private static final long serialVersionUID = 1L;
46  private static final int MAX_NAME_STRING = 120;
47 
51  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
52  VideoThumbnailPanel() {
53  initComponents();
54  this.setFocusable(true);
55  }
56 
63  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
64  private void addThumbnails(VideoThumbnailsWrapper thumbnailWrapper) {
65  imagePanel.removeAll();
66  GridBagConstraints gridBagConstraints = new GridBagConstraints();
67  gridBagConstraints.gridx = 0;
68  gridBagConstraints.gridy = 0;
69  gridBagConstraints.anchor = GridBagConstraints.LINE_START;
70  imagePanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 32767)), gridBagConstraints);
71  gridBagConstraints.gridy = 1;
72  imagePanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 32767)), gridBagConstraints);
73  gridBagConstraints.gridx++;
74  int timeIndex = 0;
75  int[] timeStamps = thumbnailWrapper.getTimeStamps();
76  for (Image image : thumbnailWrapper.getThumbnails()) {
77  gridBagConstraints.gridy = 0;
78  imagePanel.add(new JLabel(new ImageIcon(image)), gridBagConstraints);
79 
80  gridBagConstraints.gridy = 1;
81  long millis = timeStamps[timeIndex];
82  long hours = TimeUnit.MILLISECONDS.toHours(millis);
83  millis -= TimeUnit.HOURS.toMillis(hours);
84  long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
85  millis -= TimeUnit.MINUTES.toMillis(minutes);
86  long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
87  imagePanel.add(new JLabel(String.format("%01d:%02d:%02d", hours, minutes, seconds)), gridBagConstraints);
88  gridBagConstraints.gridx++;
89  gridBagConstraints.gridy = 0;
90  imagePanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 32767)), gridBagConstraints);
91  gridBagConstraints.gridy = 1;
92  imagePanel.add(new javax.swing.Box.Filler(new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 0), new java.awt.Dimension(GAP_SIZE, 32767)), gridBagConstraints);
93  gridBagConstraints.gridx++;
94  timeIndex++;
95  }
96  }
97 
103  @SuppressWarnings("unchecked")
104  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
105  private void initComponents() {
106 
107  imagePanel = new javax.swing.JPanel();
108  fileSizeLabel = new javax.swing.JLabel();
109  nameLabel = new javax.swing.JLabel();
110  scoreLabel = new javax.swing.JLabel();
111  deletedLabel = new javax.swing.JLabel();
112 
113  setBorder(javax.swing.BorderFactory.createEtchedBorder());
114 
115  imagePanel.setPreferredSize(new java.awt.Dimension(776, 115));
116  imagePanel.setLayout(new java.awt.GridBagLayout());
117 
118  scoreLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/red-circle-exclamation.png"))); // NOI18N
119  scoreLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
120  scoreLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
121  scoreLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
122 
123  deletedLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/file-icon-deleted.png"))); // NOI18N
124  deletedLabel.setMaximumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
125  deletedLabel.setMinimumSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
126  deletedLabel.setPreferredSize(new Dimension(org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize(),org.sleuthkit.autopsy.discovery.ui.DiscoveryUiUtils.getIconSize()));
127 
128  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
129  this.setLayout(layout);
130  layout.setHorizontalGroup(
131  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
132  .addGroup(layout.createSequentialGroup()
133  .addContainerGap()
134  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
135  .addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
136  .addGroup(layout.createSequentialGroup()
137  .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
138  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
139  .addComponent(deletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
140  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
141  .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
142  .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
143  .addContainerGap())
144  );
145  layout.setVerticalGroup(
146  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
147  .addGroup(layout.createSequentialGroup()
148  .addContainerGap()
149  .addComponent(nameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
150  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
151  .addComponent(imagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
152  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
153  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
154  .addComponent(deletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
155  .addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
156  .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
157  .addContainerGap())
158  );
159  }// </editor-fold>//GEN-END:initComponents
160 
161 
162  // Variables declaration - do not modify//GEN-BEGIN:variables
163  private javax.swing.JLabel deletedLabel;
164  private javax.swing.JLabel fileSizeLabel;
165  private javax.swing.JPanel imagePanel;
166  private javax.swing.JLabel nameLabel;
167  private javax.swing.JLabel scoreLabel;
168  // End of variables declaration//GEN-END:variables
169 
170  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
171  @Messages({
172  "# {0} - otherInstanceCount",
173  "VideoThumbnailPanel.nameLabel.more.text= and {0} more",
174  "VideoThumbnailPanel.deleted.text=All instances of file are deleted."})
175  @Override
176  public Component getListCellRendererComponent(JList<? extends VideoThumbnailsWrapper> list, VideoThumbnailsWrapper value, int index, boolean isSelected, boolean cellHasFocus) {
177  fileSizeLabel.setText(getFileSizeString(value.getResultFile().getFirstInstance().getSize()));
178  String nameText = value.getResultFile().getFirstInstance().getParentPath() + value.getResultFile().getFirstInstance().getName();
179  if (value.getResultFile().getAllInstances().size() > 1) {
180  nameText += Bundle.VideoThumbnailPanel_nameLabel_more_text(value.getResultFile().getAllInstances().size() - 1);
181  }
182  if (nameText.length() > MAX_NAME_STRING) {
183  nameText = "..." + nameText.substring(nameText.length() - (MAX_NAME_STRING - 3));
184  }
185  nameLabel.setText(nameText);
186  addThumbnails(value);
187  imagePanel.setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
188  DiscoveryUiUtils.setDeletedIcon(value.getResultFile().isDeleted(), deletedLabel);
189  DiscoveryUiUtils.setScoreIcon(value.getResultFile(), scoreLabel);
190  setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
191  return this;
192  }
193 
194  @Messages({"# {0} - fileSize",
195  "# {1} - units",
196  "VideoThumbnailPanel.sizeLabel.text=Size: {0} {1}",
197  "VideoThumbnailPanel.bytes.text=bytes",
198  "VideoThumbnailPanel.kiloBytes.text=KB",
199  "VideoThumbnailPanel.megaBytes.text=MB",
200  "VideoThumbnailPanel.gigaBytes.text=GB",
201  "VideoThumbnailPanel.terraBytes.text=TB"})
210  private String getFileSizeString(long bytes) {
211  long size = bytes;
212  int unitsSwitchValue = 0;
213  while (size > BYTE_UNIT_CONVERSION && unitsSwitchValue < 4) {
214  size /= BYTE_UNIT_CONVERSION;
215  unitsSwitchValue++;
216  }
217  String units;
218  switch (unitsSwitchValue) {
219  case 1:
220  units = Bundle.VideoThumbnailPanel_kiloBytes_text();
221  break;
222  case 2:
223  units = Bundle.VideoThumbnailPanel_megaBytes_text();
224  break;
225  case 3:
226  units = Bundle.VideoThumbnailPanel_gigaBytes_text();
227  break;
228  case 4:
229  units = Bundle.VideoThumbnailPanel_terraBytes_text();
230  break;
231  default:
232  units = Bundle.VideoThumbnailPanel_bytes_text();
233  break;
234  }
235  return Bundle.VideoThumbnailPanel_sizeLabel_text(size, units);
236  }
237 
238  @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
239  @Override
240  public String getToolTipText(MouseEvent event) {
241  if (event != null) {
242  //gets tooltip of internal panel item mouse is over
243  Point point = event.getPoint();
244  for (Component comp : getComponents()) {
245  if (DiscoveryUiUtils.isPointOnIcon(comp, point)) {
246  String toolTip = ((JComponent) comp).getToolTipText();
247  if (toolTip == null || toolTip.isEmpty()) {
248  return null;
249  } else {
250  return toolTip;
251  }
252  }
253  }
254  }
255  return null;
256  }
257 
258 }

Copyright © 2012-2022 Basis Technology. Generated on: Tue Jun 27 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.