Merge pull request #351 from hajdam/master
JHexEditor replaced with BinEd Hexadecimal viewer library
This commit is contained in:
commit
da616f82d0
13 changed files with 2178 additions and 709 deletions
22
pom.xml
22
pom.xml
|
@ -16,6 +16,7 @@
|
|||
<annotations.version>22.0.0</annotations.version>
|
||||
<apktool.version>2.5.0bcv2</apktool.version>
|
||||
<asm.version>9.2</asm.version>
|
||||
<bined.version>0.2.0</bined.version>
|
||||
<cfr.version>0.151</cfr.version>
|
||||
<cloning.version>1.9.12</cloning.version>
|
||||
<commons-cli.version>1.4</commons-cli.version>
|
||||
|
@ -35,6 +36,7 @@
|
|||
<byteanalysis.version>1.0bcv</byteanalysis.version>
|
||||
<jgraphx.version>3.4.1.3</jgraphx.version>
|
||||
<objenesis.version>3.2</objenesis.version>
|
||||
<paged_data.version>0.2.0</paged_data.version>
|
||||
<procyon.version>0.5.36</procyon.version>
|
||||
<rsyntaxtextarea.version>3.1.3</rsyntaxtextarea.version>
|
||||
<slf4j.version>1.7.32</slf4j.version>
|
||||
|
@ -103,6 +105,21 @@
|
|||
<artifactId>asm-util</artifactId>
|
||||
<version>${asm.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.exbin.bined</groupId>
|
||||
<artifactId>bined-core</artifactId>
|
||||
<version>${bined.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.exbin.bined</groupId>
|
||||
<artifactId>bined-swing</artifactId>
|
||||
<version>${bined.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.exbin.bined</groupId>
|
||||
<artifactId>bined-highlight-swing</artifactId>
|
||||
<version>${bined.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.benf</groupId>
|
||||
<artifactId>cfr</artifactId>
|
||||
|
@ -204,6 +221,11 @@
|
|||
<artifactId>objenesis</artifactId>
|
||||
<version>${objenesis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.exbin.auxiliary</groupId>
|
||||
<artifactId>paged_data</artifactId>
|
||||
<version>${paged_data.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bitbucket.mstrobel</groupId>
|
||||
<artifactId>procyon-core</artifactId>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.exbin.bined.CodeAreaCaretPosition;
|
||||
import org.exbin.bined.EditMode;
|
||||
import org.exbin.bined.EditOperation;
|
||||
import org.exbin.bined.SelectionRange;
|
||||
|
||||
/**
|
||||
* Binary editor status interface.
|
||||
*
|
||||
* @author hajdam
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public interface BinaryStatusApi {
|
||||
|
||||
/**
|
||||
* Reports cursor position.
|
||||
*
|
||||
* @param cursorPosition cursor position
|
||||
*/
|
||||
void setCursorPosition(CodeAreaCaretPosition cursorPosition);
|
||||
|
||||
/**
|
||||
* Sets current selection.
|
||||
*
|
||||
* @param selectionRange current selection
|
||||
*/
|
||||
void setSelectionRange(SelectionRange selectionRange);
|
||||
|
||||
/**
|
||||
* Reports currently active edit mode.
|
||||
*
|
||||
* @param mode edit mode
|
||||
* @param operation edit operation
|
||||
*/
|
||||
void setEditMode(EditMode mode, EditOperation operation);
|
||||
|
||||
/**
|
||||
* Sets current document size.
|
||||
*
|
||||
* @param documentSize document size
|
||||
* @param initialDocumentSize document size when file was opened
|
||||
*/
|
||||
void setCurrentDocumentSize(long documentSize, long initialDocumentSize);
|
||||
}
|
|
@ -0,0 +1,672 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import javax.swing.JToolTip;
|
||||
import org.exbin.bined.CodeAreaCaretPosition;
|
||||
import org.exbin.bined.CodeAreaUtils;
|
||||
import org.exbin.bined.EditMode;
|
||||
import org.exbin.bined.EditOperation;
|
||||
import org.exbin.bined.PositionCodeType;
|
||||
import org.exbin.bined.SelectionRange;
|
||||
|
||||
/**
|
||||
* Binary editor status panel.
|
||||
*
|
||||
* @author hajdam
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BinaryStatusPanel extends javax.swing.JPanel implements BinaryStatusApi {
|
||||
|
||||
public static int DEFAULT_OCTAL_SPACE_GROUP_SIZE = 4;
|
||||
public static int DEFAULT_DECIMAL_SPACE_GROUP_SIZE = 3;
|
||||
public static int DEFAULT_HEXADECIMAL_SPACE_GROUP_SIZE = 4;
|
||||
|
||||
public static final String INSERT_EDIT_MODE_LABEL = "INS";
|
||||
public static final String OVERWRITE_EDIT_MODE_LABEL = "OVR";
|
||||
public static final String READONLY_EDIT_MODE_LABEL = "RO";
|
||||
public static final String INPLACE_EDIT_MODE_LABEL = "INP";
|
||||
|
||||
public static final String OCTAL_CODE_TYPE_LABEL = "OCT";
|
||||
public static final String DECIMAL_CODE_TYPE_LABEL = "DEC";
|
||||
public static final String HEXADECIMAL_CODE_TYPE_LABEL = "HEX";
|
||||
|
||||
private StatusCursorPositionFormat cursorPositionFormat = new StatusCursorPositionFormat();
|
||||
private StatusDocumentSizeFormat documentSizeFormat = new StatusDocumentSizeFormat();
|
||||
private int octalSpaceGroupSize = DEFAULT_OCTAL_SPACE_GROUP_SIZE;
|
||||
private int decimalSpaceGroupSize = DEFAULT_DECIMAL_SPACE_GROUP_SIZE;
|
||||
private int hexadecimalSpaceGroupSize = DEFAULT_HEXADECIMAL_SPACE_GROUP_SIZE;
|
||||
|
||||
private EditOperation editOperation;
|
||||
private CodeAreaCaretPosition caretPosition;
|
||||
private SelectionRange selectionRange;
|
||||
private long documentSize;
|
||||
private long initialDocumentSize;
|
||||
|
||||
private javax.swing.JMenu cursorPositionCodeTypeMenu;
|
||||
private javax.swing.JLabel cursorPositionLabel;
|
||||
private javax.swing.ButtonGroup cursorPositionModeButtonGroup;
|
||||
private javax.swing.JCheckBoxMenuItem cursorPositionShowOffsetCheckBoxMenuItem;
|
||||
private javax.swing.JRadioButtonMenuItem decimalCursorPositionModeRadioButtonMenuItem;
|
||||
private javax.swing.JRadioButtonMenuItem decimalDocumentSizeModeRadioButtonMenuItem;
|
||||
private javax.swing.JMenu documentSizeCodeTypeMenu;
|
||||
private javax.swing.JMenuItem documentSizeCopyMenuItem;
|
||||
private javax.swing.JLabel documentSizeLabel;
|
||||
private javax.swing.ButtonGroup documentSizeModeButtonGroup;
|
||||
private javax.swing.JPopupMenu documentSizePopupMenu;
|
||||
private javax.swing.JCheckBoxMenuItem documentSizeShowRelativeCheckBoxMenuItem;
|
||||
private javax.swing.JLabel editModeLabel;
|
||||
private javax.swing.JLabel encodingLabel;
|
||||
private javax.swing.JRadioButtonMenuItem hexadecimalCursorPositionModeRadioButtonMenuItem;
|
||||
private javax.swing.JRadioButtonMenuItem hexadecimalDocumentSizeModeRadioButtonMenuItem;
|
||||
private javax.swing.JPopupMenu.Separator jSeparator1;
|
||||
private javax.swing.JPopupMenu.Separator jSeparator2;
|
||||
private javax.swing.JRadioButtonMenuItem octalCursorPositionModeRadioButtonMenuItem;
|
||||
private javax.swing.JRadioButtonMenuItem octalDocumentSizeModeRadioButtonMenuItem;
|
||||
private javax.swing.JMenuItem positionCopyMenuItem;
|
||||
private javax.swing.JMenuItem positionGoToMenuItem;
|
||||
private javax.swing.JPopupMenu positionPopupMenu;
|
||||
|
||||
public BinaryStatusPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
public void updateStatus() {
|
||||
updateCaretPosition();
|
||||
updateCursorPositionToolTip();
|
||||
updateDocumentSize();
|
||||
updateDocumentSizeToolTip();
|
||||
|
||||
switch (cursorPositionFormat.getCodeType()) {
|
||||
case OCTAL: {
|
||||
octalCursorPositionModeRadioButtonMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case DECIMAL: {
|
||||
decimalCursorPositionModeRadioButtonMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case HEXADECIMAL: {
|
||||
hexadecimalCursorPositionModeRadioButtonMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CodeAreaUtils.getInvalidTypeException(cursorPositionFormat.getCodeType());
|
||||
}
|
||||
cursorPositionShowOffsetCheckBoxMenuItem.setSelected(cursorPositionFormat.isShowOffset());
|
||||
|
||||
switch (documentSizeFormat.getCodeType()) {
|
||||
case OCTAL: {
|
||||
octalDocumentSizeModeRadioButtonMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case DECIMAL: {
|
||||
decimalDocumentSizeModeRadioButtonMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case HEXADECIMAL: {
|
||||
hexadecimalDocumentSizeModeRadioButtonMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CodeAreaUtils.getInvalidTypeException(documentSizeFormat.getCodeType());
|
||||
}
|
||||
documentSizeShowRelativeCheckBoxMenuItem.setSelected(documentSizeFormat.isShowRelative());
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
|
||||
positionPopupMenu = new javax.swing.JPopupMenu();
|
||||
cursorPositionCodeTypeMenu = new javax.swing.JMenu();
|
||||
octalCursorPositionModeRadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
|
||||
decimalCursorPositionModeRadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
|
||||
hexadecimalCursorPositionModeRadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
|
||||
cursorPositionShowOffsetCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
|
||||
jSeparator2 = new javax.swing.JPopupMenu.Separator();
|
||||
positionCopyMenuItem = new javax.swing.JMenuItem();
|
||||
positionGoToMenuItem = new javax.swing.JMenuItem();
|
||||
documentSizePopupMenu = new javax.swing.JPopupMenu();
|
||||
documentSizeCodeTypeMenu = new javax.swing.JMenu();
|
||||
octalDocumentSizeModeRadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
|
||||
decimalDocumentSizeModeRadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
|
||||
hexadecimalDocumentSizeModeRadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
|
||||
documentSizeShowRelativeCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
|
||||
jSeparator1 = new javax.swing.JPopupMenu.Separator();
|
||||
documentSizeCopyMenuItem = new javax.swing.JMenuItem();
|
||||
documentSizeModeButtonGroup = new javax.swing.ButtonGroup();
|
||||
cursorPositionModeButtonGroup = new javax.swing.ButtonGroup();
|
||||
documentSizeLabel = new javax.swing.JLabel() {
|
||||
@Override
|
||||
public JToolTip createToolTip() {
|
||||
updateDocumentSizeToolTip();
|
||||
return super.createToolTip();
|
||||
}
|
||||
};
|
||||
cursorPositionLabel = new javax.swing.JLabel() {
|
||||
@Override
|
||||
public JToolTip createToolTip() {
|
||||
updateCursorPositionToolTip();
|
||||
return super.createToolTip();
|
||||
}
|
||||
};
|
||||
editModeLabel = new javax.swing.JLabel();
|
||||
encodingLabel = new javax.swing.JLabel();
|
||||
|
||||
positionPopupMenu.setName("positionPopupMenu");
|
||||
|
||||
cursorPositionCodeTypeMenu.setText("Code Type");
|
||||
cursorPositionCodeTypeMenu.setName("cursorPositionCodeTypeMenu");
|
||||
|
||||
cursorPositionModeButtonGroup.add(octalCursorPositionModeRadioButtonMenuItem);
|
||||
octalCursorPositionModeRadioButtonMenuItem.setText("Show as octal");
|
||||
octalCursorPositionModeRadioButtonMenuItem.setName("octalCursorPositionModeRadioButtonMenuItem");
|
||||
octalCursorPositionModeRadioButtonMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
octalCursorPositionModeRadioButtonMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cursorPositionCodeTypeMenu.add(octalCursorPositionModeRadioButtonMenuItem);
|
||||
|
||||
cursorPositionModeButtonGroup.add(decimalCursorPositionModeRadioButtonMenuItem);
|
||||
decimalCursorPositionModeRadioButtonMenuItem.setSelected(true);
|
||||
decimalCursorPositionModeRadioButtonMenuItem.setText("Show as decimal");
|
||||
decimalCursorPositionModeRadioButtonMenuItem.setName("decimalCursorPositionModeRadioButtonMenuItem");
|
||||
decimalCursorPositionModeRadioButtonMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
decimalCursorPositionModeRadioButtonMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cursorPositionCodeTypeMenu.add(decimalCursorPositionModeRadioButtonMenuItem);
|
||||
|
||||
cursorPositionModeButtonGroup.add(hexadecimalCursorPositionModeRadioButtonMenuItem);
|
||||
hexadecimalCursorPositionModeRadioButtonMenuItem.setText("Show as hexadecimal");
|
||||
hexadecimalCursorPositionModeRadioButtonMenuItem.setName("hexadecimalCursorPositionModeRadioButtonMenuItem");
|
||||
hexadecimalCursorPositionModeRadioButtonMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
hexadecimalCursorPositionModeRadioButtonMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cursorPositionCodeTypeMenu.add(hexadecimalCursorPositionModeRadioButtonMenuItem);
|
||||
|
||||
positionPopupMenu.add(cursorPositionCodeTypeMenu);
|
||||
|
||||
cursorPositionShowOffsetCheckBoxMenuItem.setSelected(true);
|
||||
cursorPositionShowOffsetCheckBoxMenuItem.setText("Show offset");
|
||||
cursorPositionShowOffsetCheckBoxMenuItem.setName("cursorPositionShowOffsetCheckBoxMenuItem");
|
||||
cursorPositionShowOffsetCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cursorPositionShowOffsetCheckBoxMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
positionPopupMenu.add(cursorPositionShowOffsetCheckBoxMenuItem);
|
||||
|
||||
jSeparator2.setName("jSeparator2");
|
||||
positionPopupMenu.add(jSeparator2);
|
||||
|
||||
positionCopyMenuItem.setText("Copy");
|
||||
positionCopyMenuItem.setName("positionCopyMenuItem");
|
||||
positionCopyMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
positionCopyMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
positionPopupMenu.add(positionCopyMenuItem);
|
||||
|
||||
positionGoToMenuItem.setText("Go To...");
|
||||
positionGoToMenuItem.setEnabled(false);
|
||||
positionGoToMenuItem.setName("positionGoToMenuItem");
|
||||
positionGoToMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
positionGoToMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
positionPopupMenu.add(positionGoToMenuItem);
|
||||
|
||||
documentSizePopupMenu.setName("documentSizePopupMenu");
|
||||
|
||||
documentSizeCodeTypeMenu.setText("Code Type");
|
||||
documentSizeCodeTypeMenu.setName("documentSizeCodeTypeMenu");
|
||||
|
||||
documentSizeModeButtonGroup.add(octalDocumentSizeModeRadioButtonMenuItem);
|
||||
octalDocumentSizeModeRadioButtonMenuItem.setText("Show as octal");
|
||||
octalDocumentSizeModeRadioButtonMenuItem.setName("octalDocumentSizeModeRadioButtonMenuItem");
|
||||
octalDocumentSizeModeRadioButtonMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
octalDocumentSizeModeRadioButtonMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
documentSizeCodeTypeMenu.add(octalDocumentSizeModeRadioButtonMenuItem);
|
||||
|
||||
documentSizeModeButtonGroup.add(decimalDocumentSizeModeRadioButtonMenuItem);
|
||||
decimalDocumentSizeModeRadioButtonMenuItem.setText("Show as decimal");
|
||||
decimalDocumentSizeModeRadioButtonMenuItem.setName("decimalDocumentSizeModeRadioButtonMenuItem");
|
||||
decimalDocumentSizeModeRadioButtonMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
decimalDocumentSizeModeRadioButtonMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
documentSizeCodeTypeMenu.add(decimalDocumentSizeModeRadioButtonMenuItem);
|
||||
|
||||
documentSizeModeButtonGroup.add(hexadecimalDocumentSizeModeRadioButtonMenuItem);
|
||||
hexadecimalDocumentSizeModeRadioButtonMenuItem.setText("Show as hexadecimal");
|
||||
hexadecimalDocumentSizeModeRadioButtonMenuItem.setName("hexadecimalDocumentSizeModeRadioButtonMenuItem");
|
||||
hexadecimalDocumentSizeModeRadioButtonMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
hexadecimalDocumentSizeModeRadioButtonMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
documentSizeCodeTypeMenu.add(hexadecimalDocumentSizeModeRadioButtonMenuItem);
|
||||
|
||||
documentSizePopupMenu.add(documentSizeCodeTypeMenu);
|
||||
|
||||
documentSizeShowRelativeCheckBoxMenuItem.setSelected(true);
|
||||
documentSizeShowRelativeCheckBoxMenuItem.setText("Show relative size");
|
||||
documentSizeShowRelativeCheckBoxMenuItem.setName("documentSizeShowRelativeCheckBoxMenuItem");
|
||||
documentSizeShowRelativeCheckBoxMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
documentSizeShowRelativeCheckBoxMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
documentSizePopupMenu.add(documentSizeShowRelativeCheckBoxMenuItem);
|
||||
|
||||
jSeparator1.setName("jSeparator1");
|
||||
documentSizePopupMenu.add(jSeparator1);
|
||||
|
||||
documentSizeCopyMenuItem.setText("Copy");
|
||||
documentSizeCopyMenuItem.setName("documentSizeCopyMenuItem");
|
||||
documentSizeCopyMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
documentSizeCopyMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
documentSizePopupMenu.add(documentSizeCopyMenuItem);
|
||||
|
||||
setName("Form");
|
||||
|
||||
documentSizeLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
documentSizeLabel.setText("0 (0)");
|
||||
documentSizeLabel.setToolTipText("Document size");
|
||||
documentSizeLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
documentSizeLabel.setComponentPopupMenu(documentSizePopupMenu);
|
||||
documentSizeLabel.setName("documentSizeLabel");
|
||||
|
||||
cursorPositionLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
cursorPositionLabel.setText("0:0");
|
||||
cursorPositionLabel.setToolTipText("Cursor position");
|
||||
cursorPositionLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
cursorPositionLabel.setComponentPopupMenu(positionPopupMenu);
|
||||
cursorPositionLabel.setName("cursorPositionLabel");
|
||||
cursorPositionLabel.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
cursorPositionLabelMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
|
||||
editModeLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
editModeLabel.setText("OVR");
|
||||
editModeLabel.setToolTipText("Edit mode");
|
||||
editModeLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
editModeLabel.setName("editModeLabel");
|
||||
editModeLabel.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
editModeLabelMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
|
||||
encodingLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
|
||||
encodingLabel.setText("UTF-8");
|
||||
encodingLabel.setToolTipText("Active encoding");
|
||||
encodingLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
encodingLabel.setName("encodingLabel");
|
||||
encodingLabel.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mousePressed(java.awt.event.MouseEvent evt) {
|
||||
encodingLabelMousePressed(evt);
|
||||
}
|
||||
public void mouseReleased(java.awt.event.MouseEvent evt) {
|
||||
encodingLabelMouseReleased(evt);
|
||||
}
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
encodingLabelMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap(195, Short.MAX_VALUE)
|
||||
.addComponent(encodingLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 148, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(documentSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(cursorPositionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(editModeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(editModeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(documentSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(cursorPositionLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(encodingLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void editModeLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_editModeLabelMouseClicked
|
||||
// if (statusControlHandler != null && evt.getButton() == MouseEvent.BUTTON1) {
|
||||
// if (editOperation == EditOperation.INSERT) {
|
||||
// statusControlHandler.changeEditOperation(EditOperation.OVERWRITE);
|
||||
// } else if (editOperation == EditOperation.OVERWRITE) {
|
||||
// statusControlHandler.changeEditOperation(EditOperation.INSERT);
|
||||
// }
|
||||
// }
|
||||
}//GEN-LAST:event_editModeLabelMouseClicked
|
||||
|
||||
private void cursorPositionLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cursorPositionLabelMouseClicked
|
||||
if (evt.getButton() == MouseEvent.BUTTON1 && evt.getClickCount() > 1) {
|
||||
// statusControlHandler.changeCursorPosition();
|
||||
}
|
||||
}//GEN-LAST:event_cursorPositionLabelMouseClicked
|
||||
|
||||
private void positionGoToMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_positionGoToMenuItemActionPerformed
|
||||
// statusControlHandler.changeCursorPosition();
|
||||
}//GEN-LAST:event_positionGoToMenuItemActionPerformed
|
||||
|
||||
private void positionCopyMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_positionCopyMenuItemActionPerformed
|
||||
try {
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(new StringSelection(cursorPositionLabel.getText()), null);
|
||||
} catch (IllegalStateException ex) {
|
||||
// ignore issues with clipboard
|
||||
}
|
||||
}//GEN-LAST:event_positionCopyMenuItemActionPerformed
|
||||
|
||||
private void documentSizeCopyMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentSizeCopyMenuItemActionPerformed
|
||||
try {
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(new StringSelection(documentSizeLabel.getText()), null);
|
||||
} catch (IllegalStateException ex) {
|
||||
// ignore issues with clipboard
|
||||
}
|
||||
}//GEN-LAST:event_documentSizeCopyMenuItemActionPerformed
|
||||
|
||||
private void encodingLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_encodingLabelMouseClicked
|
||||
if (evt.getButton() == MouseEvent.BUTTON1) {
|
||||
// Not supported
|
||||
} else {
|
||||
handleEncodingPopup(evt);
|
||||
}
|
||||
}//GEN-LAST:event_encodingLabelMouseClicked
|
||||
|
||||
private void encodingLabelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_encodingLabelMousePressed
|
||||
handleEncodingPopup(evt);
|
||||
}//GEN-LAST:event_encodingLabelMousePressed
|
||||
|
||||
private void encodingLabelMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_encodingLabelMouseReleased
|
||||
handleEncodingPopup(evt);
|
||||
}//GEN-LAST:event_encodingLabelMouseReleased
|
||||
|
||||
private void cursorPositionShowOffsetCheckBoxMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cursorPositionShowOffsetCheckBoxMenuItemActionPerformed
|
||||
cursorPositionFormat.setShowOffset(cursorPositionShowOffsetCheckBoxMenuItem.isSelected());
|
||||
updateCaretPosition();
|
||||
}//GEN-LAST:event_cursorPositionShowOffsetCheckBoxMenuItemActionPerformed
|
||||
|
||||
private void documentSizeShowRelativeCheckBoxMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_documentSizeShowRelativeCheckBoxMenuItemActionPerformed
|
||||
documentSizeFormat.setShowRelative(documentSizeShowRelativeCheckBoxMenuItem.isSelected());
|
||||
updateDocumentSize();
|
||||
updateDocumentSizeToolTip();
|
||||
}//GEN-LAST:event_documentSizeShowRelativeCheckBoxMenuItemActionPerformed
|
||||
|
||||
private void octalCursorPositionModeRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_octalCursorPositionModeRadioButtonMenuItemActionPerformed
|
||||
cursorPositionFormat.setCodeType(PositionCodeType.OCTAL);
|
||||
updateCaretPosition();
|
||||
}//GEN-LAST:event_octalCursorPositionModeRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void decimalCursorPositionModeRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_decimalCursorPositionModeRadioButtonMenuItemActionPerformed
|
||||
cursorPositionFormat.setCodeType(PositionCodeType.DECIMAL);
|
||||
updateCaretPosition();
|
||||
}//GEN-LAST:event_decimalCursorPositionModeRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void hexadecimalCursorPositionModeRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hexadecimalCursorPositionModeRadioButtonMenuItemActionPerformed
|
||||
cursorPositionFormat.setCodeType(PositionCodeType.HEXADECIMAL);
|
||||
updateCaretPosition();
|
||||
}//GEN-LAST:event_hexadecimalCursorPositionModeRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void octalDocumentSizeModeRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_octalDocumentSizeModeRadioButtonMenuItemActionPerformed
|
||||
documentSizeFormat.setCodeType(PositionCodeType.OCTAL);
|
||||
updateDocumentSize();
|
||||
}//GEN-LAST:event_octalDocumentSizeModeRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void decimalDocumentSizeModeRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_decimalDocumentSizeModeRadioButtonMenuItemActionPerformed
|
||||
documentSizeFormat.setCodeType(PositionCodeType.DECIMAL);
|
||||
updateDocumentSize();
|
||||
}//GEN-LAST:event_decimalDocumentSizeModeRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void hexadecimalDocumentSizeModeRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hexadecimalDocumentSizeModeRadioButtonMenuItemActionPerformed
|
||||
documentSizeFormat.setCodeType(PositionCodeType.HEXADECIMAL);
|
||||
updateDocumentSize();
|
||||
}//GEN-LAST:event_hexadecimalDocumentSizeModeRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void handleEncodingPopup(java.awt.event.MouseEvent evt) {
|
||||
if (evt.isPopupTrigger()) {
|
||||
// Not supported
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorPosition(CodeAreaCaretPosition caretPosition) {
|
||||
this.caretPosition = caretPosition;
|
||||
updateCaretPosition();
|
||||
updateCursorPositionToolTip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectionRange(SelectionRange selectionRange) {
|
||||
this.selectionRange = selectionRange;
|
||||
updateCaretPosition();
|
||||
updateCursorPositionToolTip();
|
||||
updateDocumentSize();
|
||||
updateDocumentSizeToolTip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentDocumentSize(long documentSize, long initialDocumentSize) {
|
||||
this.documentSize = documentSize;
|
||||
this.initialDocumentSize = initialDocumentSize;
|
||||
updateDocumentSize();
|
||||
updateDocumentSizeToolTip();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getEncoding() {
|
||||
return encodingLabel.getText();
|
||||
}
|
||||
|
||||
public void setEncoding(String encodingName) {
|
||||
encodingLabel.setText(encodingName + " ^");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEditMode(EditMode editMode, EditOperation editOperation) {
|
||||
this.editOperation = editOperation;
|
||||
switch (editMode) {
|
||||
case READ_ONLY: {
|
||||
editModeLabel.setText(READONLY_EDIT_MODE_LABEL);
|
||||
break;
|
||||
}
|
||||
case EXPANDING:
|
||||
case CAPPED: {
|
||||
switch (editOperation) {
|
||||
case INSERT: {
|
||||
editModeLabel.setText(INSERT_EDIT_MODE_LABEL);
|
||||
break;
|
||||
}
|
||||
case OVERWRITE: {
|
||||
editModeLabel.setText(OVERWRITE_EDIT_MODE_LABEL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CodeAreaUtils.getInvalidTypeException(editOperation);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INPLACE: {
|
||||
editModeLabel.setText(INPLACE_EDIT_MODE_LABEL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CodeAreaUtils.getInvalidTypeException(editMode);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCaretPosition() {
|
||||
if (caretPosition == null) {
|
||||
cursorPositionLabel.setText("-");
|
||||
} else {
|
||||
StringBuilder labelBuilder = new StringBuilder();
|
||||
if (selectionRange != null && !selectionRange.isEmpty()) {
|
||||
long first = selectionRange.getFirst();
|
||||
long last = selectionRange.getLast();
|
||||
labelBuilder.append(numberToPosition(first, cursorPositionFormat.getCodeType()));
|
||||
labelBuilder.append(" to ");
|
||||
labelBuilder.append(numberToPosition(last, cursorPositionFormat.getCodeType()));
|
||||
} else {
|
||||
labelBuilder.append(numberToPosition(caretPosition.getDataPosition(), cursorPositionFormat.getCodeType()));
|
||||
if (cursorPositionFormat.isShowOffset()) {
|
||||
labelBuilder.append(":");
|
||||
labelBuilder.append(caretPosition.getCodeOffset());
|
||||
}
|
||||
}
|
||||
cursorPositionLabel.setText(labelBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCursorPositionToolTip() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<html>");
|
||||
if (caretPosition == null) {
|
||||
builder.append("Cursor position");
|
||||
} else {
|
||||
if (selectionRange != null && !selectionRange.isEmpty()) {
|
||||
long first = selectionRange.getFirst();
|
||||
long last = selectionRange.getLast();
|
||||
builder.append("Selection from<br>");
|
||||
builder.append(OCTAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(first, PositionCodeType.OCTAL)).append("<br>");
|
||||
builder.append(DECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(first, PositionCodeType.DECIMAL)).append("<br>");
|
||||
builder.append(HEXADECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(first, PositionCodeType.HEXADECIMAL)).append("<br>");
|
||||
builder.append("<br>");
|
||||
builder.append("Selection to<br>");
|
||||
builder.append(OCTAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(last, PositionCodeType.OCTAL)).append("<br>");
|
||||
builder.append(DECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(last, PositionCodeType.DECIMAL)).append("<br>");
|
||||
builder.append(HEXADECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(first, PositionCodeType.HEXADECIMAL)).append("<br>");
|
||||
} else {
|
||||
long dataPosition = caretPosition.getDataPosition();
|
||||
builder.append("Cursor position<br>");
|
||||
builder.append(OCTAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(dataPosition, PositionCodeType.OCTAL)).append("<br>");
|
||||
builder.append(DECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(dataPosition, PositionCodeType.DECIMAL)).append("<br>");
|
||||
builder.append(HEXADECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(dataPosition, PositionCodeType.HEXADECIMAL));
|
||||
builder.append("</html>");
|
||||
}
|
||||
}
|
||||
|
||||
cursorPositionLabel.setToolTipText(builder.toString());
|
||||
}
|
||||
|
||||
private void updateDocumentSize() {
|
||||
if (documentSize == -1) {
|
||||
documentSizeLabel.setText(documentSizeFormat.isShowRelative() ? "0 (0)" : "0");
|
||||
} else {
|
||||
StringBuilder labelBuilder = new StringBuilder();
|
||||
if (selectionRange != null && !selectionRange.isEmpty()) {
|
||||
labelBuilder.append(numberToPosition(selectionRange.getLength(), documentSizeFormat.getCodeType()));
|
||||
labelBuilder.append(" of ");
|
||||
labelBuilder.append(numberToPosition(documentSize, documentSizeFormat.getCodeType()));
|
||||
} else {
|
||||
labelBuilder.append(numberToPosition(documentSize, documentSizeFormat.getCodeType()));
|
||||
if (documentSizeFormat.isShowRelative()) {
|
||||
long difference = documentSize - initialDocumentSize;
|
||||
labelBuilder.append(difference > 0 ? " (+" : " (");
|
||||
labelBuilder.append(numberToPosition(difference, documentSizeFormat.getCodeType()));
|
||||
labelBuilder.append(")");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
documentSizeLabel.setText(labelBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDocumentSizeToolTip() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<html>");
|
||||
if (selectionRange != null && !selectionRange.isEmpty()) {
|
||||
long length = selectionRange.getLength();
|
||||
builder.append("Selection length<br>");
|
||||
builder.append(OCTAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(length, PositionCodeType.OCTAL)).append("<br>");
|
||||
builder.append(DECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(length, PositionCodeType.DECIMAL)).append("<br>");
|
||||
builder.append(HEXADECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(length, PositionCodeType.HEXADECIMAL)).append("<br>");
|
||||
builder.append("<br>");
|
||||
}
|
||||
|
||||
builder.append("Document size<br>");
|
||||
builder.append(OCTAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(documentSize, PositionCodeType.OCTAL)).append("<br>");
|
||||
builder.append(DECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(documentSize, PositionCodeType.DECIMAL)).append("<br>");
|
||||
builder.append(HEXADECIMAL_CODE_TYPE_LABEL + ": ").append(numberToPosition(documentSize, PositionCodeType.HEXADECIMAL));
|
||||
builder.append("</html>");
|
||||
documentSizeLabel.setToolTipText(builder.toString());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private String numberToPosition(long value, PositionCodeType codeType) {
|
||||
if (value == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
int spaceGroupSize = 0;
|
||||
switch (codeType) {
|
||||
case OCTAL: {
|
||||
spaceGroupSize = octalSpaceGroupSize;
|
||||
break;
|
||||
}
|
||||
case DECIMAL: {
|
||||
spaceGroupSize = decimalSpaceGroupSize;
|
||||
break;
|
||||
}
|
||||
case HEXADECIMAL: {
|
||||
spaceGroupSize = hexadecimalSpaceGroupSize;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw CodeAreaUtils.getInvalidTypeException(codeType);
|
||||
}
|
||||
|
||||
long remainder = value > 0 ? value : -value;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int base = codeType.getBase();
|
||||
int groupSize = spaceGroupSize == 0 ? -1 : spaceGroupSize;
|
||||
while (remainder > 0) {
|
||||
if (groupSize >= 0) {
|
||||
if (groupSize == 0) {
|
||||
builder.insert(0, ' ');
|
||||
groupSize = spaceGroupSize - 1;
|
||||
} else {
|
||||
groupSize--;
|
||||
}
|
||||
}
|
||||
|
||||
int digit = (int) (remainder % base);
|
||||
remainder = remainder / base;
|
||||
builder.insert(0, CodeAreaUtils.UPPER_HEX_CODES[digit]);
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
builder.insert(0, "-");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import org.exbin.auxiliary.paged_data.ByteArrayData;
|
||||
import org.exbin.bined.CodeAreaCaretPosition;
|
||||
import org.exbin.bined.CodeType;
|
||||
import org.exbin.bined.EditMode;
|
||||
import org.exbin.bined.RowWrappingMode;
|
||||
import org.exbin.bined.highlight.swing.HighlightNonAsciiCodeAreaPainter;
|
||||
import org.exbin.bined.swing.basic.CodeArea;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
/**
|
||||
* Binary/hexadecimal viewer based on BinEd library.
|
||||
*
|
||||
* @author hajdam
|
||||
*/
|
||||
public class HexViewer extends JPanel {
|
||||
|
||||
private final CodeArea codeArea;
|
||||
private final JToolBar toolBar;
|
||||
private final BinaryStatusPanel statusPanel;
|
||||
private final ValuesPanel valuesPanel;
|
||||
private JPanel codeAreaPanel;
|
||||
private JScrollPane valuesPanelScrollBar;
|
||||
private boolean valuesPanelVisible = false;
|
||||
|
||||
private final AbstractAction cycleCodeTypesAction;
|
||||
private javax.swing.JToggleButton lineWrappingToggleButton;
|
||||
private JButton cycleCodeTypeButton;
|
||||
private BinaryStatusApi binaryStatus;
|
||||
|
||||
public HexViewer(byte[] contentData) {
|
||||
super(new BorderLayout());
|
||||
codeArea = new CodeArea();
|
||||
codeArea.setPainter(new HighlightNonAsciiCodeAreaPainter(codeArea));
|
||||
toolBar = new JToolBar();
|
||||
statusPanel = new BinaryStatusPanel();
|
||||
valuesPanel = new ValuesPanel();
|
||||
codeArea.setContentData(new ByteArrayData(contentData));
|
||||
codeArea.setEditMode(EditMode.READ_ONLY);
|
||||
|
||||
cycleCodeTypesAction = new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int codeTypePos = codeArea.getCodeType().ordinal();
|
||||
CodeType[] values = CodeType.values();
|
||||
CodeType next = codeTypePos + 1 >= values.length ? values[0] : values[codeTypePos + 1];
|
||||
codeArea.setCodeType(next);
|
||||
updateCycleButtonState();
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
cycleCodeTypesAction.putValue(Action.SHORT_DESCRIPTION, "Cycle through code types");
|
||||
|
||||
cycleCodeTypeButton = new JButton();
|
||||
cycleCodeTypeButton.setAction(cycleCodeTypesAction);
|
||||
updateCycleButtonState();
|
||||
toolBar.add(cycleCodeTypeButton);
|
||||
lineWrappingToggleButton = new javax.swing.JToggleButton();
|
||||
lineWrappingToggleButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/the/bytecode/club/bytecodeviewer/gui/hexviewer/resources/bined-linewrap.png")));
|
||||
lineWrappingToggleButton.setToolTipText("Toggle line wrapping");
|
||||
lineWrappingToggleButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
if (codeArea.getRowWrapping() == RowWrappingMode.WRAPPING) {
|
||||
codeArea.setMaxBytesPerRow(16);
|
||||
codeArea.setRowWrapping(RowWrappingMode.NO_WRAPPING);
|
||||
} else {
|
||||
codeArea.setMaxBytesPerRow(0);
|
||||
codeArea.setRowWrapping(RowWrappingMode.WRAPPING);
|
||||
}
|
||||
}
|
||||
});
|
||||
toolBar.add(lineWrappingToggleButton);
|
||||
|
||||
add(toolBar, BorderLayout.NORTH);
|
||||
|
||||
codeAreaPanel = new JPanel(new BorderLayout());
|
||||
codeAreaPanel.add(codeArea, BorderLayout.CENTER);
|
||||
codeArea.setComponentPopupMenu(new JPopupMenu() {
|
||||
@Override
|
||||
public void show(Component invoker, int x, int y) {
|
||||
int clickedX = x;
|
||||
int clickedY = y;
|
||||
if (invoker instanceof JViewport) {
|
||||
clickedX += ((JViewport) invoker).getParent().getX();
|
||||
clickedY += ((JViewport) invoker).getParent().getY();
|
||||
}
|
||||
|
||||
removeAll();
|
||||
final JPopupMenu menu = createPopupMenu(clickedX, clickedY);
|
||||
menu.show(invoker, x, y);
|
||||
}
|
||||
});
|
||||
|
||||
valuesPanelScrollBar = new JScrollPane();
|
||||
valuesPanel.setCodeArea(codeArea);
|
||||
valuesPanel.updateValues();
|
||||
valuesPanelScrollBar.setViewportView(valuesPanel);
|
||||
valuesPanelScrollBar.setMinimumSize(new Dimension(10, valuesPanel.getMinimumSize().height));
|
||||
setShowValuesPanel(true);
|
||||
add(codeAreaPanel, BorderLayout.CENTER);
|
||||
|
||||
registerBinaryStatus(statusPanel);
|
||||
add(statusPanel, BorderLayout.SOUTH);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void setShowValuesPanel(boolean show) {
|
||||
if (valuesPanelVisible != show) {
|
||||
if (show) {
|
||||
codeAreaPanel.add(valuesPanelScrollBar, BorderLayout.SOUTH);
|
||||
codeAreaPanel.revalidate();
|
||||
codeAreaPanel.repaint();
|
||||
valuesPanelVisible = true;
|
||||
valuesPanel.enableUpdate();
|
||||
} else {
|
||||
valuesPanel.disableUpdate();
|
||||
codeAreaPanel.remove(valuesPanelScrollBar);
|
||||
codeAreaPanel.revalidate();
|
||||
codeAreaPanel.repaint();
|
||||
valuesPanelVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerBinaryStatus(BinaryStatusApi binaryStatusApi) {
|
||||
this.binaryStatus = binaryStatusApi;
|
||||
codeArea.addCaretMovedListener((CodeAreaCaretPosition caretPosition) -> {
|
||||
binaryStatus.setCursorPosition(caretPosition);
|
||||
});
|
||||
codeArea.addSelectionChangedListener(() -> {
|
||||
binaryStatus.setSelectionRange(codeArea.getSelection());
|
||||
});
|
||||
codeArea.addDataChangedListener(() -> {
|
||||
binaryStatus.setCurrentDocumentSize(codeArea.getDataSize(), codeArea.getDataSize());
|
||||
});
|
||||
binaryStatus.setCurrentDocumentSize(codeArea.getDataSize(), codeArea.getDataSize());
|
||||
|
||||
codeArea.addEditModeChangedListener(binaryStatus::setEditMode);
|
||||
binaryStatus.setEditMode(codeArea.getEditMode(), codeArea.getActiveOperation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns platform specific down mask filter.
|
||||
*
|
||||
* @return down mask for meta keys
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static int getMetaMask() {
|
||||
try {
|
||||
switch (java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) {
|
||||
case java.awt.Event.META_MASK:
|
||||
return KeyEvent.META_DOWN_MASK;
|
||||
case java.awt.Event.SHIFT_MASK:
|
||||
return KeyEvent.SHIFT_DOWN_MASK;
|
||||
case java.awt.Event.ALT_MASK:
|
||||
return KeyEvent.ALT_DOWN_MASK;
|
||||
default:
|
||||
return KeyEvent.CTRL_DOWN_MASK;
|
||||
}
|
||||
} catch (java.awt.HeadlessException ex) {
|
||||
return KeyEvent.CTRL_DOWN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private JPopupMenu createPopupMenu(int x, int y) {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
|
||||
JMenu viewMenu = new JMenu("View");
|
||||
JMenu codeTypeMenu = new JMenu("Code Type");
|
||||
ButtonGroup codeTypeButtonGroup = new ButtonGroup();
|
||||
JRadioButtonMenuItem binaryCodeTypeMenuItem = new JRadioButtonMenuItem(new AbstractAction("Binary") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
codeArea.setCodeType(CodeType.BINARY);
|
||||
updateCycleButtonState();
|
||||
menu.setVisible(false);
|
||||
}
|
||||
});
|
||||
codeTypeButtonGroup.add(binaryCodeTypeMenuItem);
|
||||
JRadioButtonMenuItem octalCodeTypeMenuItem = new JRadioButtonMenuItem(new AbstractAction("Octal") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
codeArea.setCodeType(CodeType.OCTAL);
|
||||
updateCycleButtonState();
|
||||
menu.setVisible(false);
|
||||
}
|
||||
});
|
||||
codeTypeButtonGroup.add(octalCodeTypeMenuItem);
|
||||
JRadioButtonMenuItem decimalCodeTypeMenuItem = new JRadioButtonMenuItem(new AbstractAction("Decimal") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
codeArea.setCodeType(CodeType.DECIMAL);
|
||||
updateCycleButtonState();
|
||||
menu.setVisible(false);
|
||||
}
|
||||
});
|
||||
codeTypeButtonGroup.add(decimalCodeTypeMenuItem);
|
||||
JRadioButtonMenuItem hexadecimalCodeTypeMenuItem = new JRadioButtonMenuItem(new AbstractAction("Hexadecimal") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
codeArea.setCodeType(CodeType.HEXADECIMAL);
|
||||
updateCycleButtonState();
|
||||
menu.setVisible(false);
|
||||
}
|
||||
});
|
||||
codeTypeButtonGroup.add(hexadecimalCodeTypeMenuItem);
|
||||
codeTypeMenu.add(binaryCodeTypeMenuItem);
|
||||
codeTypeMenu.add(octalCodeTypeMenuItem);
|
||||
codeTypeMenu.add(decimalCodeTypeMenuItem);
|
||||
codeTypeMenu.add(hexadecimalCodeTypeMenuItem);
|
||||
switch (codeArea.getCodeType()) {
|
||||
case BINARY: {
|
||||
binaryCodeTypeMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case OCTAL: {
|
||||
octalCodeTypeMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case DECIMAL: {
|
||||
decimalCodeTypeMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
case HEXADECIMAL: {
|
||||
hexadecimalCodeTypeMenuItem.setSelected(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
viewMenu.add(codeTypeMenu);
|
||||
JCheckBoxMenuItem showValuesPanelMenuItem = new JCheckBoxMenuItem("Show values panel");
|
||||
showValuesPanelMenuItem.setSelected(valuesPanelVisible);
|
||||
showValuesPanelMenuItem.addActionListener((event) -> {
|
||||
setShowValuesPanel(showValuesPanelMenuItem.isSelected());
|
||||
menu.setVisible(false);
|
||||
});
|
||||
viewMenu.add(showValuesPanelMenuItem);
|
||||
JCheckBoxMenuItem codeColorizationMenuItem = new JCheckBoxMenuItem("Code Colorization");
|
||||
codeColorizationMenuItem.setSelected(((HighlightNonAsciiCodeAreaPainter) codeArea.getPainter()).isNonAsciiHighlightingEnabled());
|
||||
codeColorizationMenuItem.addActionListener((event) -> {
|
||||
((HighlightNonAsciiCodeAreaPainter) codeArea.getPainter()).setNonAsciiHighlightingEnabled(codeColorizationMenuItem.isSelected());
|
||||
menu.setVisible(false);
|
||||
});
|
||||
viewMenu.add(codeColorizationMenuItem);
|
||||
menu.add(viewMenu);
|
||||
|
||||
final JMenuItem copyMenuItem = new JMenuItem("Copy");
|
||||
copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, HexViewer.getMetaMask()));
|
||||
copyMenuItem.setEnabled(codeArea.hasSelection());
|
||||
copyMenuItem.addActionListener((ActionEvent e) -> {
|
||||
codeArea.copy();
|
||||
});
|
||||
menu.add(copyMenuItem);
|
||||
|
||||
final JMenuItem selectAllMenuItem = new JMenuItem("Select All");
|
||||
selectAllMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, HexViewer.getMetaMask()));
|
||||
selectAllMenuItem.addActionListener((ActionEvent e) -> {
|
||||
codeArea.selectAll();
|
||||
});
|
||||
menu.add(selectAllMenuItem);
|
||||
return menu;
|
||||
}
|
||||
|
||||
private void updateCycleButtonState() {
|
||||
CodeType codeType = codeArea.getCodeType();
|
||||
cycleCodeTypeButton.setText(codeType.name().substring(0, 3));
|
||||
}
|
||||
}
|
|
@ -1,346 +0,0 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
|
||||
/**
|
||||
* @author laullon
|
||||
* @since 08/04/2003
|
||||
*/
|
||||
|
||||
public class JHexEditor extends JPanel implements FocusListener, AdjustmentListener, MouseWheelListener
|
||||
{
|
||||
protected int textLength = 16;
|
||||
protected int lastWidth;
|
||||
|
||||
byte[] buf;
|
||||
public int cursor;
|
||||
public Font font;
|
||||
protected int border = 2;
|
||||
public boolean DEBUG = false;
|
||||
private final JScrollBar sb;
|
||||
private int begin = 0;
|
||||
private int lines = 10;
|
||||
private final JHexEditorHEX hex;
|
||||
private final JHexEditorASCII ascii;
|
||||
|
||||
public JHexEditor(byte[] buff)
|
||||
{
|
||||
super();
|
||||
|
||||
this.buf = buff;
|
||||
this.font = new Font(Font.MONOSPACED, Font.PLAIN, BytecodeViewer.viewer.getFontSize());
|
||||
|
||||
checkSize();
|
||||
|
||||
this.addMouseWheelListener(this);
|
||||
|
||||
sb = new JScrollBar(JScrollBar.VERTICAL);
|
||||
sb.addAdjustmentListener(this);
|
||||
sb.setMinimum(0);
|
||||
sb.setMaximum(buff.length / getLines());
|
||||
|
||||
JPanel p1, p2, p3;
|
||||
// HEX Editor
|
||||
hex = new JHexEditorHEX(this);
|
||||
p1 = new JPanel(new BorderLayout(1, 1));
|
||||
p1.add(hex, BorderLayout.CENTER);
|
||||
p1.add(new Column(), BorderLayout.NORTH);
|
||||
|
||||
p2 = new JPanel(new BorderLayout(1, 1));
|
||||
p2.add(new Row(), BorderLayout.CENTER);
|
||||
p2.add(new Cell(), BorderLayout.NORTH);
|
||||
|
||||
// ASCII Editor
|
||||
ascii = new JHexEditorASCII(this);
|
||||
p3 = new JPanel(new BorderLayout(1, 1));
|
||||
p3.add(sb, BorderLayout.EAST);
|
||||
p3.add(ascii, BorderLayout.CENTER);
|
||||
p3.add(new Cell(), BorderLayout.NORTH);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout(1, 1));
|
||||
panel.add(p1, BorderLayout.CENTER);
|
||||
panel.add(p2, BorderLayout.WEST);
|
||||
panel.add(p3, BorderLayout.EAST);
|
||||
|
||||
this.setLayout(new BorderLayout(1, 1));
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
|
||||
//attach CTRL + Mouse Wheel Zoom
|
||||
SwingUtilities.invokeLater(this::attachCtrlMouseWheelZoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
checkSize();
|
||||
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
|
||||
Rectangle rec = this.getBounds();
|
||||
lines = (rec.height / fn.getHeight()) - 1;
|
||||
int n = (buf.length / textLength) - 1;
|
||||
if (lines > n) {
|
||||
lines = n;
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
sb.setValues(getBegin(), +getLines(), 0, buf.length / textLength);
|
||||
sb.setValueIsAdjusting(true);
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
public void attachCtrlMouseWheelZoom()
|
||||
{
|
||||
//get the existing scroll event
|
||||
MouseWheelListener ogListener = getMouseWheelListeners().length > 0 ?
|
||||
getMouseWheelListeners()[0] : null;
|
||||
|
||||
//remove the existing event
|
||||
if(ogListener != null)
|
||||
removeMouseWheelListener(ogListener);
|
||||
|
||||
//add a new event
|
||||
addMouseWheelListener(e ->
|
||||
{
|
||||
if ((e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0)
|
||||
{
|
||||
int size = font.getSize();
|
||||
|
||||
Font newFont;
|
||||
if (e.getWheelRotation() > 0) //Up
|
||||
newFont = new Font(font.getName(), font.getStyle(), --size >= 2 ? --size : 2);
|
||||
else //Down
|
||||
newFont = new Font(font.getName(), font.getStyle(), ++size);
|
||||
|
||||
setFont(newFont);
|
||||
hex.setFont(newFont);
|
||||
ascii.setFont(newFont);
|
||||
font = newFont;
|
||||
|
||||
e.consume();
|
||||
}
|
||||
else if(ogListener != null)
|
||||
{
|
||||
ogListener.mouseWheelMoved(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected int getBegin() {
|
||||
return begin;
|
||||
}
|
||||
|
||||
protected int getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
protected void background(Graphics g, int x, int y, int s) {
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
g.fillRect(((fn.stringWidth(" ") + 1) * x) + border,
|
||||
(fn.getHeight() * y) + border, ((fn.stringWidth(" ") + 1) * s),
|
||||
fn.getHeight() + 1);
|
||||
}
|
||||
|
||||
protected void border(Graphics g, int x, int y, int s) {
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
g.drawRect(((fn.stringWidth(" ") + 1) * x) + border,
|
||||
(fn.getHeight() * y) + border, ((fn.stringWidth(" ") + 1) * s),
|
||||
fn.getHeight() + 1);
|
||||
}
|
||||
|
||||
protected void printString(Graphics graphics, String s, int x, int y) {
|
||||
Graphics2D g = (Graphics2D) graphics;
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g.drawString(s, ((fn.stringWidth(" ") + 1) * x) + border,
|
||||
((fn.getHeight() * (y + 1)) - fn.getMaxDescent()) + border);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
begin = e.getValue();
|
||||
if (begin < 0)
|
||||
begin = 0;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
begin += (e.getUnitsToScroll());
|
||||
if ((begin + lines) >= buf.length / textLength)
|
||||
begin = (buf.length / textLength) - lines;
|
||||
if (begin < 0)
|
||||
begin = 0;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
/* switch(e.getKeyCode()) { case 33: // rep if(cursor>=(16*lines))
|
||||
cursor-=(16*lines); refreshCursor(); break; case 34: // fin
|
||||
if(cursor<(buff.length-(16*lines))) cursor+=(16*lines);
|
||||
refreshCursor(); break; case 35: // fin cursor=buff.length-1;
|
||||
refreshCursor(); break; case 36: // ini cursor=0;
|
||||
refreshCursor(); break; case 37: // <-- if(cursor!=0) cursor--;
|
||||
refreshCursor(); break; case 38: // <-- if(cursor>15) cursor-=16;
|
||||
refreshCursor(); break; case 39: // --> if(cursor!=(buff.length-1))
|
||||
cursor++; refreshCursor(); break; case 40: // -->
|
||||
if(cursor<(buff.length-16)) cursor+=16; refreshCursor(); break; } */
|
||||
}
|
||||
|
||||
private class Column extends JPanel {
|
||||
private static final long serialVersionUID = -1734199617526339842L;
|
||||
|
||||
public Column() {
|
||||
this.setLayout(new BorderLayout(1, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
int h = fn.getHeight();
|
||||
int nl = 1;
|
||||
d.setSize(((fn.stringWidth(" ") + 1) * ((textLength * 3) - 1))
|
||||
+ (border * 2) + 1, h * nl + (border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.darkGray : Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
g.setFont(font);
|
||||
|
||||
for (int n = 0; n < textLength; n++) {
|
||||
if (n == (cursor % textLength))
|
||||
border(g, n * 3, 0, 2);
|
||||
String s = "00" + Integer.toHexString(n);
|
||||
s = s.substring(s.length() - 2);
|
||||
printString(g, s, n * 3, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Cell extends JPanel {
|
||||
private static final long serialVersionUID = -6124062720565016834L;
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
int h = fn.getHeight();
|
||||
d.setSize((fn.stringWidth(" ") + 1) + (border * 2) + 1, h
|
||||
+ (border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class Row extends JPanel {
|
||||
private static final long serialVersionUID = 8797347523486018051L;
|
||||
|
||||
public Row() {
|
||||
this.setLayout(new BorderLayout(1, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(font);
|
||||
int h = fn.getHeight();
|
||||
int nl = getLines();
|
||||
d.setSize((fn.stringWidth(" ") + 1) * (8) + (border * 2) + 1, h
|
||||
* nl + (border * 2) + 1);
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.darkGray : Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
g.setFont(font);
|
||||
|
||||
int ini = getBegin();
|
||||
int fin = ini + getLines();
|
||||
int y = 0;
|
||||
for (int n = ini; n < fin; n++)
|
||||
{
|
||||
if (n == (cursor / textLength))
|
||||
border(g, 0, y, 8);
|
||||
String s = "0000000000000" + Integer.toHexString(n);
|
||||
s = s.substring(s.length() - 8);
|
||||
printString(g, s, 0, y++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkSize()
|
||||
{
|
||||
int width = getWidth();
|
||||
|
||||
if(lastWidth != width)
|
||||
{
|
||||
double spacer = 1.5;
|
||||
textLength = (int) ((int) (width / 28.4)/spacer);
|
||||
lastWidth = width;
|
||||
hex.revalidate();
|
||||
ascii.revalidate();
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 2289328616534802372L;
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import javax.swing.JComponent;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
|
||||
/**
|
||||
* @author laullon
|
||||
* @since 09/04/2003
|
||||
*/
|
||||
|
||||
public class JHexEditorASCII extends JComponent implements MouseListener, KeyListener
|
||||
{
|
||||
private final JHexEditor he;
|
||||
|
||||
public JHexEditorASCII(JHexEditor he) {
|
||||
this.he = he;
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(he);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
debug("getPreferredSize()");
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
debug("getMinimumSize()");
|
||||
|
||||
Dimension d = new Dimension();
|
||||
FontMetrics fn = getFontMetrics(he.font);
|
||||
int w = fn.stringWidth(" ");
|
||||
int h = fn.getHeight();
|
||||
int nl = he.getLines();
|
||||
int len = he.textLength + 1;
|
||||
|
||||
int width = (len * w) + (he.border * 2) + 5;
|
||||
|
||||
//trim inaccuracy
|
||||
if(len > 16)
|
||||
{
|
||||
int diff = 16-len;
|
||||
width += ((len * w) / (diff) * diff);
|
||||
}
|
||||
|
||||
//System.out.println("Values: " + w + " and " + nl + " vs " + len + " ["+width+"]");
|
||||
|
||||
d.setSize(width, h * nl + (he.border * 2) + 1);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
debug("paint(" + g + ")");
|
||||
debug("cursor=" + he.cursor + " buff.length=" + he.buf.length);
|
||||
Dimension d = getMinimumSize();
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.darkGray : Color.white);
|
||||
g.fillRect(0, 0, d.width, d.height);
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
|
||||
g.setFont(he.font);
|
||||
|
||||
// ASCII data
|
||||
int start = he.getBegin() * he.textLength;
|
||||
int stop = start + (he.getLines() * he.textLength);
|
||||
if (stop > he.buf.length)
|
||||
stop = he.buf.length;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for (int n = start; n < stop; n++) {
|
||||
if (n == he.cursor) {
|
||||
g.setColor(Color.blue);
|
||||
if (hasFocus())
|
||||
he.background(g, x, y, 1);
|
||||
else
|
||||
he.border(g, x, y, 1);
|
||||
if (hasFocus())
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.black : Color.white);
|
||||
else
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
} else {
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
}
|
||||
|
||||
String s = String.valueOf((char) (he.buf[n] & 0xFF));//"" + new Character((char) he.buff[n]);
|
||||
if ((he.buf[n] < 20) || (he.buf[n] > 126))
|
||||
s = ".";//"" + (char) 16;
|
||||
he.printString(g, s, (x++), y);
|
||||
if (x == he.textLength) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void debug(String s) {
|
||||
if (he.DEBUG)
|
||||
System.out.println("JHexEditorASCII ==> " + s);
|
||||
}
|
||||
|
||||
public int calculateMousePosition(int x, int y) {
|
||||
FontMetrics fn = getFontMetrics(he.font);
|
||||
x = x / (fn.stringWidth(" ") + 1);
|
||||
y = y / fn.getHeight();
|
||||
debug("x=" + x + " ,y=" + y);
|
||||
return x + ((y + he.getBegin()) * he.textLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
debug("mouseClicked(" + e + ")");
|
||||
he.cursor = calculateMousePosition(e.getX(), e.getY());
|
||||
this.requestFocus();
|
||||
he.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
// KeyListener
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
/*
|
||||
* debug("keyTyped("+e+")");
|
||||
*
|
||||
* he.buff[he.cursor]=(byte)e.getKeyChar();
|
||||
*
|
||||
* if(he.cursor!=(he.buff.length-1)) he.cursor++; he.repaint();
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
debug("keyPressed(" + e + ")");
|
||||
he.keyPressed(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
debug("keyReleased(" + e + ")");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isFocusTraversable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFocusable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 5505374841731053461L;
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import javax.swing.JComponent;
|
||||
import the.bytecode.club.bytecodeviewer.Configuration;
|
||||
|
||||
/**
|
||||
* @author laullon
|
||||
* @since 09/04/2003
|
||||
*/
|
||||
|
||||
public class JHexEditorHEX extends JComponent implements MouseListener, KeyListener
|
||||
{
|
||||
private final JHexEditor he;
|
||||
|
||||
public JHexEditorHEX(JHexEditor he)
|
||||
{
|
||||
this.he = he;
|
||||
addMouseListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(he);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize()
|
||||
{
|
||||
debug("getMaximumSize()");
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
debug("paint(" + g + ")");
|
||||
debug("cursor=" + he.cursor + " buff.length=" + he.buf.length);
|
||||
|
||||
if(!Configuration.lafTheme.isDark())
|
||||
{
|
||||
//TODO if you want a background for the hex-text uncomment this
|
||||
//g.setColor(Color.white);
|
||||
//g.fillRect(0, 0, getWidth(), getHeight());
|
||||
g.setColor(Color.black);
|
||||
}
|
||||
else
|
||||
{
|
||||
g.setColor(Color.white);
|
||||
}
|
||||
|
||||
g.setFont(he.font);
|
||||
|
||||
int start = he.getBegin() * he.textLength;
|
||||
int stop = start + (he.getLines() * he.textLength);
|
||||
if (stop > he.buf.length)
|
||||
stop = he.buf.length;
|
||||
|
||||
// HEX data
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for (int n = start; n < stop; n++) {
|
||||
if (n == he.cursor) {
|
||||
if (hasFocus()) {
|
||||
g.setColor(Color.black);
|
||||
he.background(g, (x * 3), y, 2);
|
||||
g.setColor(Color.blue);
|
||||
int cursor = 0;
|
||||
he.background(g, (x * 3) + cursor, y, 1);
|
||||
} else {
|
||||
g.setColor(Color.blue);
|
||||
he.border(g, (x * 3), y, 2);
|
||||
}
|
||||
|
||||
if (hasFocus())
|
||||
g.setColor(Color.white);
|
||||
else
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
} else {
|
||||
g.setColor(Configuration.lafTheme.isDark() ? Color.white : Color.black);
|
||||
}
|
||||
|
||||
String s = ("0" + Integer.toHexString(he.buf[n]));
|
||||
s = s.substring(s.length() - 2);
|
||||
he.printString(g, s, ((x++) * 3), y);
|
||||
if (x == he.textLength) {
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void debug(String s) {
|
||||
if (he.DEBUG)
|
||||
System.out.println("JHexEditorHEX ==> " + s);
|
||||
}
|
||||
|
||||
public int calculateMousePosition(int x, int y) {
|
||||
FontMetrics fn = getFontMetrics(he.font);
|
||||
x = x / ((fn.stringWidth(" ") + 1) * 3);
|
||||
y = y / fn.getHeight();
|
||||
debug("x=" + x + " ,y=" + y);
|
||||
return x + ((y + he.getBegin()) * he.textLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
debug("mouseClicked(" + e + ")");
|
||||
he.cursor = calculateMousePosition(e.getX(), e.getY());
|
||||
this.requestFocus();
|
||||
he.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
// KeyListener
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
debug("keyTyped(" + e + ")");
|
||||
|
||||
/*
|
||||
* char c=e.getKeyChar();
|
||||
* if(((c>='0')&&(c<='9'))||((c>='A')&&(c<='F'))||((c>='a')&&(c<='f')))
|
||||
* { char[] str=new char[2]; String
|
||||
* n="00"+Integer.toHexString((int)he.buff[he.cursor]); if(n.length()>2)
|
||||
* n=n.substring(n.length()-2); str[1-cursor]=n.charAt(1-cursor);
|
||||
* str[cursor]=e.getKeyChar();
|
||||
* he.buff[he.cursor]=(byte)Integer.parseInt(new String(str),16);
|
||||
*
|
||||
* if(cursor!=1) cursor=1; else if(he.cursor!=(he.buff.length-1)){
|
||||
* he.cursor++; cursor=0;} he.refreshCursor(); }
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
debug("keyPressed(" + e + ")");
|
||||
he.keyPressed(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
debug("keyReleased(" + e + ")");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean isFocusTraversable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFocusable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1481995655372014571L;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.exbin.bined.PositionCodeType;
|
||||
|
||||
/**
|
||||
* Cursor position format for status.
|
||||
*
|
||||
* @author hajdam
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public class StatusCursorPositionFormat {
|
||||
|
||||
private PositionCodeType positionCodeType = PositionCodeType.DECIMAL;
|
||||
private boolean showOffset = true;
|
||||
|
||||
public StatusCursorPositionFormat() {
|
||||
}
|
||||
|
||||
public StatusCursorPositionFormat(PositionCodeType positionCodeType, boolean showOffset) {
|
||||
this.positionCodeType = positionCodeType;
|
||||
this.showOffset = showOffset;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public PositionCodeType getCodeType() {
|
||||
return positionCodeType;
|
||||
}
|
||||
|
||||
public void setCodeType(PositionCodeType positionCodeType) {
|
||||
this.positionCodeType = Objects.requireNonNull(positionCodeType);
|
||||
}
|
||||
|
||||
public boolean isShowOffset() {
|
||||
return showOffset;
|
||||
}
|
||||
|
||||
public void setShowOffset(boolean showOffset) {
|
||||
this.showOffset = showOffset;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.hexviewer;
|
||||
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import org.exbin.bined.PositionCodeType;
|
||||
|
||||
/**
|
||||
* Document size format for status.
|
||||
*
|
||||
* @author hajdam
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public class StatusDocumentSizeFormat {
|
||||
|
||||
private PositionCodeType positionCodeType = PositionCodeType.DECIMAL;
|
||||
private boolean showRelative = true;
|
||||
|
||||
public StatusDocumentSizeFormat() {
|
||||
|
||||
}
|
||||
|
||||
public StatusDocumentSizeFormat(PositionCodeType positionCodeType, boolean showRelative) {
|
||||
this.positionCodeType = positionCodeType;
|
||||
this.showRelative = showRelative;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public PositionCodeType getCodeType() {
|
||||
return positionCodeType;
|
||||
}
|
||||
|
||||
public void setCodeType(PositionCodeType positionCodeType) {
|
||||
this.positionCodeType = Objects.requireNonNull(positionCodeType);
|
||||
}
|
||||
|
||||
public boolean isShowRelative() {
|
||||
return showRelative;
|
||||
}
|
||||
|
||||
public void setShowRelative(boolean showRelativeSize) {
|
||||
this.showRelative = showRelativeSize;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@ import the.bytecode.club.bytecodeviewer.Configuration;
|
|||
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.ImageJLabel;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||
import the.bytecode.club.bytecodeviewer.gui.hexviewer.JHexEditor;
|
||||
import the.bytecode.club.bytecodeviewer.gui.hexviewer.HexViewer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.Resource;
|
||||
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.ResourceType;
|
||||
|
@ -97,7 +97,7 @@ public class FileViewer extends ResourceViewer
|
|||
|
||||
image = MiscUtils.loadImage(image, contents);
|
||||
if (image == null) {
|
||||
JHexEditor hex = new JHexEditor(contents);
|
||||
HexViewer hex = new HexViewer(contents);
|
||||
mainPanel.add(hex);
|
||||
return;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ public class FileViewer extends ResourceViewer
|
|||
//hex viewer
|
||||
else if (BytecodeViewer.viewer.forcePureAsciiAsText.isSelected() || hexViewerOnly)
|
||||
{
|
||||
JHexEditor hex = new JHexEditor(contents);
|
||||
HexViewer hex = new HexViewer(contents);
|
||||
mainPanel.add(hex);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import the.bytecode.club.bytecodeviewer.compilers.Compiler;
|
|||
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.MethodsRenderer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
|
||||
import the.bytecode.club.bytecodeviewer.gui.hexviewer.JHexEditor;
|
||||
import the.bytecode.club.bytecodeviewer.gui.hexviewer.HexViewer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel;
|
||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
|
||||
import the.bytecode.club.bytecodeviewer.util.MethodParser;
|
||||
|
@ -96,7 +96,7 @@ public class BytecodeViewPanelUpdater implements Runnable
|
|||
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
final JHexEditor hex = new JHexEditor(cw.toByteArray());
|
||||
final HexViewer hex = new HexViewer(cw.toByteArray());
|
||||
bytecodeViewPanel.add(hex);
|
||||
});
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 452 B |
Loading…
Reference in a new issue