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