19 package org.sleuthkit.autopsy.casemodule;
21 import java.awt.BorderLayout;
22 import java.awt.Color;
23 import java.awt.Component;
25 import java.beans.PropertyChangeListener;
26 import java.beans.PropertyChangeSupport;
27 import java.util.ArrayList;
28 import java.util.Calendar;
29 import java.util.List;
30 import java.util.SimpleTimeZone;
31 import java.util.TimeZone;
32 import java.util.concurrent.CancellationException;
33 import java.util.logging.Level;
34 import javax.swing.ComboBoxModel;
35 import javax.swing.JLabel;
36 import javax.swing.JList;
37 import javax.swing.JPanel;
38 import javax.swing.JSeparator;
39 import javax.swing.ListCellRenderer;
40 import javax.swing.SwingWorker;
41 import javax.swing.border.EmptyBorder;
42 import javax.swing.event.ListDataListener;
43 import org.openide.util.NbBundle;
54 final class LocalDiskPanel
extends JPanel {
56 private static final Logger logger = Logger.getLogger(LocalDiskPanel.class.getName());
58 private static LocalDiskPanel instance;
60 private PropertyChangeSupport pcs = null;
62 private List<LocalDisk> disks;
64 private LocalDiskModel model;
66 private boolean enableNext =
false;
71 public LocalDiskPanel() {
72 this.disks =
new ArrayList<>();
83 public static synchronized LocalDiskPanel getDefault() {
84 if (instance == null) {
85 instance =
new LocalDiskPanel();
90 @SuppressWarnings(
"unchecked")
91 private
void customInit() {
92 model =
new LocalDiskModel();
93 diskComboBox.setModel(model);
94 diskComboBox.setRenderer(model);
96 errorLabel.setText(
"");
97 diskComboBox.setEnabled(
false);
106 @SuppressWarnings(
"unchecked")
108 private
void initComponents() {
110 diskLabel =
new javax.swing.JLabel();
111 diskComboBox =
new javax.swing.JComboBox<>();
112 errorLabel =
new javax.swing.JLabel();
113 timeZoneLabel =
new javax.swing.JLabel();
114 timeZoneComboBox =
new javax.swing.JComboBox<String>();
115 noFatOrphansCheckbox =
new javax.swing.JCheckBox();
116 descLabel =
new javax.swing.JLabel();
118 setMinimumSize(
new java.awt.Dimension(0, 65));
119 setPreferredSize(
new java.awt.Dimension(485, 65));
121 org.openide.awt.Mnemonics.setLocalizedText(diskLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.diskLabel.text"));
123 errorLabel.setForeground(
new java.awt.Color(255, 0, 0));
124 org.openide.awt.Mnemonics.setLocalizedText(errorLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.errorLabel.text"));
126 org.openide.awt.Mnemonics.setLocalizedText(timeZoneLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.timeZoneLabel.text"));
128 timeZoneComboBox.setMaximumRowCount(30);
130 org.openide.awt.Mnemonics.setLocalizedText(noFatOrphansCheckbox,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.noFatOrphansCheckbox.text"));
131 noFatOrphansCheckbox.setToolTipText(
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.noFatOrphansCheckbox.toolTipText"));
133 org.openide.awt.Mnemonics.setLocalizedText(descLabel,
org.openide.util.NbBundle.getMessage(LocalDiskPanel.class,
"LocalDiskPanel.descLabel.text"));
135 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
136 this.setLayout(layout);
137 layout.setHorizontalGroup(
138 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
139 .addGroup(layout.createSequentialGroup()
140 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
141 .addComponent(diskLabel)
142 .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE)
143 .addComponent(errorLabel)
144 .addGroup(layout.createSequentialGroup()
145 .addComponent(timeZoneLabel)
146 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
147 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
148 .addComponent(noFatOrphansCheckbox)
149 .addGroup(layout.createSequentialGroup()
151 .addComponent(descLabel)))
152 .addGap(0, 102, Short.MAX_VALUE))
154 layout.setVerticalGroup(
155 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
156 .addGroup(layout.createSequentialGroup()
157 .addComponent(diskLabel)
158 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
159 .addComponent(diskComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
161 .addComponent(errorLabel)
162 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
163 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
164 .addComponent(timeZoneLabel)
165 .addComponent(timeZoneComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
167 .addComponent(noFatOrphansCheckbox)
168 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
169 .addComponent(descLabel)
170 .addContainerGap(21, Short.MAX_VALUE))
174 private javax.swing.JLabel descLabel;
175 private javax.swing.JComboBox<LocalDisk> diskComboBox;
176 private javax.swing.JLabel diskLabel;
177 private javax.swing.JLabel errorLabel;
178 private javax.swing.JCheckBox noFatOrphansCheckbox;
179 private javax.swing.JComboBox<String> timeZoneComboBox;
180 private javax.swing.JLabel timeZoneLabel;
189 public String getContentPaths() {
190 if (disks.size() > 0) {
191 LocalDisk selected = (LocalDisk) diskComboBox.getSelectedItem();
192 return selected.getPath();
202 public void setContentPath(String s) {
203 for (
int i = 0; i < disks.size(); i++) {
204 if (disks.get(i).getPath().equals(s)) {
205 diskComboBox.setSelectedIndex(i);
210 public String getTimeZone() {
211 String tz = timeZoneComboBox.getSelectedItem().toString();
212 return tz.substring(tz.indexOf(
")") + 2).trim();
216 boolean getNoFatOrphans() {
217 return noFatOrphansCheckbox.isSelected();
227 public boolean validatePanel() {
232 public void reset() {
241 public void select() {
242 diskComboBox.requestFocusInWindow();
248 public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
249 super.addPropertyChangeListener(pcl);
252 pcs =
new PropertyChangeSupport(
this);
255 pcs.addPropertyChangeListener(pcl);
259 public void removePropertyChangeListener(PropertyChangeListener pcl) {
260 super.removePropertyChangeListener(pcl);
262 pcs.removePropertyChangeListener(pcl);
269 public void createTimeZoneList() {
271 String[] ids = SimpleTimeZone.getAvailableIDs();
272 for (String
id : ids) {
273 TimeZone zone = TimeZone.getTimeZone(
id);
274 int offset = zone.getRawOffset() / 1000;
275 int hour = offset / 3600;
276 int minutes = (offset % 3600) / 60;
277 String item = String.format(
"(GMT%+d:%02d) %s", hour, minutes,
id);
288 timeZoneComboBox.addItem(item);
291 TimeZone thisTimeZone = Calendar.getInstance().getTimeZone();
292 int thisOffset = thisTimeZone.getRawOffset() / 1000;
293 int thisHour = thisOffset / 3600;
294 int thisMinutes = (thisOffset % 3600) / 60;
295 String formatted = String.format(
"(GMT%+d:%02d) %s", thisHour, thisMinutes, thisTimeZone.getID());
298 timeZoneComboBox.setSelectedItem(formatted);
301 @SuppressWarnings(
"rawtypes")
306 private boolean ready =
false;
308 private volatile boolean loadingDisks =
false;
310 List<LocalDisk> physicalDrives =
new ArrayList<>();
311 List<LocalDisk> partitions =
new ArrayList<>();
314 private String LOADING = NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.localDiskModel.loading.msg");
315 private String NO_DRIVES = NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.localDiskModel.nodrives.msg");
317 LocalDiskThread worker = null;
322 if (loadingDisks && worker != null) {
323 worker.cancel(
false);
327 errorLabel.setText(
"");
328 disks =
new ArrayList<>();
329 physicalDrives =
new ArrayList<>();
330 partitions =
new ArrayList<>();
331 diskComboBox.setEnabled(
false);
336 worker =
new LocalDiskThread();
349 }
catch (Exception e) {
350 logger.log(Level.SEVERE,
"LocalDiskPanel listener threw exception", e);
352 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.moduleErr.msg"),
361 if (disks.isEmpty()) {
374 if (disks.isEmpty()) {
387 if (disks.isEmpty()) {
390 return disks.get(index);
405 @SuppressWarnings(
"rawtypes")
408 JPanel panel =
new JPanel(
new BorderLayout());
409 JLabel label =
new JLabel();
410 if ((index == physicalDrives.size() - 1) && (physicalDrives.size() > 0)) {
411 panel.add(
new JSeparator(JSeparator.HORIZONTAL), BorderLayout.SOUTH);
415 label.setBackground(list.getSelectionBackground());
416 label.setForeground(list.getSelectionForeground());
418 label.setBackground(list.getBackground());
419 label.setForeground(list.getForeground());
423 String localDiskString = value.toString();
424 label.setText(value.toString());
425 if ((localDiskString.equals(LOADING)) || (localDiskString.equals(NO_DRIVES))) {
426 label.setFont(label.getFont().deriveFont(Font.ITALIC));
427 label.setBackground(Color.GRAY);
430 label.setOpaque(
true);
431 label.setBorder(
new EmptyBorder(2, 2, 2, 2));
433 panel.add(label, BorderLayout.CENTER);
437 class LocalDiskThread
extends SwingWorker<Object, Void> {
442 protected Object doInBackground() throws Exception {
450 private void displayErrors() {
451 if (physicalDrives.isEmpty() && partitions.isEmpty()) {
454 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.disksNotDetected.text"));
455 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
456 "LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
459 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.drivesNotDetected.text"));
460 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
461 "LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
463 diskComboBox.setEnabled(
false);
464 }
else if (physicalDrives.isEmpty()) {
466 NbBundle.getMessage(
this.getClass(),
"LocalDiskPanel.errLabel.someDisksNotDetected.text"));
467 errorLabel.setToolTipText(NbBundle.getMessage(
this.getClass(),
468 "LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
473 protected void done() {
476 }
catch (CancellationException ex) {
477 logger.log(Level.INFO,
"Loading local disks was canceled, which should not be possible.");
478 }
catch (InterruptedException ex) {
479 logger.log(Level.INFO,
"Loading local disks was interrupted.");
480 }
catch (Exception ex) {
481 logger.log(Level.SEVERE,
"Fatal error when loading local disks", ex);
483 if (!this.isCancelled()) {
488 loadingDisks =
false;
490 disks.addAll(physicalDrives);
491 disks.addAll(partitions);
493 if (disks.size() > 0) {
494 diskComboBox.setEnabled(
true);
495 diskComboBox.setSelectedIndex(0);
499 logger.log(Level.INFO,
"Loading local disks was canceled, which should not be possible.");
UPDATE_UI
the content of JPanel has changed that MAY warrant updates to the caller UI
void setSelectedItem(Object anItem)
void addListDataListener(ListDataListener l)
Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
Object getElementAt(int index)
static void show(String title, String message, MessageType type, ActionListener actionListener)
static Logger getLogger(String name)
void removeListDataListener(ListDataListener l)