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