JHexEditor replaced with BinEd Hexadecimal viewer library
This commit is contained in:
		
							parent
							
								
									ec6db5cd23
								
							
						
					
					
						commit
						c264e365cb
					
				
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue