19 package org.sleuthkit.autopsy.logicalimager.dsp;
21 import java.awt.Color;
22 import java.awt.Component;
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.logging.Level;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import javax.swing.JFileChooser;
36 import javax.swing.JPanel;
37 import javax.swing.JTable;
38 import javax.swing.ListSelectionModel;
39 import javax.swing.event.DocumentEvent;
40 import javax.swing.event.DocumentListener;
41 import javax.swing.filechooser.FileSystemView;
42 import javax.swing.table.DefaultTableModel;
43 import javax.swing.table.TableColumn;
44 import org.openide.util.NbBundle.Messages;
54 "LogicalImagerPanel.messageLabel.noImageSelected=No image selected",
55 "LogicalImagerPanel.messageLabel.driveHasNoImages=Drive has no images",
56 "LogicalImagerPanel.selectAcquisitionFromDriveLabel.text=Select acquisition from Drive",})
57 @SuppressWarnings(
"PMD.SingularField")
58 final class LogicalImagerPanel extends JPanel implements DocumentListener {
60 private static final Logger logger = Logger.getLogger(LogicalImagerPanel.class.getName());
61 private static final long serialVersionUID = 1L;
62 private static final String NO_IMAGE_SELECTED = Bundle.LogicalImagerPanel_messageLabel_noImageSelected();
63 private static final String DRIVE_HAS_NO_IMAGES = Bundle.LogicalImagerPanel_messageLabel_driveHasNoImages();
64 private static final int COLUMN_TO_SORT_ON_INDEX = 1;
65 private static final int NUMBER_OF_VISIBLE_COLUMNS = 2;
66 private static final String[] EMPTY_LIST_DATA = {};
68 private final Pattern regex = Pattern.compile(
"Logical_Imager_(.+)_(\\d{4})(\\d{2})(\\d{2})_(\\d{2})_(\\d{2})_(\\d{2})");
69 private Path manualImageDirPath;
70 private DefaultTableModel imageTableModel;
71 private final JFileChooserFactory chooserHelper;
79 private LogicalImagerPanel(String context) {
81 configureImageTable();
82 jScrollPane1.setBorder(null);
84 chooserHelper =
new JFileChooserFactory();
91 private void configureImageTable() {
93 if (imageTable.getColumnCount() > NUMBER_OF_VISIBLE_COLUMNS) {
94 TableColumn columnToHide = imageTable.getColumn(imageTableModel.getColumnName(NUMBER_OF_VISIBLE_COLUMNS));
95 if (columnToHide != null) {
96 imageTable.removeColumn(columnToHide);
99 imageTable.getRowSorter().toggleSortOrder(COLUMN_TO_SORT_ON_INDEX);
100 imageTable.getRowSorter().toggleSortOrder(COLUMN_TO_SORT_ON_INDEX);
112 static synchronized LogicalImagerPanel createInstance(String context) {
113 LogicalImagerPanel instance =
new LogicalImagerPanel(context);
115 instance.imageTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
125 private void initComponents() {
127 buttonGroup1 =
new javax.swing.ButtonGroup();
128 browseButton =
new javax.swing.JButton();
129 importRadioButton =
new javax.swing.JRadioButton();
130 manualRadioButton =
new javax.swing.JRadioButton();
131 pathTextField =
new javax.swing.JTextField();
132 selectFolderLabel =
new javax.swing.JLabel();
133 selectDriveLabel =
new javax.swing.JLabel();
134 selectFromDriveLabel =
new javax.swing.JLabel();
135 driveListScrollPane =
new javax.swing.JScrollPane();
136 driveList =
new javax.swing.JList<>();
137 refreshButton =
new javax.swing.JButton();
138 imageScrollPane =
new javax.swing.JScrollPane();
139 imageTable =
new javax.swing.JTable();
140 jSeparator2 =
new javax.swing.JSeparator();
141 jScrollPane1 =
new javax.swing.JScrollPane();
142 messageTextArea =
new javax.swing.JTextArea();
144 setMinimumSize(
new java.awt.Dimension(0, 65));
145 setPreferredSize(
new java.awt.Dimension(403, 65));
147 org.openide.awt.Mnemonics.setLocalizedText(browseButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.browseButton.text"));
148 browseButton.setEnabled(
false);
149 browseButton.addActionListener(
new java.awt.event.ActionListener() {
150 public void actionPerformed(java.awt.event.ActionEvent evt) {
151 browseButtonActionPerformed(evt);
155 buttonGroup1.add(importRadioButton);
156 importRadioButton.setSelected(
true);
157 org.openide.awt.Mnemonics.setLocalizedText(importRadioButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.importRadioButton.text"));
158 importRadioButton.setToolTipText(
"");
159 importRadioButton.addActionListener(
new java.awt.event.ActionListener() {
160 public void actionPerformed(java.awt.event.ActionEvent evt) {
161 importRadioButtonActionPerformed(evt);
165 buttonGroup1.add(manualRadioButton);
166 org.openide.awt.Mnemonics.setLocalizedText(manualRadioButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.manualRadioButton.text"));
167 manualRadioButton.addActionListener(
new java.awt.event.ActionListener() {
168 public void actionPerformed(java.awt.event.ActionEvent evt) {
169 manualRadioButtonActionPerformed(evt);
173 pathTextField.setDisabledTextColor(java.awt.Color.black);
174 pathTextField.setEnabled(
false);
176 org.openide.awt.Mnemonics.setLocalizedText(selectFolderLabel,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.selectFolderLabel.text"));
178 org.openide.awt.Mnemonics.setLocalizedText(selectDriveLabel,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.selectDriveLabel.text"));
180 org.openide.awt.Mnemonics.setLocalizedText(selectFromDriveLabel,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.selectFromDriveLabel.text"));
182 driveList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
183 driveList.addMouseListener(
new java.awt.event.MouseAdapter() {
184 public void mouseReleased(java.awt.event.MouseEvent evt) {
185 driveListMouseReleased(evt);
188 driveList.addKeyListener(
new java.awt.event.KeyAdapter() {
189 public void keyReleased(java.awt.event.KeyEvent evt) {
190 driveListKeyReleased(evt);
193 driveListScrollPane.setViewportView(driveList);
195 org.openide.awt.Mnemonics.setLocalizedText(refreshButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.refreshButton.text"));
196 refreshButton.addActionListener(
new java.awt.event.ActionListener() {
197 public void actionPerformed(java.awt.event.ActionEvent evt) {
198 refreshButtonActionPerformed(evt);
202 imageScrollPane.setPreferredSize(
new java.awt.Dimension(346, 402));
204 imageTable.setAutoCreateRowSorter(
true);
205 imageTable.setModel(
new javax.swing.table.DefaultTableModel(
213 imageTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
214 imageTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
215 imageTable.setShowHorizontalLines(
false);
216 imageTable.setShowVerticalLines(
false);
217 imageTable.getTableHeader().setReorderingAllowed(
false);
218 imageTable.addMouseListener(
new java.awt.event.MouseAdapter() {
219 public void mouseReleased(java.awt.event.MouseEvent evt) {
220 imageTableMouseReleased(evt);
223 imageTable.addKeyListener(
new java.awt.event.KeyAdapter() {
224 public void keyReleased(java.awt.event.KeyEvent evt) {
225 imageTableKeyReleased(evt);
228 imageScrollPane.setViewportView(imageTable);
229 imageTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
231 jScrollPane1.setBorder(null);
233 messageTextArea.setBackground(
new java.awt.Color(240, 240, 240));
234 messageTextArea.setColumns(20);
235 messageTextArea.setForeground(java.awt.Color.red);
236 messageTextArea.setLineWrap(
true);
237 messageTextArea.setRows(3);
238 messageTextArea.setBorder(null);
239 messageTextArea.setDisabledTextColor(java.awt.Color.red);
240 messageTextArea.setEnabled(
false);
241 messageTextArea.setMargin(
new java.awt.Insets(0, 0, 0, 0));
242 jScrollPane1.setViewportView(messageTextArea);
244 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
245 this.setLayout(layout);
246 layout.setHorizontalGroup(
247 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
248 .addGroup(layout.createSequentialGroup()
249 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
250 .addGroup(layout.createSequentialGroup()
252 .addComponent(selectFolderLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
254 .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 474, javax.swing.GroupLayout.PREFERRED_SIZE))
255 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,
false)
256 .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING)
257 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
258 .addGroup(layout.createSequentialGroup()
260 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
261 .addComponent(driveListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)
262 .addComponent(refreshButton))
263 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
264 .addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 377, javax.swing.GroupLayout.PREFERRED_SIZE))
265 .addGroup(layout.createSequentialGroup()
267 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
268 .addGroup(layout.createSequentialGroup()
269 .addComponent(manualRadioButton)
270 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
271 .addComponent(browseButton))
272 .addComponent(importRadioButton)
273 .addGroup(layout.createSequentialGroup()
275 .addComponent(selectDriveLabel)
276 .addGap(113, 113, 113)
277 .addComponent(selectFromDriveLabel))))))
278 .addGroup(layout.createSequentialGroup()
280 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 568, javax.swing.GroupLayout.PREFERRED_SIZE)))
281 .addContainerGap(93, Short.MAX_VALUE))
283 layout.setVerticalGroup(
284 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
285 .addGroup(layout.createSequentialGroup()
287 .addComponent(importRadioButton)
288 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
289 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
290 .addComponent(selectDriveLabel)
291 .addComponent(selectFromDriveLabel))
292 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
293 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
294 .addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
295 .addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 198, Short.MAX_VALUE))
296 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
297 .addComponent(refreshButton)
299 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
300 .addComponent(browseButton)
301 .addComponent(manualRadioButton))
303 .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
304 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
305 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
306 .addComponent(selectFolderLabel)
307 .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
308 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
309 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
315 "# {0} - sparseImageDirectory",
316 "LogicalImagerPanel.messageLabel.directoryDoesNotContainSparseImage=Directory {0} does not contain any images",
317 "# {0} - invalidFormatDirectory",
318 "LogicalImagerPanel.messageLabel.directoryFormatInvalid=Directory {0} does not match format Logical_Imager_HOSTNAME_yyyymmdd_HH_MM_SS"
320 private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {
321 JFileChooser fileChooser = chooserHelper.getChooser();
322 imageTable.clearSelection();
323 manualImageDirPath = null;
324 setErrorMessage(NO_IMAGE_SELECTED);
325 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
326 int retval = fileChooser.showOpenDialog(
this);
327 if (retval == JFileChooser.APPROVE_OPTION) {
328 String path = fileChooser.getSelectedFile().getPath();
329 Matcher m = regex.matcher(path);
331 File dir = Paths.get(path).toFile();
332 String[] vhdFiles = dir.list(
new FilenameFilter() {
334 public boolean accept(File dir, String name) {
335 return name.endsWith(
".vhd");
338 if (vhdFiles.length == 0) {
340 String[] directories = dir.list(
new FilenameFilter() {
342 public boolean accept(File dir, String name) {
343 return Paths.get(dir.toString(), name).toFile().isDirectory();
346 if (directories.length == 0) {
348 setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryDoesNotContainSparseImage(path));
349 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
353 manualImageDirPath = Paths.get(path);
354 setNormalMessage(path);
355 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
357 setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryFormatInvalid(path));
358 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
361 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
365 private void imageTableSelect() {
366 int index = imageTable.getSelectedRow();
368 setNormalMessage((String) imageTableModel.getValueAt(imageTable.convertRowIndexToModel(index), 2));
369 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
371 setErrorMessage(NO_IMAGE_SELECTED);
372 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
376 private boolean dirHasImagerResult(File dir) {
377 String[] fList = dir.list(
new FilenameFilter() {
379 public boolean accept(File dir, String name) {
380 return name.endsWith(
".vhd") || Paths.get(dir.toString(), name).toFile().isDirectory();
383 return (fList != null && fList.length != 0);
386 private void driveListSelect() {
387 String selectedStr = driveList.getSelectedValue();
388 if (selectedStr == null) {
391 String driveLetter = selectedStr.substring(0, 3);
392 File directory =
new File(driveLetter);
393 File[] fList = directory.listFiles();
396 imageTableModel =
new ImageTableModel();
399 for (File file : fList) {
400 if (file.isDirectory() && dirHasImagerResult(file)) {
401 String dir = file.getName();
402 Matcher m = regex.matcher(dir);
404 String imageDirPath = driveLetter + dir;
405 String hostname = m.group(1);
406 String year = m.group(2);
407 String month = m.group(3);
408 String day = m.group(4);
409 String hour = m.group(5);
410 String minute = m.group(6);
411 String second = m.group(7);
412 String extractDate = year +
"/" + month +
"/" + day
413 +
" " + hour +
":" + minute +
":" + second;
414 imageTableModel.addRow(
new Object[]{hostname, extractDate, imageDirPath});
418 selectFromDriveLabel.setText(Bundle.LogicalImagerPanel_selectAcquisitionFromDriveLabel_text()
419 +
" " + driveLetter);
420 imageTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
421 imageTable.setModel(imageTableModel);
422 configureImageTable();
423 fixImageTableColumnWidth();
425 if (imageTable.getRowCount() > 0) {
426 imageTable.setRowSelectionInterval(0, 0);
429 setErrorMessage(DRIVE_HAS_NO_IMAGES);
433 setErrorMessage(DRIVE_HAS_NO_IMAGES);
437 private void fixImageTableColumnWidth() {
438 int width = imageScrollPane.getPreferredSize().width - 2;
439 imageTable.getColumnModel().getColumn(0).setPreferredWidth((
int) (.60 * width));
440 imageTable.getColumnModel().getColumn(1).setPreferredWidth((
int) (.40 * width));
443 private void setErrorMessage(String msg) {
444 messageTextArea.setForeground(Color.red);
445 messageTextArea.setText(msg);
446 pathTextField.setText(
"");
449 private void setNormalMessage(String msg) {
450 pathTextField.setText(msg);
451 messageTextArea.setText(
"");
454 private void clearImageTable() {
455 imageTableModel =
new ImageTableModel();
456 imageTable.setModel(imageTableModel);
457 configureImageTable();
458 fixImageTableColumnWidth();
461 private void toggleMouseAndKeyListeners(Component component,
boolean isEnable) {
462 component.setEnabled(isEnable);
465 private void manualRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {
466 browseButton.setEnabled(
true);
469 toggleMouseAndKeyListeners(driveList,
false);
470 toggleMouseAndKeyListeners(driveListScrollPane,
false);
471 toggleMouseAndKeyListeners(imageScrollPane,
false);
472 toggleMouseAndKeyListeners(imageTable,
false);
474 refreshButton.setEnabled(
false);
476 manualImageDirPath = null;
477 setNormalMessage(
"");
478 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
481 private void importRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {
482 browseButton.setEnabled(
false);
484 toggleMouseAndKeyListeners(driveList,
true);
485 toggleMouseAndKeyListeners(driveListScrollPane,
true);
486 toggleMouseAndKeyListeners(imageScrollPane,
true);
487 toggleMouseAndKeyListeners(imageTable,
true);
489 refreshButton.setEnabled(
true);
491 manualImageDirPath = null;
492 setNormalMessage(
"");
493 refreshButton.doClick();
497 "LogicalImagerPanel.messageLabel.scanningExternalDrives=Scanning external drives for images ...",
498 "LogicalImagerPanel.messageLabel.noExternalDriveFound=No drive found"
500 private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {
503 setNormalMessage(Bundle.LogicalImagerPanel_messageLabel_scanningExternalDrives());
504 List<String> listData =
new ArrayList<>();
505 File[] roots = File.listRoots();
506 int firstRemovableDrive = -1;
508 for (File root : roots) {
509 if (DriveListUtils.isNetworkDrive(root.toString().replace(
":\\",
""))) {
512 String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root);
513 long spaceInBytes = root.getTotalSpace();
514 String sizeWithUnit = DriveListUtils.humanReadableByteCount(spaceInBytes,
false);
515 listData.add(root +
" (" + description +
") (" + sizeWithUnit +
")");
516 if (firstRemovableDrive == -1) {
518 FileStore fileStore = Files.getFileStore(root.toPath());
519 if ((
boolean) fileStore.getAttribute(
"volume:isRemovable")) {
520 firstRemovableDrive = i;
522 }
catch (IOException ignored) {
524 logger.log(Level.INFO, String.format(
"Unable to select first removable drive found: %s", ignored.getMessage()));
529 driveList.setListData(listData.toArray(
new String[listData.size()]));
530 if (!listData.isEmpty()) {
532 driveList.setSelectedIndex(firstRemovableDrive == -1 ? 0 : firstRemovableDrive);
533 driveListMouseReleased(null);
534 driveList.requestFocusInWindow();
536 setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_noExternalDriveFound());
538 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
541 private void driveListKeyReleased(java.awt.event.KeyEvent evt) {
542 if (importRadioButton.isSelected()) {
544 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
548 private void imageTableKeyReleased(java.awt.event.KeyEvent evt) {
549 if (importRadioButton.isSelected()) {
554 private void imageTableMouseReleased(java.awt.event.MouseEvent evt) {
555 if (importRadioButton.isSelected()) {
560 private void driveListMouseReleased(java.awt.event.MouseEvent evt) {
561 if (importRadioButton.isSelected()) {
563 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
569 private javax.swing.JButton browseButton;
570 private javax.swing.ButtonGroup buttonGroup1;
571 private javax.swing.JList<String> driveList;
572 private javax.swing.JScrollPane driveListScrollPane;
573 private javax.swing.JScrollPane imageScrollPane;
574 private javax.swing.JTable imageTable;
575 private javax.swing.JRadioButton importRadioButton;
576 private javax.swing.JScrollPane jScrollPane1;
577 private javax.swing.JSeparator jSeparator2;
578 private javax.swing.JRadioButton manualRadioButton;
579 private javax.swing.JTextArea messageTextArea;
580 private javax.swing.JTextField pathTextField;
581 private javax.swing.JButton refreshButton;
582 private javax.swing.JLabel selectDriveLabel;
583 private javax.swing.JLabel selectFolderLabel;
584 private javax.swing.JLabel selectFromDriveLabel;
589 manualImageDirPath = null;
590 setNormalMessage(
"");
591 driveList.setListData(EMPTY_LIST_DATA);
593 if (importRadioButton.isSelected()) {
594 refreshButton.doClick();
603 boolean validatePanel() {
604 if (manualRadioButton.isSelected()) {
605 return manualImageDirPath != null && manualImageDirPath.toFile().exists();
606 }
else if (imageTable.getSelectedRow() != -1) {
607 Path path = Paths.get((String) imageTableModel.getValueAt(imageTable.convertRowIndexToModel(imageTable.getSelectedRow()), 2));
608 return path != null && path.toFile().exists();
614 Path getImageDirPath() {
615 if (manualRadioButton.isSelected()) {
616 return manualImageDirPath;
617 }
else if (imageTable.getSelectedRow() != -1) {
618 return Paths.get((String) imageTableModel.getValueAt(imageTable.convertRowIndexToModel(imageTable.getSelectedRow()), 2));
625 public void insertUpdate(DocumentEvent e) {
629 public void removeUpdate(DocumentEvent e) {
633 public void changedUpdate(DocumentEvent e) {
636 void storeSettings() {
644 private static final long serialVersionUID = 1L;
652 "LogicalImagerPanel.imageTable.columnModel.title0=Hostname",
653 "LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date (GMT)",
654 "LogicalImagerPanel.imageTable.columnModel.title2=Path"
658 String colName = null;
661 colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title0();
664 colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title1();
667 colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title2();
String getColumnName(int column)
boolean isCellEditable(int rowIndex, int columnIndex)