Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
DataContentViewerHex.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.corecomponents;
20 
21 import java.awt.Component;
22 import java.awt.Cursor;
23 import java.awt.Font;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.io.File;
27 import java.io.IOException;
28 import java.nio.file.Paths;
29 import java.util.logging.Level;
31 import org.openide.util.NbBundle;
33 import javax.swing.JMenuItem;
34 import javax.swing.JOptionPane;
35 import javax.swing.SwingWorker;
36 import javax.swing.text.BadLocationException;
37 import javax.swing.text.Utilities;
38 import org.netbeans.api.progress.ProgressHandle;
39 import org.openide.nodes.Node;
40 import org.openide.util.lookup.ServiceProvider;
45 import static org.sleuthkit.autopsy.corecomponents.Bundle.*;
49 import org.sleuthkit.datamodel.BlackboardArtifact;
50 import org.sleuthkit.datamodel.Content;
51 import org.sleuthkit.datamodel.TskCoreException;
52 
56 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
57 @ServiceProvider(service = DataContentViewer.class, position = 1)
58 public class DataContentViewerHex extends javax.swing.JPanel implements DataContentViewer {
59 
60  private static final long PAGE_LENGTH = 16384;
61  private final byte[] data = new byte[(int) PAGE_LENGTH];
62  private static int currentPage = 1;
63  private int totalPages;
64  private Content dataSource;
65 
66  private static final Logger logger = Logger.getLogger(DataContentViewerHex.class.getName());
67 
72  initComponents();
73  customizeComponents();
74  this.resetComponent();
75  logger.log(Level.INFO, "Created HexView instance: " + this); //NON-NLS
76  }
77 
78  private void customizeComponents() {
79  outputTextArea.setComponentPopupMenu(rightClickMenu);
80  ActionListener actList = new ActionListener() {
81  @Override
82  public void actionPerformed(ActionEvent e) {
83  JMenuItem jmi = (JMenuItem) e.getSource();
84  if (jmi.equals(copyMenuItem)) {
85  outputTextArea.copy();
86  } else if (jmi.equals(selectAllMenuItem)) {
87  outputTextArea.selectAll();
88  }
89  }
90  };
91  copyMenuItem.addActionListener(actList);
92  selectAllMenuItem.addActionListener(actList);
93  }
94 
100  @SuppressWarnings("unchecked")
101  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
102  private void initComponents() {
103 
104  rightClickMenu = new javax.swing.JPopupMenu();
105  copyMenuItem = new javax.swing.JMenuItem();
106  selectAllMenuItem = new javax.swing.JMenuItem();
107  jScrollPane3 = new javax.swing.JScrollPane();
108  outputTextArea = new javax.swing.JTextArea();
109  jScrollPane2 = new javax.swing.JScrollPane();
110  hexViewerPanel = new javax.swing.JPanel();
111  totalPageLabel = new javax.swing.JLabel();
112  ofLabel = new javax.swing.JLabel();
113  currentPageLabel = new javax.swing.JLabel();
114  pageLabel = new javax.swing.JLabel();
115  prevPageButton = new javax.swing.JButton();
116  nextPageButton = new javax.swing.JButton();
117  pageLabel2 = new javax.swing.JLabel();
118  goToPageTextField = new javax.swing.JTextField();
119  goToPageLabel = new javax.swing.JLabel();
120  goToOffsetLabel = new javax.swing.JLabel();
121  goToOffsetTextField = new javax.swing.JTextField();
122  launchHxDButton = new javax.swing.JButton();
123 
124  copyMenuItem.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.copyMenuItem.text")); // NOI18N
125  rightClickMenu.add(copyMenuItem);
126 
127  selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.selectAllMenuItem.text")); // NOI18N
128  rightClickMenu.add(selectAllMenuItem);
129 
130  setPreferredSize(new java.awt.Dimension(100, 58));
131 
132  jScrollPane3.setPreferredSize(new java.awt.Dimension(300, 33));
133 
134  outputTextArea.setEditable(false);
135  outputTextArea.setFont(new Font("Monospaced", Font.PLAIN, 11));
136  outputTextArea.setTabSize(0);
137  outputTextArea.setInheritsPopupMenu(true);
138  jScrollPane3.setViewportView(outputTextArea);
139 
140  jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
141  jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
142 
143  totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.totalPageLabel.text_1")); // NOI18N
144 
145  ofLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.ofLabel.text_1")); // NOI18N
146 
147  currentPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.currentPageLabel.text_1")); // NOI18N
148  currentPageLabel.setMaximumSize(new java.awt.Dimension(18, 14));
149  currentPageLabel.setMinimumSize(new java.awt.Dimension(18, 14));
150 
151  pageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.pageLabel.text_1")); // NOI18N
152  pageLabel.setMaximumSize(new java.awt.Dimension(33, 14));
153  pageLabel.setMinimumSize(new java.awt.Dimension(33, 14));
154 
155  prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
156  prevPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.prevPageButton.text")); // NOI18N
157  prevPageButton.setBorderPainted(false);
158  prevPageButton.setContentAreaFilled(false);
159  prevPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
160  prevPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
161  prevPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
162  prevPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png"))); // NOI18N
163  prevPageButton.addActionListener(new java.awt.event.ActionListener() {
164  public void actionPerformed(java.awt.event.ActionEvent evt) {
165  prevPageButtonActionPerformed(evt);
166  }
167  });
168 
169  nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
170  nextPageButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.nextPageButton.text")); // NOI18N
171  nextPageButton.setBorderPainted(false);
172  nextPageButton.setContentAreaFilled(false);
173  nextPageButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
174  nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
175  nextPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
176  nextPageButton.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png"))); // NOI18N
177  nextPageButton.addActionListener(new java.awt.event.ActionListener() {
178  public void actionPerformed(java.awt.event.ActionEvent evt) {
179  nextPageButtonActionPerformed(evt);
180  }
181  });
182 
183  pageLabel2.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.pageLabel2.text")); // NOI18N
184  pageLabel2.setMaximumSize(new java.awt.Dimension(29, 14));
185  pageLabel2.setMinimumSize(new java.awt.Dimension(29, 14));
186 
187  goToPageTextField.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToPageTextField.text")); // NOI18N
188  goToPageTextField.addActionListener(new java.awt.event.ActionListener() {
189  public void actionPerformed(java.awt.event.ActionEvent evt) {
190  goToPageTextFieldActionPerformed(evt);
191  }
192  });
193 
194  goToPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToPageLabel.text")); // NOI18N
195 
196  goToOffsetLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToOffsetLabel.text")); // NOI18N
197 
198  goToOffsetTextField.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.goToOffsetTextField.text")); // NOI18N
199  goToOffsetTextField.addActionListener(new java.awt.event.ActionListener() {
200  public void actionPerformed(java.awt.event.ActionEvent evt) {
201  goToOffsetTextFieldActionPerformed(evt);
202  }
203  });
204 
205  launchHxDButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.launchHxDButton.text")); // NOI18N
206  launchHxDButton.addActionListener(new java.awt.event.ActionListener() {
207  public void actionPerformed(java.awt.event.ActionEvent evt) {
208  launchHxDButtonActionPerformed(evt);
209  }
210  });
211 
212  javax.swing.GroupLayout hexViewerPanelLayout = new javax.swing.GroupLayout(hexViewerPanel);
213  hexViewerPanel.setLayout(hexViewerPanelLayout);
214  hexViewerPanelLayout.setHorizontalGroup(
215  hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
216  .addGroup(hexViewerPanelLayout.createSequentialGroup()
217  .addContainerGap()
218  .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
219  .addGap(18, 18, 18)
220  .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
221  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
222  .addComponent(ofLabel)
223  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
224  .addComponent(totalPageLabel)
225  .addGap(50, 50, 50)
226  .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
227  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
228  .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
229  .addGap(0, 0, 0)
230  .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
231  .addGap(18, 18, 18)
232  .addComponent(goToPageLabel)
233  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
234  .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
235  .addGap(18, 18, 18)
236  .addComponent(goToOffsetLabel)
237  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
238  .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
239  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
240  .addComponent(launchHxDButton)
241  .addContainerGap(146, Short.MAX_VALUE))
242  );
243  hexViewerPanelLayout.setVerticalGroup(
244  hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
245  .addGroup(hexViewerPanelLayout.createSequentialGroup()
246  .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
247  .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
248  .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
249  .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
250  .addComponent(ofLabel)
251  .addComponent(totalPageLabel))
252  .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
253  .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
254  .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
255  .addComponent(goToPageLabel)
256  .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
257  .addComponent(goToOffsetLabel)
258  .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
259  .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
260  .addComponent(launchHxDButton)))
261  .addGap(0, 0, 0))
262  );
263 
264  launchHxDButton.setEnabled(PlatformUtil.isWindowsOS());
265 
266  jScrollPane2.setViewportView(hexViewerPanel);
267 
268  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
269  this.setLayout(layout);
270  layout.setHorizontalGroup(
271  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
272  .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 827, Short.MAX_VALUE)
273  .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
274  );
275  layout.setVerticalGroup(
276  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
277  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
278  .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
279  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
280  .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 239, Short.MAX_VALUE))
281  );
282  }// </editor-fold>//GEN-END:initComponents
283 
284  private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
285  setDataViewByPageNumber(currentPage - 1);
286  goToPageTextField.setText(Integer.toString(currentPage));
287  }//GEN-LAST:event_prevPageButtonActionPerformed
288 
289  private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
290  setDataViewByPageNumber(currentPage + 1);
291  goToPageTextField.setText(Integer.toString(currentPage));
292  }//GEN-LAST:event_nextPageButtonActionPerformed
293 
294  private void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToPageTextFieldActionPerformed
295  String pageNumberStr = goToPageTextField.getText();
296  int pageNumber;
297  try {
298  pageNumber = Integer.parseInt(pageNumberStr);
299  } catch (NumberFormatException ex) {
300  pageNumber = totalPages + 1;
301  }
302  if (pageNumber > totalPages || pageNumber < 1) {
303  JOptionPane.showMessageDialog(this,
304  NbBundle.getMessage(this.getClass(),
305  "DataContentViewerHex.goToPageTextField.msgDlg",
306  totalPages),
307  NbBundle.getMessage(this.getClass(),
308  "DataContentViewerHex.goToPageTextField.err"),
309  JOptionPane.WARNING_MESSAGE);
310  return;
311  }
312  setDataViewByPageNumber(pageNumber);
313  }//GEN-LAST:event_goToPageTextFieldActionPerformed
314 
325  private long getOffsetRelativeToCaretPosition(Long userInput) {
326  String userSelectedLine;
327  try {
328  // get the selected line. Extract the current hex offset location.
329  userSelectedLine = outputTextArea.getText().subSequence(
330  Utilities.getRowStart(outputTextArea, outputTextArea.getCaretPosition()),
331  Utilities.getRowEnd(outputTextArea, outputTextArea.getCaretPosition()))
332  .toString();
333  // NOTE: This needs to change if the outputFormat of outputTextArea changes.
334  String hexForUserSelectedLine = userSelectedLine.substring(0, userSelectedLine.indexOf(':'));
335 
336  return Long.decode(hexForUserSelectedLine) + userInput;
337  } catch (BadLocationException | StringIndexOutOfBoundsException | NumberFormatException ex) {
338  // thrown in case the caret location is out of the range of the outputTextArea.
339  return -1L;
340  }
341  }
342 
343  private void goToOffsetTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToOffsetTextFieldActionPerformed
344  long offset;
345  try {
346  if (goToOffsetTextField.getText().startsWith("+") || goToOffsetTextField.getText().startsWith("-")) {
347  offset = getOffsetRelativeToCaretPosition(Long.decode(goToOffsetTextField.getText()));
348  } else {
349  offset = Long.decode(goToOffsetTextField.getText());
350  }
351  } catch (NumberFormatException ex) {
352  // notify the user and return
353  JOptionPane.showMessageDialog(this, NbBundle.getMessage(this.getClass(), "DataContentViewerHex.goToOffsetTextField.msgDlg", goToOffsetTextField.getText()));
354  return;
355  }
356 
357  if (offset >= 0) {
358  setDataViewByOffset(offset);
359  } else {
360  outputTextArea.setText(NbBundle.getMessage(DataContentViewerHex.class, "DataContentViewerHex.setDataView.invalidOffset.negativeOffsetValue"));
361  }
362  }//GEN-LAST:event_goToOffsetTextFieldActionPerformed
363 
364  @NbBundle.Messages({"DataContentViewerHex.launchError=Unable to launch HxD Editor. "
365  + "Please specify the HxD install location in Tools -> Options -> External Viewer",
366  "DataContentViewerHex.copyingFile=Copying file to open in HxD..."})
367  private void launchHxDButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_launchHxDButtonActionPerformed
368  new BackgroundFileCopyTask().execute();
369  }//GEN-LAST:event_launchHxDButtonActionPerformed
370 
375  private class BackgroundFileCopyTask extends SwingWorker<Void, Void> {
376 
377  private boolean wasCancelled = false;
378 
379  @Override
380  public Void doInBackground() throws InterruptedException {
381  ProgressHandle progress = ProgressHandle.createHandle(DataContentViewerHex_copyingFile(), () -> {
382  //Cancel the swing worker (which will interrupt the ContentUtils call below)
383  this.cancel(true);
384  wasCancelled = true;
385  return true;
386  });
387 
388  try {
389  File HxDExecutable = new File(UserPreferences.getExternalHexEditorPath());
390  if (!HxDExecutable.exists() || !HxDExecutable.canExecute()) {
391  JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
392  return null;
393  }
394 
395  String tempDirectory = Case.getCurrentCaseThrows().getTempDirectory();
396  File tempFile = Paths.get(tempDirectory,
397  FileUtil.escapeFileName(dataSource.getId() + dataSource.getName())).toFile();
398 
399  progress.start(100);
400  ContentUtils.writeToFile(dataSource, tempFile, progress, this, true);
401 
402  if (wasCancelled) {
403  tempFile.delete();
404  progress.finish();
405  return null;
406  }
407 
408  try {
409  ProcessBuilder launchHxDExecutable = new ProcessBuilder();
410  launchHxDExecutable.command(String.format("\"%s\" \"%s\"",
411  HxDExecutable.getAbsolutePath(),
412  tempFile.getAbsolutePath()));
413  launchHxDExecutable.start();
414  } catch (IOException ex) {
415  logger.log(Level.WARNING, "Unsuccessful attempt to launch HxD", ex);
416  JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
417  tempFile.delete();
418  }
419  } catch (NoCurrentCaseException | IOException ex) {
420  logger.log(Level.SEVERE, "Unable to copy file into temp directory", ex);
421  JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
422  }
423 
424  progress.finish();
425  return null;
426  }
427  }
428 
429 
430  // Variables declaration - do not modify//GEN-BEGIN:variables
431  private javax.swing.JMenuItem copyMenuItem;
432  private javax.swing.JLabel currentPageLabel;
433  private javax.swing.JLabel goToOffsetLabel;
434  private javax.swing.JTextField goToOffsetTextField;
435  private javax.swing.JLabel goToPageLabel;
436  private javax.swing.JTextField goToPageTextField;
437  private javax.swing.JPanel hexViewerPanel;
438  private javax.swing.JScrollPane jScrollPane2;
439  private javax.swing.JScrollPane jScrollPane3;
440  private javax.swing.JButton launchHxDButton;
441  private javax.swing.JButton nextPageButton;
442  private javax.swing.JLabel ofLabel;
443  private javax.swing.JTextArea outputTextArea;
444  private javax.swing.JLabel pageLabel;
445  private javax.swing.JLabel pageLabel2;
446  private javax.swing.JButton prevPageButton;
447  private javax.swing.JPopupMenu rightClickMenu;
448  private javax.swing.JMenuItem selectAllMenuItem;
449  private javax.swing.JLabel totalPageLabel;
450  // End of variables declaration//GEN-END:variables
451 
457  private void setDataViewByPageNumber(int page) {
458  if (this.dataSource == null) {
459  return;
460  }
461  if (page == 0) {
462  return;
463  }
464  currentPage = page;
465  long offset = (currentPage - 1) * PAGE_LENGTH;
466  setDataView(offset);
467  goToOffsetTextField.setText(Long.toString(offset));
468  }
469 
475  private void setDataViewByOffset(long offset) {
476  if (this.dataSource == null) {
477  return;
478  }
479  currentPage = (int) (offset / PAGE_LENGTH) + 1;
480  setDataView(offset);
481  goToPageTextField.setText(Integer.toString(currentPage));
482  }
483 
484  private void setDataView(long offset) {
485  // change the cursor to "waiting cursor" for this operation
486  this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
487 
488  String errorText = null;
489 
490  int bytesRead = 0;
491  if (dataSource.getSize() > 0) {
492  try {
493  bytesRead = dataSource.read(data, offset, PAGE_LENGTH); // read the data
494  } catch (TskCoreException ex) {
495  errorText = NbBundle.getMessage(this.getClass(), "DataContentViewerHex.setDataView.errorText", offset,
496  offset + PAGE_LENGTH);
497  logger.log(Level.WARNING, "Error while trying to show the hex content.", ex); //NON-NLS
498  }
499  }
500 
501  // set the data on the bottom and show it
502  if (bytesRead <= 0) {
503  errorText = NbBundle.getMessage(this.getClass(), "DataContentViewerHex.setDataView.errorText", offset,
504  offset + PAGE_LENGTH);
505  }
506 
507  // disable or enable the next button
508  if ((errorText == null) && (currentPage < totalPages)) {
509  nextPageButton.setEnabled(true);
510  } else {
511  nextPageButton.setEnabled(false);
512  }
513 
514  if ((errorText == null) && (currentPage > 1)) {
515  prevPageButton.setEnabled(true);
516  } else {
517  prevPageButton.setEnabled(false);
518  }
519 
520  currentPageLabel.setText(Integer.toString(currentPage));
521  setComponentsVisibility(true); // shows the components that not needed
522 
523  // set the output view
524  if (errorText == null) {
525  int showLength = bytesRead < PAGE_LENGTH ? bytesRead : (int) PAGE_LENGTH;
526  outputTextArea.setText(DataConversion.byteArrayToHex(data, showLength, offset));
527  } else {
528  outputTextArea.setText(errorText);
529  }
530 
531  outputTextArea.setCaretPosition(0);
532  this.setCursor(null);
533  }
534 
535  @Override
536  public void setNode(Node selectedNode) {
537  if ((selectedNode == null) || (!isSupported(selectedNode))) {
538  resetComponent();
539  return;
540  }
541 
542  Content content = DataContentViewerUtility.getDefaultContent(selectedNode);
543  if (content == null) {
544  resetComponent();
545  return;
546  }
547 
548  dataSource = content;
549  totalPages = 0;
550  if (dataSource.getSize() > 0) {
551  totalPages = Math.round((dataSource.getSize() - 1) / PAGE_LENGTH) + 1;
552  }
553  totalPageLabel.setText(Integer.toString(totalPages));
554 
555  this.setDataViewByPageNumber(1);
556  }
557 
558  @Override
559  public String getTitle() {
560  return NbBundle.getMessage(this.getClass(), "DataContentViewerHex.title");
561  }
562 
563  @Override
564  public String getToolTip() {
565  return NbBundle.getMessage(this.getClass(), "DataContentViewerHex.toolTip");
566  }
567 
568  @Override
569  public DataContentViewer createInstance() {
570  return new DataContentViewerHex();
571  }
572 
573  @Override
574  public void resetComponent() {
575  // clear / reset the fields
576  currentPage = 1;
577  this.dataSource = null;
578  currentPageLabel.setText("");
579  totalPageLabel.setText("");
580  outputTextArea.setText("");
581  setComponentsVisibility(false); // hides the components that not needed
582  }
583 
589  private void setComponentsVisibility(boolean isVisible) {
590  currentPageLabel.setVisible(isVisible);
591  totalPageLabel.setVisible(isVisible);
592  ofLabel.setVisible(isVisible);
593  prevPageButton.setVisible(isVisible);
594  nextPageButton.setVisible(isVisible);
595  pageLabel.setVisible(isVisible);
596  pageLabel2.setVisible(isVisible);
597  goToPageTextField.setVisible(isVisible);
598  goToPageLabel.setVisible(isVisible);
599  goToOffsetTextField.setVisible(isVisible);
600  goToOffsetLabel.setVisible(isVisible);
601  launchHxDButton.setVisible(isVisible);
602  }
603 
604  @Override
605  public boolean isSupported(Node node) {
606  if (node == null) {
607  return false;
608  }
609  Content content = DataContentViewerUtility.getDefaultContent(node);
610  return content != null && !(content instanceof BlackboardArtifact) && content.getSize() > 0;
611  }
612 
613  @Override
614  public int isPreferred(Node node) {
615  return 1;
616  }
617 
618  @Override
619  public Component getComponent() {
620  return this;
621  }
622 }
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
void goToOffsetTextFieldActionPerformed(java.awt.event.ActionEvent evt)
void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt)
static String byteArrayToHex(byte[] array, int length, long arrayOffset, Font font)
void launchHxDButtonActionPerformed(java.awt.event.ActionEvent evt)
static String escapeFileName(String fileName)
Definition: FileUtil.java:169
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt)
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.