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;
53 "LogicalImagerPanel.messageLabel.noImageSelected=No image selected",
54 "LogicalImagerPanel.messageLabel.driveHasNoImages=Drive has no images",
55 "LogicalImagerPanel.selectAcquisitionFromDriveLabel.text=Select acquisition from Drive",})
56 @SuppressWarnings(
"PMD.SingularField")
57 final class LogicalImagerPanel extends JPanel implements DocumentListener {
59 private static final Logger logger = Logger.
getLogger(LogicalImagerPanel.class.getName());
60 private static final long serialVersionUID = 1L;
61 private static final String NO_IMAGE_SELECTED = Bundle.LogicalImagerPanel_messageLabel_noImageSelected();
62 private static final String DRIVE_HAS_NO_IMAGES = Bundle.LogicalImagerPanel_messageLabel_driveHasNoImages();
63 private static final int COLUMN_TO_SORT_ON_INDEX = 1;
64 private static final int NUMBER_OF_VISIBLE_COLUMNS = 2;
65 private static final String[] EMPTY_LIST_DATA = {};
67 private final JFileChooser fileChooser =
new JFileChooser();
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;
78 private LogicalImagerPanel(String context) {
80 configureImageTable();
81 jScrollPane1.setBorder(null);
89 private void configureImageTable() {
91 if (imageTable.getColumnCount() > NUMBER_OF_VISIBLE_COLUMNS) {
92 TableColumn columnToHide = imageTable.getColumn(imageTableModel.getColumnName(NUMBER_OF_VISIBLE_COLUMNS));
93 if (columnToHide != null) {
94 imageTable.removeColumn(columnToHide);
97 imageTable.getRowSorter().toggleSortOrder(COLUMN_TO_SORT_ON_INDEX);
98 imageTable.getRowSorter().toggleSortOrder(COLUMN_TO_SORT_ON_INDEX);
110 static synchronized LogicalImagerPanel createInstance(String context) {
111 LogicalImagerPanel instance =
new LogicalImagerPanel(context);
113 instance.imageTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
123 private void initComponents() {
125 buttonGroup1 =
new javax.swing.ButtonGroup();
126 browseButton =
new javax.swing.JButton();
127 importRadioButton =
new javax.swing.JRadioButton();
128 manualRadioButton =
new javax.swing.JRadioButton();
129 pathTextField =
new javax.swing.JTextField();
130 selectFolderLabel =
new javax.swing.JLabel();
131 selectDriveLabel =
new javax.swing.JLabel();
132 selectFromDriveLabel =
new javax.swing.JLabel();
133 driveListScrollPane =
new javax.swing.JScrollPane();
134 driveList =
new javax.swing.JList<>();
135 refreshButton =
new javax.swing.JButton();
136 imageScrollPane =
new javax.swing.JScrollPane();
137 imageTable =
new javax.swing.JTable();
138 jSeparator2 =
new javax.swing.JSeparator();
139 jScrollPane1 =
new javax.swing.JScrollPane();
140 messageTextArea =
new javax.swing.JTextArea();
142 setMinimumSize(
new java.awt.Dimension(0, 65));
143 setPreferredSize(
new java.awt.Dimension(403, 65));
145 org.openide.awt.Mnemonics.setLocalizedText(browseButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.browseButton.text"));
146 browseButton.setEnabled(
false);
147 browseButton.addActionListener(
new java.awt.event.ActionListener() {
148 public void actionPerformed(java.awt.event.ActionEvent evt) {
149 browseButtonActionPerformed(evt);
153 buttonGroup1.add(importRadioButton);
154 importRadioButton.setSelected(
true);
155 org.openide.awt.Mnemonics.setLocalizedText(importRadioButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.importRadioButton.text"));
156 importRadioButton.setToolTipText(
"");
157 importRadioButton.addActionListener(
new java.awt.event.ActionListener() {
158 public void actionPerformed(java.awt.event.ActionEvent evt) {
159 importRadioButtonActionPerformed(evt);
163 buttonGroup1.add(manualRadioButton);
164 org.openide.awt.Mnemonics.setLocalizedText(manualRadioButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.manualRadioButton.text"));
165 manualRadioButton.addActionListener(
new java.awt.event.ActionListener() {
166 public void actionPerformed(java.awt.event.ActionEvent evt) {
167 manualRadioButtonActionPerformed(evt);
171 pathTextField.setDisabledTextColor(java.awt.Color.black);
172 pathTextField.setEnabled(
false);
174 org.openide.awt.Mnemonics.setLocalizedText(selectFolderLabel,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.selectFolderLabel.text"));
176 org.openide.awt.Mnemonics.setLocalizedText(selectDriveLabel,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.selectDriveLabel.text"));
178 org.openide.awt.Mnemonics.setLocalizedText(selectFromDriveLabel,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.selectFromDriveLabel.text"));
180 driveList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
181 driveList.addMouseListener(
new java.awt.event.MouseAdapter() {
182 public void mouseReleased(java.awt.event.MouseEvent evt) {
183 driveListMouseReleased(evt);
186 driveList.addKeyListener(
new java.awt.event.KeyAdapter() {
187 public void keyReleased(java.awt.event.KeyEvent evt) {
188 driveListKeyReleased(evt);
191 driveListScrollPane.setViewportView(driveList);
193 org.openide.awt.Mnemonics.setLocalizedText(refreshButton,
org.openide.util.NbBundle.getMessage(LogicalImagerPanel.class,
"LogicalImagerPanel.refreshButton.text"));
194 refreshButton.addActionListener(
new java.awt.event.ActionListener() {
195 public void actionPerformed(java.awt.event.ActionEvent evt) {
196 refreshButtonActionPerformed(evt);
200 imageScrollPane.setPreferredSize(
new java.awt.Dimension(346, 402));
202 imageTable.setAutoCreateRowSorter(
true);
203 imageTable.setModel(
new javax.swing.table.DefaultTableModel(
211 imageTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
212 imageTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
213 imageTable.setShowHorizontalLines(
false);
214 imageTable.setShowVerticalLines(
false);
215 imageTable.getTableHeader().setReorderingAllowed(
false);
216 imageTable.addMouseListener(
new java.awt.event.MouseAdapter() {
217 public void mouseReleased(java.awt.event.MouseEvent evt) {
218 imageTableMouseReleased(evt);
221 imageTable.addKeyListener(
new java.awt.event.KeyAdapter() {
222 public void keyReleased(java.awt.event.KeyEvent evt) {
223 imageTableKeyReleased(evt);
226 imageScrollPane.setViewportView(imageTable);
227 imageTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
229 jScrollPane1.setBorder(null);
231 messageTextArea.setBackground(
new java.awt.Color(240, 240, 240));
232 messageTextArea.setColumns(20);
233 messageTextArea.setForeground(java.awt.Color.red);
234 messageTextArea.setLineWrap(
true);
235 messageTextArea.setRows(3);
236 messageTextArea.setBorder(null);
237 messageTextArea.setDisabledTextColor(java.awt.Color.red);
238 messageTextArea.setEnabled(
false);
239 messageTextArea.setMargin(
new java.awt.Insets(0, 0, 0, 0));
240 jScrollPane1.setViewportView(messageTextArea);
242 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
243 this.setLayout(layout);
244 layout.setHorizontalGroup(
245 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
246 .addGroup(layout.createSequentialGroup()
247 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
248 .addGroup(layout.createSequentialGroup()
250 .addComponent(selectFolderLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
252 .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 474, javax.swing.GroupLayout.PREFERRED_SIZE))
253 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,
false)
254 .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING)
255 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
256 .addGroup(layout.createSequentialGroup()
258 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
259 .addComponent(driveListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)
260 .addComponent(refreshButton))
261 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
262 .addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 377, javax.swing.GroupLayout.PREFERRED_SIZE))
263 .addGroup(layout.createSequentialGroup()
265 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
266 .addGroup(layout.createSequentialGroup()
267 .addComponent(manualRadioButton)
268 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
269 .addComponent(browseButton))
270 .addComponent(importRadioButton)
271 .addGroup(layout.createSequentialGroup()
273 .addComponent(selectDriveLabel)
274 .addGap(113, 113, 113)
275 .addComponent(selectFromDriveLabel))))))
276 .addGroup(layout.createSequentialGroup()
278 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 568, javax.swing.GroupLayout.PREFERRED_SIZE)))
279 .addContainerGap(93, Short.MAX_VALUE))
281 layout.setVerticalGroup(
282 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
283 .addGroup(layout.createSequentialGroup()
285 .addComponent(importRadioButton)
286 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
287 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
288 .addComponent(selectDriveLabel)
289 .addComponent(selectFromDriveLabel))
290 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
291 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
292 .addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
293 .addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 198, Short.MAX_VALUE))
294 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
295 .addComponent(refreshButton)
297 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
298 .addComponent(browseButton)
299 .addComponent(manualRadioButton))
301 .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
302 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
303 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
304 .addComponent(selectFolderLabel)
305 .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
306 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
307 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
313 "# {0} - sparseImageDirectory",
314 "LogicalImagerPanel.messageLabel.directoryDoesNotContainSparseImage=Directory {0} does not contain any images",
315 "# {0} - invalidFormatDirectory",
316 "LogicalImagerPanel.messageLabel.directoryFormatInvalid=Directory {0} does not match format Logical_Imager_HOSTNAME_yyyymmdd_HH_MM_SS"
318 private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {
319 imageTable.clearSelection();
320 manualImageDirPath = null;
321 setErrorMessage(NO_IMAGE_SELECTED);
322 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
323 int retval = fileChooser.showOpenDialog(
this);
324 if (retval == JFileChooser.APPROVE_OPTION) {
325 String path = fileChooser.getSelectedFile().getPath();
326 Matcher m = regex.matcher(path);
328 File dir = Paths.get(path).toFile();
329 String[] vhdFiles = dir.list(
new FilenameFilter() {
331 public boolean accept(File dir, String name) {
332 return name.endsWith(
".vhd");
335 if (vhdFiles.length == 0) {
337 String[] directories = dir.list(
new FilenameFilter() {
339 public boolean accept(File dir, String name) {
340 return Paths.get(dir.toString(), name).toFile().isDirectory();
343 if (directories.length == 0) {
345 setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryDoesNotContainSparseImage(path));
346 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
350 manualImageDirPath = Paths.get(path);
351 setNormalMessage(path);
352 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
354 setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_directoryFormatInvalid(path));
355 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
358 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
362 private void imageTableSelect() {
363 int index = imageTable.getSelectedRow();
365 setNormalMessage((String) imageTableModel.getValueAt(imageTable.convertRowIndexToModel(index), 2));
366 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
false,
true);
368 setErrorMessage(NO_IMAGE_SELECTED);
369 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
373 private boolean dirHasImagerResult(File dir) {
374 String[] fList = dir.list(
new FilenameFilter() {
376 public boolean accept(File dir, String name) {
377 return name.endsWith(
".vhd") || Paths.get(dir.toString(), name).toFile().isDirectory();
380 return (fList != null && fList.length != 0);
383 private void driveListSelect() {
384 String selectedStr = driveList.getSelectedValue();
385 if (selectedStr == null) {
388 String driveLetter = selectedStr.substring(0, 3);
389 File directory =
new File(driveLetter);
390 File[] fList = directory.listFiles();
393 imageTableModel =
new ImageTableModel();
396 for (File file : fList) {
397 if (file.isDirectory() && dirHasImagerResult(file)) {
398 String dir = file.getName();
399 Matcher m = regex.matcher(dir);
401 String imageDirPath = driveLetter + dir;
402 String hostname = m.group(1);
403 String year = m.group(2);
404 String month = m.group(3);
405 String day = m.group(4);
406 String hour = m.group(5);
407 String minute = m.group(6);
408 String second = m.group(7);
409 String extractDate = year +
"/" + month +
"/" + day
410 +
" " + hour +
":" + minute +
":" + second;
411 imageTableModel.addRow(
new Object[]{hostname, extractDate, imageDirPath});
415 selectFromDriveLabel.setText(Bundle.LogicalImagerPanel_selectAcquisitionFromDriveLabel_text()
416 +
" " + driveLetter);
417 imageTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
418 imageTable.setModel(imageTableModel);
419 configureImageTable();
420 fixImageTableColumnWidth();
422 if (imageTable.getRowCount() > 0) {
423 imageTable.setRowSelectionInterval(0, 0);
426 setErrorMessage(DRIVE_HAS_NO_IMAGES);
430 setErrorMessage(DRIVE_HAS_NO_IMAGES);
434 private void fixImageTableColumnWidth() {
435 int width = imageScrollPane.getPreferredSize().width - 2;
436 imageTable.getColumnModel().getColumn(0).setPreferredWidth((
int) (.60 * width));
437 imageTable.getColumnModel().getColumn(1).setPreferredWidth((
int) (.40 * width));
440 private void setErrorMessage(String msg) {
441 messageTextArea.setForeground(Color.red);
442 messageTextArea.setText(msg);
443 pathTextField.setText(
"");
446 private void setNormalMessage(String msg) {
447 pathTextField.setText(msg);
448 messageTextArea.setText(
"");
451 private void clearImageTable() {
452 imageTableModel =
new ImageTableModel();
453 imageTable.setModel(imageTableModel);
454 configureImageTable();
455 fixImageTableColumnWidth();
458 private void toggleMouseAndKeyListeners(Component component,
boolean isEnable) {
459 component.setEnabled(isEnable);
462 private void manualRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {
463 browseButton.setEnabled(
true);
466 toggleMouseAndKeyListeners(driveList,
false);
467 toggleMouseAndKeyListeners(driveListScrollPane,
false);
468 toggleMouseAndKeyListeners(imageScrollPane,
false);
469 toggleMouseAndKeyListeners(imageTable,
false);
471 refreshButton.setEnabled(
false);
473 manualImageDirPath = null;
474 setNormalMessage(
"");
475 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
478 private void importRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {
479 browseButton.setEnabled(
false);
481 toggleMouseAndKeyListeners(driveList,
true);
482 toggleMouseAndKeyListeners(driveListScrollPane,
true);
483 toggleMouseAndKeyListeners(imageScrollPane,
true);
484 toggleMouseAndKeyListeners(imageTable,
true);
486 refreshButton.setEnabled(
true);
488 manualImageDirPath = null;
489 setNormalMessage(
"");
490 refreshButton.doClick();
494 "LogicalImagerPanel.messageLabel.scanningExternalDrives=Scanning external drives for images ...",
495 "LogicalImagerPanel.messageLabel.noExternalDriveFound=No drive found"
497 private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {
500 setNormalMessage(Bundle.LogicalImagerPanel_messageLabel_scanningExternalDrives());
501 List<String> listData =
new ArrayList<>();
502 File[] roots = File.listRoots();
503 int firstRemovableDrive = -1;
505 for (File root : roots) {
506 if (DriveListUtils.isNetworkDrive(root.toString().replace(
":\\",
""))) {
509 String description = FileSystemView.getFileSystemView().getSystemTypeDescription(root);
510 long spaceInBytes = root.getTotalSpace();
511 String sizeWithUnit = DriveListUtils.humanReadableByteCount(spaceInBytes,
false);
512 listData.add(root +
" (" + description +
") (" + sizeWithUnit +
")");
513 if (firstRemovableDrive == -1) {
515 FileStore fileStore = Files.getFileStore(root.toPath());
516 if ((
boolean) fileStore.getAttribute(
"volume:isRemovable")) {
517 firstRemovableDrive = i;
519 }
catch (IOException ignored) {
521 logger.log(Level.INFO, String.format(
"Unable to select first removable drive found: %s", ignored.getMessage()));
526 driveList.setListData(listData.toArray(
new String[listData.size()]));
527 if (!listData.isEmpty()) {
529 driveList.setSelectedIndex(firstRemovableDrive == -1 ? 0 : firstRemovableDrive);
530 driveListMouseReleased(null);
531 driveList.requestFocusInWindow();
533 setErrorMessage(Bundle.LogicalImagerPanel_messageLabel_noExternalDriveFound());
535 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
538 private void driveListKeyReleased(java.awt.event.KeyEvent evt) {
539 if (importRadioButton.isSelected()) {
541 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
545 private void imageTableKeyReleased(java.awt.event.KeyEvent evt) {
546 if (importRadioButton.isSelected()) {
551 private void imageTableMouseReleased(java.awt.event.MouseEvent evt) {
552 if (importRadioButton.isSelected()) {
557 private void driveListMouseReleased(java.awt.event.MouseEvent evt) {
558 if (importRadioButton.isSelected()) {
560 firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(),
true,
false);
566 private javax.swing.JButton browseButton;
567 private javax.swing.ButtonGroup buttonGroup1;
568 private javax.swing.JList<String> driveList;
569 private javax.swing.JScrollPane driveListScrollPane;
570 private javax.swing.JScrollPane imageScrollPane;
571 private javax.swing.JTable imageTable;
572 private javax.swing.JRadioButton importRadioButton;
573 private javax.swing.JScrollPane jScrollPane1;
574 private javax.swing.JSeparator jSeparator2;
575 private javax.swing.JRadioButton manualRadioButton;
576 private javax.swing.JTextArea messageTextArea;
577 private javax.swing.JTextField pathTextField;
578 private javax.swing.JButton refreshButton;
579 private javax.swing.JLabel selectDriveLabel;
580 private javax.swing.JLabel selectFolderLabel;
581 private javax.swing.JLabel selectFromDriveLabel;
586 manualImageDirPath = null;
587 setNormalMessage(
"");
588 driveList.setListData(EMPTY_LIST_DATA);
590 if (importRadioButton.isSelected()) {
591 refreshButton.doClick();
600 boolean validatePanel() {
601 if (manualRadioButton.isSelected()) {
602 return manualImageDirPath != null && manualImageDirPath.toFile().exists();
603 }
else if (imageTable.getSelectedRow() != -1) {
604 Path path = Paths.get((String) imageTableModel.getValueAt(imageTable.convertRowIndexToModel(imageTable.getSelectedRow()), 2));
605 return path != null && path.toFile().exists();
611 Path getImageDirPath() {
612 if (manualRadioButton.isSelected()) {
613 return manualImageDirPath;
614 }
else if (imageTable.getSelectedRow() != -1) {
615 return Paths.get((String) imageTableModel.getValueAt(imageTable.convertRowIndexToModel(imageTable.getSelectedRow()), 2));
622 public void insertUpdate(DocumentEvent e) {
626 public void removeUpdate(DocumentEvent e) {
630 public void changedUpdate(DocumentEvent e) {
633 void storeSettings() {
641 private static final long serialVersionUID = 1L;
649 "LogicalImagerPanel.imageTable.columnModel.title0=Hostname",
650 "LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date (GMT)",
651 "LogicalImagerPanel.imageTable.columnModel.title2=Path"
655 String colName = null;
658 colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title0();
661 colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title1();
664 colName = Bundle.LogicalImagerPanel_imageTable_columnModel_title2();
String getColumnName(int column)
synchronized static Logger getLogger(String name)
boolean isCellEditable(int rowIndex, int columnIndex)