Autopsy  4.11.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
LogicalImagerPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-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.logicalimager.dsp;
20 
21 import java.awt.Color;
22 import java.awt.Component;
23 import java.io.File;
24 import java.io.FilenameFilter;
25 import java.io.IOException;
26 import java.nio.file.FileStore;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34 import javax.swing.JFileChooser;
35 import javax.swing.JPanel;
36 import javax.swing.JTable;
37 import javax.swing.ListSelectionModel;
38 import javax.swing.event.DocumentEvent;
39 import javax.swing.event.DocumentListener;
40 import javax.swing.filechooser.FileSystemView;
41 import javax.swing.table.AbstractTableModel;
42 import javax.swing.table.TableModel;
43 import org.openide.util.NbBundle.Messages;
45 
50 @Messages({
51  "LogicalImagerPanel.messageLabel.noImageSelected=No image selected",
52  "LogicalImagerPanel.messageLabel.driveHasNoImages=Drive has no images",
53  "LogicalImagerPanel.selectAcquisitionFromDriveLabel.text=Select acquisition from Drive",})
54 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
55 final class LogicalImagerPanel extends JPanel implements DocumentListener {
56 
57  private static final long serialVersionUID = 1L;
58  private static final String NO_IMAGE_SELECTED = Bundle.LogicalImagerPanel_messageLabel_noImageSelected();
59  private static final String DRIVE_HAS_NO_IMAGES = Bundle.LogicalImagerPanel_messageLabel_driveHasNoImages();
60  private static final String[] EMPTY_LIST_DATA = {};
61 
62  private final JFileChooser fileChooser = new JFileChooser();
63  private final Pattern regex = Pattern.compile("Logical_Imager_(.+)_(\\d{4})(\\d{2})(\\d{2})_(\\d{2})_(\\d{2})_(\\d{2})");
64  private Path choosenImageDirPath;
65  private TableModel imageTableModel;
66 
73  private LogicalImagerPanel(String context) {
74  initComponents();
75  jScrollPane1.setBorder(null);
76  clearImageTable();
77  }
78 
87  static synchronized LogicalImagerPanel createInstance(String context) {
88  LogicalImagerPanel instance = new LogicalImagerPanel(context);
89  // post-constructor initialization of listener support without leaking references of uninitialized objects
90  instance.imageTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
91  return instance;
92  }
93 
99  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
100  private void initComponents() {
101 
102  buttonGroup1 = new javax.swing.ButtonGroup();
103  browseButton = new javax.swing.JButton();
104  importRadioButton = new javax.swing.JRadioButton();
105  manualRadioButton = new javax.swing.JRadioButton();
106  pathTextField = new javax.swing.JTextField();
107  selectFolderLabel = new javax.swing.JLabel();
108  selectDriveLabel = new javax.swing.JLabel();
109  selectFromDriveLabel = new javax.swing.JLabel();
110  driveListScrollPane = new javax.swing.JScrollPane();
111  driveList = new javax.swing.JList<>();
112  refreshButton = new javax.swing.JButton();
113  imageScrollPane = new javax.swing.JScrollPane();
114  imageTable = new javax.swing.JTable();
115  jSeparator2 = new javax.swing.JSeparator();
116  jScrollPane1 = new javax.swing.JScrollPane();
117  messageTextArea = new javax.swing.JTextArea();
118 
119  setMinimumSize(new java.awt.Dimension(0, 65));
120  setPreferredSize(new java.awt.Dimension(403, 65));
121 
122  org.openide.awt.Mnemonics.setLocalizedText(browseButton, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.browseButton.text")); // NOI18N
123  browseButton.setEnabled(false);
124  browseButton.addActionListener(new java.awt.event.ActionListener() {
125  public void actionPerformed(java.awt.event.ActionEvent evt) {
126  browseButtonActionPerformed(evt);
127  }
128  });
129 
130  buttonGroup1.add(importRadioButton);
131  importRadioButton.setSelected(true);
132  org.openide.awt.Mnemonics.setLocalizedText(importRadioButton, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.importRadioButton.text")); // NOI18N
133  importRadioButton.setToolTipText(org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.importRadioButton.toolTipText")); // NOI18N
134  importRadioButton.addActionListener(new java.awt.event.ActionListener() {
135  public void actionPerformed(java.awt.event.ActionEvent evt) {
136  importRadioButtonActionPerformed(evt);
137  }
138  });
139 
140  buttonGroup1.add(manualRadioButton);
141  org.openide.awt.Mnemonics.setLocalizedText(manualRadioButton, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.manualRadioButton.text")); // NOI18N
142  manualRadioButton.addActionListener(new java.awt.event.ActionListener() {
143  public void actionPerformed(java.awt.event.ActionEvent evt) {
144  manualRadioButtonActionPerformed(evt);
145  }
146  });
147 
148  pathTextField.setText(org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.pathTextField.text")); // NOI18N
149  pathTextField.setDisabledTextColor(java.awt.Color.black);
150  pathTextField.setEnabled(false);
151 
152  org.openide.awt.Mnemonics.setLocalizedText(selectFolderLabel, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.selectFolderLabel.text")); // NOI18N
153 
154  org.openide.awt.Mnemonics.setLocalizedText(selectDriveLabel, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.selectDriveLabel.text")); // NOI18N
155 
156  org.openide.awt.Mnemonics.setLocalizedText(selectFromDriveLabel, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.selectFromDriveLabel.text")); // NOI18N
157 
158  driveList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
159  driveList.addMouseListener(new java.awt.event.MouseAdapter() {
160  public void mouseReleased(java.awt.event.MouseEvent evt) {
161  driveListMouseReleased(evt);
162  }
163  });
164  driveList.addKeyListener(new java.awt.event.KeyAdapter() {
165  public void keyReleased(java.awt.event.KeyEvent evt) {
166  driveListKeyReleased(evt);
167  }
168  });
169  driveListScrollPane.setViewportView(driveList);
170 
171  org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.refreshButton.text")); // NOI18N
172  refreshButton.addActionListener(new java.awt.event.ActionListener() {
173  public void actionPerformed(java.awt.event.ActionEvent evt) {
174  refreshButtonActionPerformed(evt);
175  }
176  });
177 
178  imageScrollPane.setPreferredSize(new java.awt.Dimension(346, 402));
179 
180  imageTable.setModel(new javax.swing.table.DefaultTableModel(
181  new Object [][] {
182 
183  },
184  new String [] {
185 
186  }
187  ));
188  imageTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
189  imageTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
190  imageTable.setShowHorizontalLines(false);
191  imageTable.setShowVerticalLines(false);
192  imageTable.getTableHeader().setReorderingAllowed(false);
193  imageTable.setUpdateSelectionOnSort(false);
194  imageTable.addMouseListener(new java.awt.event.MouseAdapter() {
195  public void mouseReleased(java.awt.event.MouseEvent evt) {
196  imageTableMouseReleased(evt);
197  }
198  });
199  imageTable.addKeyListener(new java.awt.event.KeyAdapter() {
200  public void keyReleased(java.awt.event.KeyEvent evt) {
201  imageTableKeyReleased(evt);
202  }
203  });
204  imageScrollPane.setViewportView(imageTable);
205  imageTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
206 
207  jScrollPane1.setBorder(null);
208 
209  messageTextArea.setBackground(new java.awt.Color(240, 240, 240));
210  messageTextArea.setColumns(20);
211  messageTextArea.setForeground(java.awt.Color.red);
212  messageTextArea.setLineWrap(true);
213  messageTextArea.setRows(3);
214  messageTextArea.setText(org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class, "LogicalImagerPanel.messageTextArea.text")); // NOI18N
215  messageTextArea.setBorder(null);
216  messageTextArea.setDisabledTextColor(java.awt.Color.red);
217  messageTextArea.setEnabled(false);
218  messageTextArea.setMargin(new java.awt.Insets(0, 0, 0, 0));
219  jScrollPane1.setViewportView(messageTextArea);
220 
221  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
222  this.setLayout(layout);
223  layout.setHorizontalGroup(
224  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
225  .addGroup(layout.createSequentialGroup()
226  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
227  .addGroup(layout.createSequentialGroup()
228  .addGap(10, 10, 10)
229  .addComponent(selectFolderLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
230  .addGap(13, 13, 13)
231  .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 474, javax.swing.GroupLayout.PREFERRED_SIZE))
232  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
233  .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING)
234  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
235  .addGroup(layout.createSequentialGroup()
236  .addGap(41, 41, 41)
237  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
238  .addComponent(driveListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)
239  .addComponent(refreshButton))
240  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
241  .addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 377, javax.swing.GroupLayout.PREFERRED_SIZE))
242  .addGroup(layout.createSequentialGroup()
243  .addGap(20, 20, 20)
244  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
245  .addGroup(layout.createSequentialGroup()
246  .addComponent(manualRadioButton)
247  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
248  .addComponent(browseButton))
249  .addComponent(importRadioButton)
250  .addGroup(layout.createSequentialGroup()
251  .addGap(21, 21, 21)
252  .addComponent(selectDriveLabel)
253  .addGap(113, 113, 113)
254  .addComponent(selectFromDriveLabel))))))
255  .addGroup(layout.createSequentialGroup()
256  .addContainerGap()
257  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 568, javax.swing.GroupLayout.PREFERRED_SIZE)))
258  .addContainerGap(338, Short.MAX_VALUE))
259  );
260  layout.setVerticalGroup(
261  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
262  .addGroup(layout.createSequentialGroup()
263  .addGap(16, 16, 16)
264  .addComponent(importRadioButton)
265  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
266  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
267  .addComponent(selectDriveLabel)
268  .addComponent(selectFromDriveLabel))
269  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
270  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
271  .addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
272  .addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 461, Short.MAX_VALUE))
273  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
274  .addComponent(refreshButton)
275  .addGap(18, 18, 18)
276  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
277  .addComponent(browseButton)
278  .addComponent(manualRadioButton))
279  .addGap(18, 18, 18)
280  .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
281  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
282  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
283  .addComponent(selectFolderLabel)
284  .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
285  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
286  .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
287  .addGap(6, 6, 6))
288  );
289  }// </editor-fold>//GEN-END:initComponents
290 
291  private static String humanReadableByteCount(long bytes, boolean si) {
292  int unit = si ? 1000 : 1024;
293  if (bytes < unit) {
294  return bytes + " B"; //NON-NLS
295  }
296  int exp = (int) (Math.log(bytes) / Math.log(unit));
297  String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); //NON-NLS
298  return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); //NON-NLS
299  }
300 
301  @Messages({
302  "# {0} - sparseImageDirectory",
303  "LogicalImagerPanel.messageLabel.directoryDoesNotContainSparseImage=Directory {0} does not contain any images",
304  "# {0} - invalidFormatDirectory",
305  "LogicalImagerPanel.messageLabel.directoryFormatInvalid=Directory {0} does not match format Logical_Imager_HOSTNAME_yyyymmdd_HH_MM_SS"
306  })
307  private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
308  imageTable.clearSelection();
309  choosenImageDirPath = null;
310  setErrorMessage(NO_IMAGE_SELECTED);
311  fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
312  int retval = fileChooser.showOpenDialog(this);
313  if (retval == JFileChooser.APPROVE_OPTION) {
314  String path = fileChooser.getSelectedFile().getPath();
315  Matcher m = regex.matcher(path);
316  if (m.find()) {
317  File dir = Paths.get(path).toFile();
318  String[] vhdFiles = dir.list(new FilenameFilter() {
319  @Override
320  public boolean accept(File dir, String name) {
321  return name.endsWith(".vhd");
322  }
323  });
324  if (vhdFiles.length == 0) {
325  setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryDoesNotContainSparseImage(path));
326  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
327  return;
328  }
329  choosenImageDirPath = Paths.get(path);
330  setNormalMessage(path);
331  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
332  } else {
333  setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryFormatInvalid(path));
334  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
335  }
336  } else {
337  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
338  }
339  }//GEN-LAST:event_browseButtonActionPerformed
340 
341  private void imageTableSelect() {
342  int index = imageTable.getSelectedRow();
343  if (index != -1) {
344  choosenImageDirPath = Paths.get((String) imageTableModel.getValueAt(index, 2));
345  setNormalMessage(choosenImageDirPath.toString());
346  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
347  } else {
348  choosenImageDirPath = null;
349  setErrorMessage(NO_IMAGE_SELECTED);
350  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
351  }
352  }
353 
354  private boolean dirHasVhdFiles(File dir) {
355  File[] fList = dir.listFiles(new FilenameFilter() {
356  @Override
357  public boolean accept(File dir, String name) {
358  return name.endsWith(".vhd");
359  }
360  });
361  return (fList != null && fList.length != 0);
362  }
363 
364  private void driveListSelect() {
365  String selectedStr = driveList.getSelectedValue();
366  if (selectedStr == null) {
367  return;
368  }
369  String driveLetter = selectedStr.substring(0, 3);
370  File directory = new File(driveLetter);
371  File[] fList = directory.listFiles();
372 
373  if (fList != null) {
374  imageTableModel = new ImageTableModel();
375  int row = 0;
376  // Find all directories with name like Logical_Imager_HOSTNAME_yyyymmdd_HH_MM_SS
377  // and has vhd files in it
378  for (File file : fList) {
379  if (file.isDirectory() && dirHasVhdFiles(file)) {
380  String dir = file.getName();
381  Matcher m = regex.matcher(dir);
382  if (m.find()) {
383  String imageDirPath = driveLetter + dir;
384  String hostname = m.group(1);
385  String year = m.group(2);
386  String month = m.group(3);
387  String day = m.group(4);
388  String hour = m.group(5);
389  String minute = m.group(6);
390  String second = m.group(7);
391  String extractDate = year + "/" + month + "/" + day
392  + " " + hour + ":" + minute + ":" + second;
393  imageTableModel.setValueAt(hostname, row, 0);
394  imageTableModel.setValueAt(extractDate, row, 1);
395  imageTableModel.setValueAt(imageDirPath, row, 2);
396  row++;
397  }
398  }
399  }
400  selectFromDriveLabel.setText(Bundle.LogicalImagerPanel_selectAcquisitionFromDriveLabel_text()
401  + " " + driveLetter);
402  imageTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
403  imageTable.setModel(imageTableModel);
404  fixImageTableColumnWidth();
405  // If there are any images, select the first one
406  if (imageTable.getRowCount() > 0) {
407  imageTable.setRowSelectionInterval(0, 0);
408  imageTableSelect();
409  } else {
410  choosenImageDirPath = null;
411  setErrorMessage(DRIVE_HAS_NO_IMAGES);
412  }
413  } else {
414  clearImageTable();
415  choosenImageDirPath = null;
416  setErrorMessage(DRIVE_HAS_NO_IMAGES);
417  }
418  }
419 
420  private void fixImageTableColumnWidth() {
421  int width = imageScrollPane.getPreferredSize().width - 2;
422  imageTable.getColumnModel().getColumn(0).setPreferredWidth((int) (.60 * width));
423  imageTable.getColumnModel().getColumn(1).setPreferredWidth((int) (.40 * width));
424  }
425 
426  private void setErrorMessage(String msg) {
427  messageTextArea.setForeground(Color.red);
428  messageTextArea.setText(msg);
429  pathTextField.setText("");
430  }
431 
432  private void setNormalMessage(String msg) {
433  pathTextField.setText(msg);
434  messageTextArea.setText("");
435  }
436 
437  private void clearImageTable() {
438  imageTableModel = new ImageTableModel();
439  imageTable.setModel(imageTableModel);
440  fixImageTableColumnWidth();
441  }
442 
443  private void toggleMouseAndKeyListeners(Component component, boolean isEnable) {
444  component.setEnabled(isEnable);
445  }
446 
447  private void manualRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manualRadioButtonActionPerformed
448  browseButton.setEnabled(true);
449 
450  // disable import panel
451  toggleMouseAndKeyListeners(driveList, false);
452  toggleMouseAndKeyListeners(driveListScrollPane, false);
453  toggleMouseAndKeyListeners(imageScrollPane, false);
454  toggleMouseAndKeyListeners(imageTable, false);
455 
456  refreshButton.setEnabled(false);
457 
458  choosenImageDirPath = null;
459  setNormalMessage("");
460  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
461  }//GEN-LAST:event_manualRadioButtonActionPerformed
462 
463  private void importRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importRadioButtonActionPerformed
464  browseButton.setEnabled(false);
465 
466  toggleMouseAndKeyListeners(driveList, true);
467  toggleMouseAndKeyListeners(driveListScrollPane, true);
468  toggleMouseAndKeyListeners(imageScrollPane, true);
469  toggleMouseAndKeyListeners(imageTable, true);
470 
471  refreshButton.setEnabled(true);
472 
473  choosenImageDirPath = null;
474  setNormalMessage("");
475  refreshButton.doClick();
476  }//GEN-LAST:event_importRadioButtonActionPerformed
477 
478  @Messages({
479  "LogicalImagerPanel.messageLabel.scanningExternalDrives=Scanning external drives for images ...",
480  "LogicalImagerPanel.messageLabel.noExternalDriveFound=No drive found"
481  })
482  private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
483  // Scan external drives for vhd images
484  clearImageTable();
485  setNormalMessage(Bundle.LogicalImagerPanel_messageLabel_scanningExternalDrives());
486  List<String> listData = new ArrayList<>();
487  File[] roots = File.listRoots();
488  int firstRemovableDrive = -1;
489  int i = 0;
490  for (File root : roots) {
491  String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root);
492  long spaceInBytes = root.getTotalSpace();
493  String sizeWithUnit = humanReadableByteCount(spaceInBytes, false);
494  listData.add(root + " (" + description + ") (" + sizeWithUnit + ")");
495  if (firstRemovableDrive == -1) {
496  try {
497  FileStore fileStore = Files.getFileStore(root.toPath());
498  if ((boolean) fileStore.getAttribute("volume:isRemovable")) { //NON-NLS
499  firstRemovableDrive = i;
500  }
501  } catch (IOException ex) {
502  i++;
503  continue;
504  }
505  }
506  i++;
507  }
508  driveList.setListData(listData.toArray(new String[listData.size()]));
509  if (!listData.isEmpty()) {
510  // auto-select the first external drive, if any
511  driveList.setSelectedIndex(firstRemovableDrive == -1 ? 0 : firstRemovableDrive);
512  driveListMouseReleased(null);
513  driveList.requestFocusInWindow();
514  } else {
515  setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_noExternalDriveFound());
516  }
517  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
518  }//GEN-LAST:event_refreshButtonActionPerformed
519 
520  private void driveListKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_driveListKeyReleased
521  if (importRadioButton.isSelected()) {
522  driveListSelect();
523  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
524  }
525  }//GEN-LAST:event_driveListKeyReleased
526 
527  private void imageTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_imageTableKeyReleased
528  if (importRadioButton.isSelected()) {
529  imageTableSelect();
530  }
531  }//GEN-LAST:event_imageTableKeyReleased
532 
533  private void imageTableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_imageTableMouseReleased
534  if (importRadioButton.isSelected()) {
535  imageTableSelect();
536  }
537  }//GEN-LAST:event_imageTableMouseReleased
538 
539  private void driveListMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_driveListMouseReleased
540  if (importRadioButton.isSelected()) {
541  driveListSelect();
542  firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), true, false);
543  }
544  }//GEN-LAST:event_driveListMouseReleased
545 
546 
547  // Variables declaration - do not modify//GEN-BEGIN:variables
548  private javax.swing.JButton browseButton;
549  private javax.swing.ButtonGroup buttonGroup1;
550  private javax.swing.JList<String> driveList;
551  private javax.swing.JScrollPane driveListScrollPane;
552  private javax.swing.JScrollPane imageScrollPane;
553  private javax.swing.JTable imageTable;
554  private javax.swing.JRadioButton importRadioButton;
555  private javax.swing.JScrollPane jScrollPane1;
556  private javax.swing.JSeparator jSeparator2;
557  private javax.swing.JRadioButton manualRadioButton;
558  private javax.swing.JTextArea messageTextArea;
559  private javax.swing.JTextField pathTextField;
560  private javax.swing.JButton refreshButton;
561  private javax.swing.JLabel selectDriveLabel;
562  private javax.swing.JLabel selectFolderLabel;
563  private javax.swing.JLabel selectFromDriveLabel;
564  // End of variables declaration//GEN-END:variables
565 
566  void reset() {
567  //reset the UI elements to default
568  choosenImageDirPath = null;
569  setNormalMessage("");
570  driveList.setListData(EMPTY_LIST_DATA);
571  clearImageTable();
572  if (importRadioButton.isSelected()) {
573  refreshButton.doClick();
574  }
575  }
576 
582  boolean validatePanel() {
583  return choosenImageDirPath != null && choosenImageDirPath.toFile().exists();
584  }
585 
586  Path getImageDirPath() {
587  return choosenImageDirPath;
588  }
589 
590  @Override
591  public void insertUpdate(DocumentEvent e) {
592  }
593 
594  @Override
595  public void removeUpdate(DocumentEvent e) {
596  }
597 
598  @Override
599  public void changedUpdate(DocumentEvent e) {
600  }
601 
602  void storeSettings() {
603  }
604 
608  private class ImageTableModel extends AbstractTableModel {
609 
610  private final List<String> hostnames = new ArrayList<>();
611  private final List<String> extractDates = new ArrayList<>();
612  private final List<String> imageDirPaths = new ArrayList<>();
613 
614  @Override
615  public int getRowCount() {
616  return hostnames.size();
617  }
618 
619  @Override
620  public int getColumnCount() {
621  return 2;
622  }
623 
624  @Messages({
625  "LogicalImagerPanel.imageTable.columnModel.title0=Hostname",
626  "LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date"
627  })
628  @Override
629  public String getColumnName(int column) {
630  String colName = null;
631  switch (column) {
632  case 0:
633  colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title0();
634  break;
635  case 1:
636  colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title1();
637  break;
638  default:
639  break;
640  }
641  return colName;
642  }
643 
644  @Override
645  public Object getValueAt(int rowIndex, int columnIndex) {
646  Object ret = null;
647  switch (columnIndex) {
648  case 0:
649  ret = hostnames.get(rowIndex);
650  break;
651  case 1:
652  ret = extractDates.get(rowIndex);
653  break;
654  case 2:
655  ret = imageDirPaths.get(rowIndex);
656  break;
657  default:
658  throw new UnsupportedOperationException("Invalid table column index: " + columnIndex); //NON-NLS
659  }
660  return ret;
661  }
662 
663  @Override
664  public boolean isCellEditable(int rowIndex, int columnIndex) {
665  return false;
666  }
667 
668  @Override
669  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
670  switch (columnIndex) {
671  case 0:
672  hostnames.add((String) aValue);
673  break;
674  case 1:
675  extractDates.add((String) aValue);
676  break;
677  case 2:
678  imageDirPaths.add((String) aValue);
679  break;
680  default:
681  throw new UnsupportedOperationException("Invalid table column index: " + columnIndex); //NON-NLS
682  }
683  // Only show the hostname and extractDates column
684  if (columnIndex < 2) {
685  super.setValueAt(aValue, rowIndex, columnIndex);
686  }
687  }
688  }
689 }

Copyright © 2012-2018 Basis Technology. Generated on: Fri Jun 21 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.