de.codesourcery.jasm16.ide.ui.views.HexDumpView.java Source code

Java tutorial

Introduction

Here is the source code for de.codesourcery.jasm16.ide.ui.views.HexDumpView.java

Source

/**
 * Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.codesourcery.jasm16.ide.ui.views;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.apache.commons.lang.StringUtils;

import de.codesourcery.jasm16.Address;
import de.codesourcery.jasm16.Size;
import de.codesourcery.jasm16.emulator.EmulationListener;
import de.codesourcery.jasm16.emulator.IEmulationListener;
import de.codesourcery.jasm16.emulator.IEmulator;
import de.codesourcery.jasm16.emulator.memory.MemUtils;
import de.codesourcery.jasm16.ide.ui.utils.PagingKeyAdapter;
import de.codesourcery.jasm16.utils.Misc;

public class HexDumpView extends AbstractView {
    public static final String VIEW_ID = "hexdump-view";

    private JPanel panel;
    private final JTextArea textArea = new JTextArea();

    private IEmulator emulator;
    private Address dumpStartAddress = Address.wordAddress(0x0);
    private int numberOfWordsPerLine = 8;
    private boolean printASCII = true;

    private final IEmulationListener listener = new EmulationListener() {

        @Override
        public void afterCommandExecution(IEmulator emulator, int commandDuration) {
            if (!isFullSpeedMode()) {
                refreshDisplay();
            }
        }

        @Override
        public void afterReset(IEmulator emulator) {
            if (!isFullSpeedMode()) {
                refreshDisplay();
            }
        }

        @Override
        public void afterMemoryLoad(IEmulator emulator, Address startAddress, int lengthInBytes) {
            if (!isFullSpeedMode()) {
                refreshDisplay();
            }
        }

        @Override
        public void onStopHook(IEmulator emulator, Address previousPC, Throwable emulationError) {
            refreshDisplay();
        }
    };

    public HexDumpView(IEmulator emulator) {
        setEmulator(emulator);
    }

    public HexDumpView() {
    }

    @Override
    public void refreshDisplay() {
        if (emulator == null) {
            return;
        }

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                final byte[] data = MemUtils.getBytes(emulator.getMemory(), dumpStartAddress,
                        calcSizeOfVisibleMemory(), true);

                textArea.setText(Misc.toHexDumpWithAddresses(dumpStartAddress, data, data.length,
                        numberOfWordsPerLine, printASCII, true));
            }
        });
    }

    protected Size calcSizeOfVisibleMemory() {
        int rows = calculateVisibleTextRowCount(textArea);
        if (rows < 1) {
            rows = 1;
        }
        return Size.words(rows * numberOfWordsPerLine);
    }

    public void setEmulator(IEmulator emulator) {
        if (emulator == null) {
            throw new IllegalArgumentException("emulator must not be NULL.");
        }
        if (this.emulator == emulator) {
            return;
        }

        if (this.emulator != null) {
            this.emulator.removeEmulationListener(listener);
        }
        this.emulator = emulator;

        emulator.addEmulationListener(listener);
    }

    @Override
    public void disposeHook() {
        if (this.emulator != null) {
            this.emulator.removeEmulationListener(listener);
            this.emulator = null;
        }
    }

    protected JPanel createPanel() {
        textArea.setEditable(false);
        setColors(textArea);
        textArea.setFont(getMonospacedFont());
        textArea.setEditable(false);

        // dump panel
        final JPanel dumpPanel = new JPanel();
        setColors(dumpPanel);
        dumpPanel.setLayout(new GridBagLayout());
        GridBagConstraints cnstrs = constraints(0, 0, true, true, GridBagConstraints.BOTH);
        dumpPanel.add(textArea, cnstrs);

        // toolbar panel
        final JPanel toolbarPanel = new JPanel();
        setColors(toolbarPanel);
        toolbarPanel.setLayout(new GridBagLayout());

        cnstrs = constraints(0, 0, false, false, GridBagConstraints.NONE);
        toolbarPanel.add(new JLabel("Goto"), cnstrs);

        final JTextField gotoTextfield = new JTextField();
        gotoTextfield.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final String val = gotoTextfield.getText();
                Address adr;
                if (StringUtils.isBlank(val)) {
                    gotoTextfield.setText("0000");
                    adr = Address.wordAddress(0);
                } else {
                    try {
                        adr = Address.wordAddress(Misc.parseHexString(val));
                    } catch (NumberFormatException e1) {
                        gotoTextfield.setText("0000");
                        adr = Address.wordAddress(0);
                    }
                }
                dumpStartAddress = adr;
                refreshDisplay();
            }
        });

        cnstrs = constraints(0, 1, true, true, GridBagConstraints.HORIZONTAL);
        toolbarPanel.add(gotoTextfield, cnstrs);

        // create result panel
        final JPanel result = new JPanel();
        setColors(result);
        result.setLayout(new GridBagLayout());
        cnstrs = constraints(0, 0, false, true, GridBagConstraints.BOTH);
        result.add(dumpPanel, cnstrs);
        cnstrs = constraints(1, 0, true, true, GridBagConstraints.VERTICAL);
        result.add(toolbarPanel, cnstrs);

        textArea.addKeyListener(new PagingKeyAdapter() {

            @Override
            protected void onePageUp() {
                HexDumpView.this.onePageUp();
            }

            @Override
            protected void onePageDown() {
                HexDumpView.this.onePageDown();
            }

            @Override
            protected void oneLineUp() {
                HexDumpView.this.oneLineUp();
            }

            @Override
            protected void oneLineDown() {
                HexDumpView.this.oneLineDown();
            }
        });

        result.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                refreshDisplay();
            }
        });

        return result;
    }

    private void onePageDown() {
        dumpStartAddress = dumpStartAddress.plus(calcSizeOfVisibleMemory(), true);
        refreshDisplay();
    }

    private void oneLineDown() {
        dumpStartAddress = dumpStartAddress.plus(Size.words(numberOfWordsPerLine), true);
        refreshDisplay();
    }

    private void onePageUp() {
        dumpStartAddress = dumpStartAddress.minus(calcSizeOfVisibleMemory());
        refreshDisplay();
    }

    private void oneLineUp() {
        dumpStartAddress = dumpStartAddress.minus(Size.words(numberOfWordsPerLine));
        refreshDisplay();
    }

    @Override
    public JPanel getPanel() {
        if (panel == null) {
            panel = createPanel();
        }
        return panel;
    }

    @Override
    public String getTitle() {
        return "memory view";
    }

    @Override
    public String getID() {
        return VIEW_ID;
    }
}