Java tutorial
/** * 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; } }