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