mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
4961 make internal listeners for HexView and RejTreeView to avoid leaking this
This commit is contained in:
parent
711ae01f20
commit
6feed3db22
@ -51,7 +51,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
* estimate it to load three strings with length equal to the given ByteBuffer.
|
* estimate it to load three strings with length equal to the given ByteBuffer.
|
||||||
* So its probably not good to use this view with large files.
|
* So its probably not good to use this view with large files.
|
||||||
*/
|
*/
|
||||||
final class HexView extends JPanel implements CaretListener {
|
final class HexView extends JPanel {
|
||||||
|
|
||||||
private final static int DEFAULT_BYTES_PER_LINE = 0x10;
|
private final static int DEFAULT_BYTES_PER_LINE = 0x10;
|
||||||
private final static char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
private final static char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
@ -59,6 +59,7 @@ final class HexView extends JPanel implements CaretListener {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final int bytesPerLine;
|
private final int bytesPerLine;
|
||||||
private final ByteBuffer buf;
|
private final ByteBuffer buf;
|
||||||
|
private final HexViewListener listener = new HexViewListener();
|
||||||
private final JTextComponent offsetView;
|
private final JTextComponent offsetView;
|
||||||
private final JTextComponent hexView;
|
private final JTextComponent hexView;
|
||||||
private final JTextComponent asciiView;
|
private final JTextComponent asciiView;
|
||||||
@ -155,147 +156,151 @@ final class HexView extends JPanel implements CaretListener {
|
|||||||
this.offsetView.setText(offsetSB.toString());
|
this.offsetView.setText(offsetSB.toString());
|
||||||
this.hexView.setText(hexSB.toString());
|
this.hexView.setText(hexSB.toString());
|
||||||
this.asciiView.setText(asciiSB.toString());
|
this.asciiView.setText(asciiSB.toString());
|
||||||
this.hexView.addCaretListener(this);
|
this.hexView.addCaretListener(listener);
|
||||||
this.asciiView.addCaretListener(this);
|
this.asciiView.addCaretListener(listener);
|
||||||
this.asciiView.setSelectedTextColor(this.asciiView.getForeground());
|
this.asciiView.setSelectedTextColor(this.asciiView.getForeground());
|
||||||
this.hexView.setSelectedTextColor(this.asciiView.getForeground());
|
this.hexView.setSelectedTextColor(this.asciiView.getForeground());
|
||||||
this.highlightColor = this.hexView.getSelectionColor();
|
this.highlightColor = this.hexView.getSelectionColor();
|
||||||
this.highlighterPainter = new DefaultHighlighter.DefaultHighlightPainter(this.highlightColor);
|
this.highlighterPainter = new DefaultHighlighter.DefaultHighlightPainter(this.highlightColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private class HexViewListener implements CaretListener {
|
||||||
* clearHighlight removes any colors applied to the text views.
|
|
||||||
*/
|
|
||||||
private void clearHighlight() {
|
|
||||||
this.asciiView.getHighlighter().removeAllHighlights();
|
|
||||||
this.hexView.getHighlighter().removeAllHighlights();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* setHighlight colors the given byte range.
|
public void caretUpdate(CaretEvent e) {
|
||||||
*
|
if (e.getMark() == e.getDot()) {
|
||||||
* @param startByte The starting byte index of the selection.
|
this.clearHighlight();
|
||||||
* @param endByte The ending byte index of the selection.
|
}
|
||||||
*/
|
|
||||||
private void setHighlight(int startByte, int endByte) {
|
|
||||||
int startRows = (startByte - (startByte % this.bytesPerLine)) / this.bytesPerLine;
|
|
||||||
int endRows = (endByte - (endByte % this.bytesPerLine)) / this.bytesPerLine;
|
|
||||||
|
|
||||||
this.clearHighlight();
|
if (e.getSource() == asciiView) {
|
||||||
|
int startByte = e.getMark();
|
||||||
|
int endByte = e.getDot();
|
||||||
|
|
||||||
try {
|
if (startByte > endByte) {
|
||||||
this.asciiView.getHighlighter().addHighlight(startByte + startRows, endByte + endRows, this.highlighterPainter);
|
int t = endByte;
|
||||||
this.hexView.getHighlighter().addHighlight((startByte * 3) + startRows, (endByte * 3) + endRows, this.highlighterPainter);
|
endByte = startByte;
|
||||||
} catch (BadLocationException ex) {
|
startByte = t;
|
||||||
logger.log(Level.WARNING, "bad location", ex);
|
}
|
||||||
|
|
||||||
|
// the number of line endings before the start,end points
|
||||||
|
int startRows = (startByte - (startByte % bytesPerLine)) / bytesPerLine;
|
||||||
|
int endRows = (endByte - (endByte % bytesPerLine)) / bytesPerLine;
|
||||||
|
|
||||||
|
// the byte index of the start,end points in the ASCII view
|
||||||
|
startByte -= startRows;
|
||||||
|
endByte -= endRows;
|
||||||
|
|
||||||
|
// avoid the loop
|
||||||
|
if (asciiLastSelectionStart == startByte && asciiLastSelectionEnd == endByte) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
asciiLastSelectionStart = startByte;
|
||||||
|
asciiLastSelectionEnd = endByte;
|
||||||
|
|
||||||
|
this.setSelection(startByte, endByte);
|
||||||
|
} else if (e.getSource() == hexView) {
|
||||||
|
int startByte = e.getMark();
|
||||||
|
int endByte = e.getDot();
|
||||||
|
|
||||||
|
if (startByte > endByte) {
|
||||||
|
int t = endByte;
|
||||||
|
endByte = startByte;
|
||||||
|
startByte = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the number of line endings before the start,end points
|
||||||
|
int startRows = (startByte - (startByte % bytesPerLine)) / (3 * bytesPerLine);
|
||||||
|
int endRows = (endByte - (endByte % bytesPerLine)) / (3 * bytesPerLine);
|
||||||
|
|
||||||
|
// the byte index of the start,end points in the ASCII view
|
||||||
|
startByte -= startRows;
|
||||||
|
startByte /= 3;
|
||||||
|
endByte -= endRows;
|
||||||
|
endByte /= 3;
|
||||||
|
|
||||||
|
if (hexLastSelectionStart == startByte && hexLastSelectionEnd == endByte) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hexLastSelectionStart = startByte;
|
||||||
|
hexLastSelectionEnd = endByte;
|
||||||
|
|
||||||
|
this.setSelection(startByte, endByte);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.INFO, "from unknown");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setSelection sets the given byte range as "selected", which from a GUI
|
* setSelection sets the given byte range as "selected", which from a
|
||||||
* perspective means the bytes are highlighted, and the status bar updated.
|
* GUI perspective means the bytes are highlighted, and the status bar
|
||||||
*
|
* updated.
|
||||||
* @param startByte The starting byte index of the selection.
|
*
|
||||||
* @param endByte The ending byte index of the selection.
|
* @param startByte The starting byte index of the selection.
|
||||||
*/
|
* @param endByte The ending byte index of the selection.
|
||||||
@Messages({"# {0} - startByteD",
|
*/
|
||||||
"# {1} - endByteD",
|
@Messages({"# {0} - startByteD",
|
||||||
"# {2} - lengthD",
|
"# {1} - endByteD",
|
||||||
"# {3} - startByteH",
|
"# {2} - lengthD",
|
||||||
"# {4} - endByteH",
|
"# {3} - startByteH",
|
||||||
"# {5} - lengthH",
|
"# {4} - endByteH",
|
||||||
"HexView.statusTemplate.nonZeroLength=Selection: {0} to {1} (len: {2}) [{3} to {4} (len: {5})",
|
"# {5} - lengthH",
|
||||||
"# {0} - startByteDec",
|
"HexView.statusTemplate.nonZeroLength=Selection: {0} to {1} (len: {2}) [{3} to {4} (len: {5})",
|
||||||
"# {1} - startByteHex",
|
"# {0} - startByteDec",
|
||||||
"HexView.statusTemplate.zeroLength=Position: {0} [{1}])"})
|
"# {1} - startByteHex",
|
||||||
private void setSelection(int startByte, int endByte) {
|
"HexView.statusTemplate.zeroLength=Position: {0} [{1}])"})
|
||||||
this.setHighlight(startByte, endByte);
|
private void setSelection(int startByte, int endByte) {
|
||||||
|
this.setHighlight(startByte, endByte);
|
||||||
|
|
||||||
if (startByte != endByte) {
|
if (startByte != endByte) {
|
||||||
/**
|
/**
|
||||||
* @param 1 Start
|
* @param 1 Start
|
||||||
* @param 2 End
|
* @param 2 End
|
||||||
* @param 3 Len
|
* @param 3 Len
|
||||||
*/
|
*/
|
||||||
int length = endByte - startByte;
|
int length = endByte - startByte;
|
||||||
String text = Bundle.HexView_statusTemplate_nonZeroLength(
|
String text = Bundle.HexView_statusTemplate_nonZeroLength(
|
||||||
startByte,
|
startByte,
|
||||||
endByte,
|
endByte,
|
||||||
length,
|
length,
|
||||||
String.format("0x%1$x", startByte),
|
String.format("0x%1$x", startByte),
|
||||||
String.format("0x%1$x", endByte),
|
String.format("0x%1$x", endByte),
|
||||||
String.format("0x%1$x", length));
|
String.format("0x%1$x", length));
|
||||||
this.statusLabel.setText(text);
|
statusLabel.setText(text);
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
* @param 1 Start
|
* @param 1 Start
|
||||||
*/
|
*/
|
||||||
String text = Bundle.HexView_statusTemplate_zeroLength(startByte, String.format("0x%1$x", startByte));
|
String text = Bundle.HexView_statusTemplate_zeroLength(startByte, String.format("0x%1$x", startByte));
|
||||||
this.statusLabel.setText(text);
|
statusLabel.setText(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void caretUpdate(CaretEvent e) {
|
* clearHighlight removes any colors applied to the text views.
|
||||||
if (e.getMark() == e.getDot()) {
|
*/
|
||||||
|
private void clearHighlight() {
|
||||||
|
asciiView.getHighlighter().removeAllHighlights();
|
||||||
|
hexView.getHighlighter().removeAllHighlights();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setHighlight colors the given byte range.
|
||||||
|
*
|
||||||
|
* @param startByte The starting byte index of the selection.
|
||||||
|
* @param endByte The ending byte index of the selection.
|
||||||
|
*/
|
||||||
|
private void setHighlight(int startByte, int endByte) {
|
||||||
|
int startRows = (startByte - (startByte % bytesPerLine)) / bytesPerLine;
|
||||||
|
int endRows = (endByte - (endByte % bytesPerLine)) / bytesPerLine;
|
||||||
|
|
||||||
this.clearHighlight();
|
this.clearHighlight();
|
||||||
}
|
|
||||||
|
|
||||||
if (e.getSource() == this.asciiView) {
|
try {
|
||||||
int startByte = e.getMark();
|
asciiView.getHighlighter().addHighlight(startByte + startRows, endByte + endRows, highlighterPainter);
|
||||||
int endByte = e.getDot();
|
hexView.getHighlighter().addHighlight((startByte * 3) + startRows, (endByte * 3) + endRows, highlighterPainter);
|
||||||
|
} catch (BadLocationException ex) {
|
||||||
if (startByte > endByte) {
|
logger.log(Level.WARNING, "bad location", ex);
|
||||||
int t = endByte;
|
|
||||||
endByte = startByte;
|
|
||||||
startByte = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the number of line endings before the start,end points
|
|
||||||
int startRows = (startByte - (startByte % this.bytesPerLine)) / this.bytesPerLine;
|
|
||||||
int endRows = (endByte - (endByte % this.bytesPerLine)) / this.bytesPerLine;
|
|
||||||
|
|
||||||
// the byte index of the start,end points in the ASCII view
|
|
||||||
startByte -= startRows;
|
|
||||||
endByte -= endRows;
|
|
||||||
|
|
||||||
// avoid the loop
|
|
||||||
if (asciiLastSelectionStart == startByte && asciiLastSelectionEnd == endByte) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
asciiLastSelectionStart = startByte;
|
|
||||||
asciiLastSelectionEnd = endByte;
|
|
||||||
|
|
||||||
this.setSelection(startByte, endByte);
|
|
||||||
} else if (e.getSource() == this.hexView) {
|
|
||||||
int startByte = e.getMark();
|
|
||||||
int endByte = e.getDot();
|
|
||||||
|
|
||||||
if (startByte > endByte) {
|
|
||||||
int t = endByte;
|
|
||||||
endByte = startByte;
|
|
||||||
startByte = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the number of line endings before the start,end points
|
|
||||||
int startRows = (startByte - (startByte % this.bytesPerLine)) / (3 * this.bytesPerLine);
|
|
||||||
int endRows = (endByte - (endByte % this.bytesPerLine)) / (3 * this.bytesPerLine);
|
|
||||||
|
|
||||||
// the byte index of the start,end points in the ASCII view
|
|
||||||
startByte -= startRows;
|
|
||||||
startByte /= 3;
|
|
||||||
endByte -= endRows;
|
|
||||||
endByte /= 3;
|
|
||||||
|
|
||||||
if (hexLastSelectionStart == startByte && hexLastSelectionEnd == endByte) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hexLastSelectionStart = startByte;
|
|
||||||
hexLastSelectionEnd = endByte;
|
|
||||||
|
|
||||||
this.setSelection(startByte, endByte);
|
|
||||||
} else {
|
|
||||||
logger.log(Level.INFO, "from unknown");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,16 @@ import javax.swing.JTree;
|
|||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
final class RejTreeView extends JScrollPane implements TreeExpansionListener, TreeSelectionListener {
|
final class RejTreeView extends JScrollPane {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(HexView.class.getName());
|
private static final Logger logger = Logger.getLogger(HexView.class.getName());
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final DefaultTreeModel treeModel;
|
private final DefaultTreeModel treeModel;
|
||||||
|
private final RejTreeViewListener listener = new RejTreeViewListener();
|
||||||
private final RegistryHive hive;
|
private final RegistryHive hive;
|
||||||
private final CopyOnWriteArrayList<RejTreeNodeSelectionListener> nodeSelectionListeners;
|
private final CopyOnWriteArrayList<RejTreeNodeSelectionListener> nodeSelectionListeners;
|
||||||
private final JTree tree;
|
private final JTree tree;
|
||||||
|
|
||||||
@NbBundle.Messages({"RejTreeView.failureValueName.text=PARSE FAILED"})
|
@NbBundle.Messages({"RejTreeView.failureValueName.text=PARSE FAILED"})
|
||||||
RejTreeView(RegistryHive hive) {
|
RejTreeView(RegistryHive hive) {
|
||||||
this.hive = hive;
|
this.hive = hive;
|
||||||
@ -63,13 +65,13 @@ final class RejTreeView extends JScrollPane implements TreeExpansionListener, Tr
|
|||||||
this.treeModel.setAsksAllowsChildren(true);
|
this.treeModel.setAsksAllowsChildren(true);
|
||||||
|
|
||||||
this.tree = new JTree(this.treeModel);
|
this.tree = new JTree(this.treeModel);
|
||||||
this.tree.addTreeExpansionListener(this);
|
this.tree.addTreeExpansionListener(listener);
|
||||||
this.tree.addTreeSelectionListener(this);
|
this.tree.addTreeSelectionListener(listener);
|
||||||
// here's a bit of a hack to force the children to be loaded and shown
|
// here's a bit of a hack to force the children to be loaded and shown
|
||||||
this.tree.collapsePath(new TreePath(rootNode.getPath()));
|
this.tree.collapsePath(new TreePath(rootNode.getPath()));
|
||||||
this.tree.expandPath(new TreePath(rootNode.getPath()));
|
this.tree.expandPath(new TreePath(rootNode.getPath()));
|
||||||
setViewportView(this.tree);
|
setViewportView(this.tree);
|
||||||
setPreferredSize(new Dimension(350,20));
|
setPreferredSize(new Dimension(350, 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,31 +85,6 @@ final class RejTreeView extends JScrollPane implements TreeExpansionListener, Tr
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void treeExpanded(TreeExpansionEvent event) {
|
|
||||||
TreePath path = event.getPath();
|
|
||||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
|
|
||||||
|
|
||||||
if (node.getChildCount() == 0 && node.getUserObject() instanceof RejTreeNode) {
|
|
||||||
RejTreeNode n = (RejTreeNode) node.getUserObject();
|
|
||||||
for (RejTreeNode rejTreeNode : n.getChildren()) {
|
|
||||||
node.add(getTreeNode(rejTreeNode));
|
|
||||||
}
|
|
||||||
this.treeModel.nodeStructureChanged(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void treeCollapsed(TreeExpansionEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void valueChanged(TreeSelectionEvent e) {
|
|
||||||
TreePath path = e.getPath();
|
|
||||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
|
|
||||||
this.triggerRejTreeNodeSelection((RejTreeNode) node.getUserObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
void addRejTreeNodeSelectionListener(RejTreeNodeSelectionListener l) {
|
void addRejTreeNodeSelectionListener(RejTreeNodeSelectionListener l) {
|
||||||
this.nodeSelectionListeners.add(l);
|
this.nodeSelectionListeners.add(l);
|
||||||
}
|
}
|
||||||
@ -116,10 +93,38 @@ final class RejTreeView extends JScrollPane implements TreeExpansionListener, Tr
|
|||||||
this.nodeSelectionListeners.remove(l);
|
this.nodeSelectionListeners.remove(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
void triggerRejTreeNodeSelection(RejTreeNode n) {
|
private class RejTreeViewListener implements TreeExpansionListener, TreeSelectionListener {
|
||||||
RejTreeNodeSelectionEvent e = new RejTreeNodeSelectionEvent(n);
|
|
||||||
for (RejTreeNodeSelectionListener listener : this.nodeSelectionListeners) {
|
@Override
|
||||||
listener.nodeSelected(e);
|
public void treeExpanded(TreeExpansionEvent event) {
|
||||||
|
TreePath path = event.getPath();
|
||||||
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
|
||||||
|
|
||||||
|
if (node.getChildCount() == 0 && node.getUserObject() instanceof RejTreeNode) {
|
||||||
|
RejTreeNode n = (RejTreeNode) node.getUserObject();
|
||||||
|
for (RejTreeNode rejTreeNode : n.getChildren()) {
|
||||||
|
node.add(getTreeNode(rejTreeNode));
|
||||||
|
}
|
||||||
|
treeModel.nodeStructureChanged(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void treeCollapsed(TreeExpansionEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged(TreeSelectionEvent e) {
|
||||||
|
TreePath path = e.getPath();
|
||||||
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
|
||||||
|
this.triggerRejTreeNodeSelection((RejTreeNode) node.getUserObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
void triggerRejTreeNodeSelection(RejTreeNode n) {
|
||||||
|
RejTreeNodeSelectionEvent e = new RejTreeNodeSelectionEvent(n);
|
||||||
|
for (RejTreeNodeSelectionListener listener : nodeSelectionListeners) {
|
||||||
|
listener.nodeSelected(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user