19 package org.sleuthkit.autopsy.corecomponents;
21 import java.awt.Component;
22 import java.awt.Cursor;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
27 import java.io.IOException;
28 import java.nio.file.Paths;
29 import java.util.concurrent.ExecutionException;
30 import java.util.logging.Level;
32 import org.openide.util.NbBundle;
34 import javax.swing.JMenuItem;
35 import javax.swing.JOptionPane;
36 import javax.swing.SwingWorker;
37 import javax.swing.text.BadLocationException;
38 import javax.swing.text.Utilities;
39 import org.netbeans.api.progress.ProgressHandle;
40 import org.openide.nodes.Node;
41 import org.openide.util.NbBundle.Messages;
42 import org.openide.util.lookup.ServiceProvider;
59 @SuppressWarnings(
"PMD.SingularField")
60 @ServiceProvider(service = DataContentViewer.class, position = 1)
63 private static final long PAGE_LENGTH = 16384;
64 private final byte[] data =
new byte[(int) PAGE_LENGTH];
65 private static int currentPage = 1;
78 customizeComponents();
79 this.resetComponent();
80 logger.log(Level.INFO,
"Created HexView instance: " +
this);
84 outputTextArea.setComponentPopupMenu(rightClickMenu);
85 ActionListener actList =
new ActionListener() {
87 public void actionPerformed(ActionEvent e) {
88 JMenuItem jmi = (JMenuItem) e.getSource();
89 if (jmi.equals(copyMenuItem)) {
90 outputTextArea.copy();
91 }
else if (jmi.equals(selectAllMenuItem)) {
92 outputTextArea.selectAll();
96 copyMenuItem.addActionListener(actList);
97 selectAllMenuItem.addActionListener(actList);
105 @SuppressWarnings(
"unchecked")
107 private
void initComponents() {
109 rightClickMenu =
new javax.swing.JPopupMenu();
110 copyMenuItem =
new javax.swing.JMenuItem();
111 selectAllMenuItem =
new javax.swing.JMenuItem();
112 jScrollPane3 =
new javax.swing.JScrollPane();
113 outputTextArea =
new javax.swing.JTextArea();
114 jScrollPane2 =
new javax.swing.JScrollPane();
115 hexViewerPanel =
new javax.swing.JPanel();
116 totalPageLabel =
new javax.swing.JLabel();
117 ofLabel =
new javax.swing.JLabel();
118 currentPageLabel =
new javax.swing.JLabel();
119 pageLabel =
new javax.swing.JLabel();
120 prevPageButton =
new javax.swing.JButton();
121 nextPageButton =
new javax.swing.JButton();
122 pageLabel2 =
new javax.swing.JLabel();
123 goToPageTextField =
new javax.swing.JTextField();
124 goToPageLabel =
new javax.swing.JLabel();
125 goToOffsetLabel =
new javax.swing.JLabel();
126 goToOffsetTextField =
new javax.swing.JTextField();
127 launchHxDButton =
new javax.swing.JButton();
129 copyMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.copyMenuItem.text"));
130 rightClickMenu.add(copyMenuItem);
132 selectAllMenuItem.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.selectAllMenuItem.text"));
133 rightClickMenu.add(selectAllMenuItem);
135 setPreferredSize(
new java.awt.Dimension(100, 58));
137 jScrollPane3.setPreferredSize(
new java.awt.Dimension(300, 33));
139 outputTextArea.setEditable(
false);
140 outputTextArea.setFont(
new Font(
"Monospaced", Font.PLAIN, 11));
141 outputTextArea.setTabSize(0);
142 outputTextArea.setInheritsPopupMenu(
true);
143 jScrollPane3.setViewportView(outputTextArea);
145 jScrollPane2.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
146 jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
148 totalPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.totalPageLabel.text_1"));
150 ofLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.ofLabel.text_1"));
152 currentPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.currentPageLabel.text_1"));
153 currentPageLabel.setMaximumSize(
new java.awt.Dimension(18, 14));
154 currentPageLabel.setMinimumSize(
new java.awt.Dimension(18, 14));
156 pageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.pageLabel.text_1"));
157 pageLabel.setMaximumSize(
new java.awt.Dimension(33, 14));
158 pageLabel.setMinimumSize(
new java.awt.Dimension(33, 14));
160 prevPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back.png")));
161 prevPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.prevPageButton.text"));
162 prevPageButton.setBorderPainted(
false);
163 prevPageButton.setContentAreaFilled(
false);
164 prevPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png")));
165 prevPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
166 prevPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
167 prevPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_back_hover.png")));
168 prevPageButton.addActionListener(
new java.awt.event.ActionListener() {
169 public void actionPerformed(java.awt.event.ActionEvent evt) {
170 prevPageButtonActionPerformed(evt);
174 nextPageButton.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png")));
175 nextPageButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.nextPageButton.text"));
176 nextPageButton.setBorderPainted(
false);
177 nextPageButton.setContentAreaFilled(
false);
178 nextPageButton.setDisabledIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png")));
179 nextPageButton.setMargin(
new java.awt.Insets(2, 0, 2, 0));
180 nextPageButton.setPreferredSize(
new java.awt.Dimension(23, 23));
181 nextPageButton.setRolloverIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/corecomponents/btn_step_forward_hover.png")));
182 nextPageButton.addActionListener(
new java.awt.event.ActionListener() {
183 public void actionPerformed(java.awt.event.ActionEvent evt) {
184 nextPageButtonActionPerformed(evt);
188 pageLabel2.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.pageLabel2.text"));
189 pageLabel2.setMaximumSize(
new java.awt.Dimension(29, 14));
190 pageLabel2.setMinimumSize(
new java.awt.Dimension(29, 14));
192 goToPageTextField.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.goToPageTextField.text"));
193 goToPageTextField.addActionListener(
new java.awt.event.ActionListener() {
194 public void actionPerformed(java.awt.event.ActionEvent evt) {
195 goToPageTextFieldActionPerformed(evt);
199 goToPageLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.goToPageLabel.text"));
201 goToOffsetLabel.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.goToOffsetLabel.text"));
203 goToOffsetTextField.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.goToOffsetTextField.text"));
204 goToOffsetTextField.addActionListener(
new java.awt.event.ActionListener() {
205 public void actionPerformed(java.awt.event.ActionEvent evt) {
206 goToOffsetTextFieldActionPerformed(evt);
210 launchHxDButton.setText(
org.openide.util.NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.launchHxDButton.text"));
211 launchHxDButton.addActionListener(
new java.awt.event.ActionListener() {
212 public void actionPerformed(java.awt.event.ActionEvent evt) {
213 launchHxDButtonActionPerformed(evt);
217 javax.swing.GroupLayout hexViewerPanelLayout =
new javax.swing.GroupLayout(hexViewerPanel);
218 hexViewerPanel.setLayout(hexViewerPanelLayout);
219 hexViewerPanelLayout.setHorizontalGroup(
220 hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
221 .addGroup(hexViewerPanelLayout.createSequentialGroup()
223 .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
225 .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
226 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
227 .addComponent(ofLabel)
228 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
229 .addComponent(totalPageLabel)
231 .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
232 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
233 .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
235 .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
237 .addComponent(goToPageLabel)
238 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
239 .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
241 .addComponent(goToOffsetLabel)
242 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
243 .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
244 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
245 .addComponent(launchHxDButton)
246 .addContainerGap(146, Short.MAX_VALUE))
248 hexViewerPanelLayout.setVerticalGroup(
249 hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
250 .addGroup(hexViewerPanelLayout.createSequentialGroup()
251 .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
252 .addComponent(pageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
253 .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
254 .addComponent(currentPageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
255 .addComponent(ofLabel)
256 .addComponent(totalPageLabel))
257 .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
258 .addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
259 .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
260 .addComponent(goToPageLabel)
261 .addComponent(goToPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
262 .addComponent(goToOffsetLabel)
263 .addGroup(hexViewerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
264 .addComponent(goToOffsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
265 .addComponent(launchHxDButton)))
271 jScrollPane2.setViewportView(hexViewerPanel);
273 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
274 this.setLayout(layout);
275 layout.setHorizontalGroup(
276 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
277 .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 827, Short.MAX_VALUE)
278 .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
280 layout.setVerticalGroup(
281 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
282 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
283 .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
284 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
285 .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 239, Short.MAX_VALUE))
290 setDataViewByPageNumber(currentPage - 1);
291 goToPageTextField.setText(Integer.toString(currentPage));
295 setDataViewByPageNumber(currentPage + 1);
296 goToPageTextField.setText(Integer.toString(currentPage));
300 String pageNumberStr = goToPageTextField.getText();
303 pageNumber = Integer.parseInt(pageNumberStr);
304 }
catch (NumberFormatException ex) {
305 pageNumber = totalPages + 1;
307 if (pageNumber > totalPages || pageNumber < 1) {
308 JOptionPane.showMessageDialog(
this,
309 NbBundle.getMessage(
this.getClass(),
310 "DataContentViewerHex.goToPageTextField.msgDlg",
312 NbBundle.getMessage(
this.getClass(),
313 "DataContentViewerHex.goToPageTextField.err"),
314 JOptionPane.WARNING_MESSAGE);
317 setDataViewByPageNumber(pageNumber);
331 String userSelectedLine;
334 userSelectedLine = outputTextArea.getText().subSequence(
335 Utilities.getRowStart(outputTextArea, outputTextArea.getCaretPosition()),
336 Utilities.getRowEnd(outputTextArea, outputTextArea.getCaretPosition()))
339 String hexForUserSelectedLine = userSelectedLine.substring(0, userSelectedLine.indexOf(
':'));
341 return Long.decode(hexForUserSelectedLine) + userInput;
342 }
catch (BadLocationException | StringIndexOutOfBoundsException | NumberFormatException ex) {
351 if (goToOffsetTextField.getText().startsWith(
"+") || goToOffsetTextField.getText().startsWith(
"-")) {
352 offset = getOffsetRelativeToCaretPosition(Long.decode(goToOffsetTextField.getText()));
354 offset = Long.decode(goToOffsetTextField.getText());
356 }
catch (NumberFormatException ex) {
358 JOptionPane.showMessageDialog(
this, NbBundle.getMessage(
this.getClass(),
"DataContentViewerHex.goToOffsetTextField.msgDlg", goToOffsetTextField.getText()));
363 setDataViewByOffset(offset);
365 outputTextArea.setText(NbBundle.getMessage(
DataContentViewerHex.class,
"DataContentViewerHex.setDataView.invalidOffset.negativeOffsetValue"));
369 @NbBundle.Messages({
"DataContentViewerHex.launchError=Unable to launch HxD Editor. "
370 +
"Please specify the HxD install location in Tools -> Options -> External Viewer",
371 "DataContentViewerHex.copyingFile=Copying file to open in HxD..."})
382 private boolean wasCancelled =
false;
386 ProgressHandle progress = ProgressHandle.createHandle(DataContentViewerHex_copyingFile(), () -> {
395 if (!HxDExecutable.exists() || !HxDExecutable.canExecute()) {
396 JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
401 File tempFile = Paths.get(tempDirectory,
414 ProcessBuilder launchHxDExecutable =
new ProcessBuilder();
415 launchHxDExecutable.command(String.format(
"\"%s\" \"%s\"",
416 HxDExecutable.getAbsolutePath(),
417 tempFile.getAbsolutePath()));
418 launchHxDExecutable.start();
419 }
catch (IOException ex) {
420 logger.log(Level.WARNING,
"Unsuccessful attempt to launch HxD", ex);
421 JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
425 logger.log(Level.SEVERE,
"Unable to copy file into temp directory", ex);
426 JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
467 launchWorker(dataSource, (page - 1) * PAGE_LENGTH, page);
476 launchWorker(dataSource, offset, (
int) (offset / PAGE_LENGTH) + 1);
480 "DataContentViewerHex_loading_text=Loading hex from file..."
491 if (this.dataSource == null) {
495 worker =
new HexWorker(source, offset, page);
496 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
497 outputTextArea.setText(Bundle.DataContentViewerHex_loading_text());
503 if (worker != null) {
510 if ((selectedNode == null)) {
515 if (content == null) {
519 dataSource = content;
521 if (dataSource.getSize() > 0) {
522 totalPages = Math.round((dataSource.getSize() - 1) / PAGE_LENGTH) + 1;
524 totalPageLabel.setText(Integer.toString(totalPages));
526 this.setDataViewByPageNumber(1);
531 return NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.title");
536 return NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.toolTip");
548 this.dataSource = null;
549 currentPageLabel.setText(
"");
550 totalPageLabel.setText(
"");
551 outputTextArea.setText(
"");
552 setComponentsVisibility(
false);
561 currentPageLabel.setVisible(isVisible);
562 totalPageLabel.setVisible(isVisible);
563 ofLabel.setVisible(isVisible);
564 prevPageButton.setVisible(isVisible);
565 nextPageButton.setVisible(isVisible);
566 pageLabel.setVisible(isVisible);
567 pageLabel2.setVisible(isVisible);
568 goToPageTextField.setVisible(isVisible);
569 goToPageLabel.setVisible(isVisible);
570 goToOffsetTextField.setVisible(isVisible);
571 goToOffsetLabel.setVisible(isVisible);
572 launchHxDButton.setVisible(isVisible);
581 return content != null && !(content instanceof BlackboardArtifact) && content.getSize() > 0;
597 private class HexWorker extends SwingWorker<String, Void> {
599 private final byte[] data =
new byte[(int) PAGE_LENGTH];
603 private String errorText =
"";
605 HexWorker(Content content,
long offset,
int newCurrentPage) {
606 this.content = content;
607 this.offset = offset;
608 this.newCurrentPage = newCurrentPage;
614 if (content.getSize() > 0) {
616 bytesRead = content.read(data, offset, PAGE_LENGTH);
617 }
catch (TskCoreException ex) {
618 errorText = NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.setDataView.errorText", offset,
619 offset + PAGE_LENGTH);
620 logger.log(Level.WARNING,
"Error while trying to show the hex content.", ex);
625 if (bytesRead <= 0) {
626 errorText = NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.setDataView.errorText", offset,
627 offset + PAGE_LENGTH);
630 if (errorText.isEmpty()) {
631 int showLength = bytesRead < PAGE_LENGTH ? bytesRead : (int) PAGE_LENGTH;
646 outputTextArea.setText(text);
649 if ((errorText.isEmpty()) && (newCurrentPage < totalPages)) {
650 nextPageButton.setEnabled(
true);
652 nextPageButton.setEnabled(
false);
655 if ((errorText.isEmpty()) && (newCurrentPage > 1)) {
656 prevPageButton.setEnabled(
true);
658 prevPageButton.setEnabled(
false);
661 currentPageLabel.setText(Integer.toString(newCurrentPage));
662 setComponentsVisibility(
true);
663 outputTextArea.setCaretPosition(0);
664 goToPageTextField.setText(Integer.toString(newCurrentPage));
665 currentPage = newCurrentPage;
666 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
668 }
catch (InterruptedException | ExecutionException ex) {
669 logger.log(Level.SEVERE, String.format(
"Failed to get hex data from content (%d)", content.getId()), ex);
javax.swing.JScrollPane jScrollPane2
static Content getDefaultContent(Node node)
javax.swing.JButton launchHxDButton
void setNode(Node selectedNode)
javax.swing.JLabel currentPageLabel
javax.swing.JPopupMenu rightClickMenu
void setComponentsVisibility(boolean isVisible)
javax.swing.JButton prevPageButton
static String getExternalHexEditorPath()
int isPreferred(Node node)
String getTempDirectory()
javax.swing.JTextField goToOffsetTextField
javax.swing.JLabel goToPageLabel
javax.swing.JTextField goToPageTextField
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
void goToOffsetTextFieldActionPerformed(java.awt.event.ActionEvent evt)
boolean isSupported(Node node)
void launchWorker(Content source, long offset, int page)
javax.swing.JMenuItem copyMenuItem
long getOffsetRelativeToCaretPosition(Long userInput)
void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt)
void setDataViewByOffset(long offset)
static String byteArrayToHex(byte[] array, int length, long arrayOffset, Font font)
void launchHxDButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JPanel hexViewerPanel
void setDataViewByPageNumber(int page)
javax.swing.JTextArea outputTextArea
javax.swing.JButton nextPageButton
static String escapeFileName(String fileName)
javax.swing.JMenuItem selectAllMenuItem
synchronized static Logger getLogger(String name)
javax.swing.JLabel goToOffsetLabel
javax.swing.JLabel ofLabel
static Case getCurrentCaseThrows()
void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt)
javax.swing.JLabel totalPageLabel
javax.swing.JLabel pageLabel2
javax.swing.JScrollPane jScrollPane3
javax.swing.JLabel pageLabel
void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt)
DataContentViewer createInstance()
void customizeComponents()