mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 19:54:37 +00:00
Merge origin/master
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.AppResources;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator;
|
||||
|
||||
@@ -1262,13 +1262,13 @@ public class CommandLineArgumentParser {
|
||||
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.err.println("CharacterId should be integer");
|
||||
badArguments();
|
||||
System.exit(1);
|
||||
}
|
||||
int characterId = Integer.parseInt(args.remove());
|
||||
SWF swf = new SWF(is, Configuration.parallelSpeedUp.get());
|
||||
if (!swf.characters.containsKey(characterId)) {
|
||||
System.err.println("CharacterId not exits");
|
||||
badArguments();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
CharacterTag characterTag = swf.characters.get(characterId);
|
||||
@@ -1281,7 +1281,7 @@ public class CommandLineArgumentParser {
|
||||
new ImageImporter().importImage(imageTag, data);
|
||||
} else {
|
||||
System.err.println("The specified tag type it not supported for import");
|
||||
badArguments();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.hexview.HexView;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ComponentEvent;
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Rectangle;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class HexView extends JTable {
|
||||
|
||||
private final int bytesInRow = 16;
|
||||
private long[] highlightStarts;
|
||||
private long[] highlightEnds;
|
||||
private byte[] data;
|
||||
private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"};
|
||||
private final Color[] highlightColors;
|
||||
private Color bgColor = Color.decode("#F7F7F7");
|
||||
private Color bgColorAlternate = Color.decode("#EDEDED");
|
||||
|
||||
public class HighlightCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
|
||||
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
|
||||
int level = -1;
|
||||
if (col > 0 && highlightStarts != null) {
|
||||
if (col != bytesInRow + 1) {
|
||||
int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1));
|
||||
for (int i = 0; i < highlightStarts.length; i++) {
|
||||
if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) {
|
||||
level++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (level > -1) {
|
||||
l.setForeground(Color.white);
|
||||
l.setBackground(highlightColors[level % highlightColors.length]);
|
||||
} else {
|
||||
l.setForeground(Color.black);
|
||||
l.setBackground(row % 2 == 0 ? bgColor : bgColorAlternate);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
public HexView() {
|
||||
highlightColors = new Color[highlightColorsStr.length];
|
||||
for (int i = 0; i < highlightColors.length; i++) {
|
||||
highlightColors[i] = Color.decode("#" + highlightColorsStr[i]);
|
||||
}
|
||||
|
||||
setModel(new AbstractTableModel() {
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
if (data == null) {
|
||||
return 0;
|
||||
}
|
||||
int byteCount = data.length;
|
||||
int rowCount = byteCount / bytesInRow;
|
||||
if (byteCount % bytesInRow != 0) {
|
||||
rowCount++;
|
||||
}
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2 * bytesInRow + 1 + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
if (column == 0) {
|
||||
return "Address";
|
||||
} else if (column <= bytesInRow) {
|
||||
return String.format("%01X", column - 1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int row, int column) {
|
||||
if (column == 0) {
|
||||
return String.format("%08X", (long) row * bytesInRow);
|
||||
} else if (column <= bytesInRow) {
|
||||
int pos = row * bytesInRow + column - 1;
|
||||
if (pos < data.length) {
|
||||
return String.format("%02X", data[pos]);
|
||||
}
|
||||
return null;
|
||||
} else if (column == 1 + bytesInRow) {
|
||||
return null;
|
||||
} else {
|
||||
int pos = row * bytesInRow + column - bytesInRow - 1 - 1;
|
||||
if (pos < data.length) {
|
||||
return (char) data[pos];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setBackground(Color.white);
|
||||
setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||
setTableHeader(new JTableHeader());
|
||||
setMaximumSize(new Dimension(200, 200));
|
||||
|
||||
setShowHorizontalLines(false);
|
||||
setShowVerticalLines(false);
|
||||
setRowSelectionAllowed(false);
|
||||
setColumnSelectionAllowed(false);
|
||||
|
||||
HighlightCellRenderer cellRenderer = new HighlightCellRenderer();
|
||||
TableColumn column = columnModel.getColumn(0);
|
||||
column.setMaxWidth(80);
|
||||
//column.setCellRenderer(cellRenderer);
|
||||
for (int i = 0; i < bytesInRow; i++) {
|
||||
column = columnModel.getColumn(i + 1);
|
||||
column.setMaxWidth(25);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
|
||||
column = columnModel.getColumn(bytesInRow + 1);
|
||||
column.setMaxWidth(10);
|
||||
|
||||
for (int i = 0; i < bytesInRow; i++) {
|
||||
column = columnModel.getColumn(i + bytesInRow + 1 + 1);
|
||||
column.setMaxWidth(10);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) {
|
||||
|
||||
if ((highlightStarts == null) ^ (highlightEnds == null)) {
|
||||
throw new Error("highlightStarts and highlightEnds should be both null or not null.");
|
||||
}
|
||||
|
||||
if (highlightStarts != null && highlightStarts.length != highlightEnds.length) {
|
||||
throw new Error("highlightStarts and highlightEnds should have the same number of elements.");
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
this.highlightStarts = highlightStarts;
|
||||
this.highlightEnds = highlightEnds;
|
||||
}
|
||||
|
||||
public void scrollToByte(long byteNum) {
|
||||
int row = (int) (byteNum / bytesInRow);
|
||||
|
||||
//final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight());
|
||||
getSelectionModel().setSelectionInterval(row, row);
|
||||
scrollRectToVisible(new Rectangle(getCellRect(row, 0, true)));
|
||||
}
|
||||
|
||||
public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) {
|
||||
for (int i = 0; i < byteNumStarts.length; i++) {
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
scrollToByte(byteNumEnds[i]);
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,7 +358,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
|
||||
private JPanel createDumpPreviewCard() {
|
||||
JPanel dumpViewCard = new JPanel(new BorderLayout());
|
||||
dumpViewPanel = new DumpViewPanel();
|
||||
dumpViewPanel = new DumpViewPanel(dumpTree);
|
||||
dumpViewCard.add(new JScrollPane(dumpViewPanel), BorderLayout.CENTER);
|
||||
|
||||
return dumpViewCard;
|
||||
@@ -2172,8 +2172,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
return;
|
||||
}
|
||||
|
||||
dumpViewPanel.setData(DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().originalUncompressedData, dumpInfo);
|
||||
dumpViewPanel.revalidate();
|
||||
dumpViewPanel.setSelectedNode(dumpInfo);
|
||||
showCard(CARDDUMPVIEW);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
package com.jpexs.decompiler.flash.gui.dumpview;
|
||||
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.gui.HexView;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode;
|
||||
import com.jpexs.decompiler.flash.gui.hexview.HexView;
|
||||
import com.jpexs.decompiler.flash.gui.hexview.HexViewListener;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.util.ArrayList;
|
||||
@@ -25,6 +28,8 @@ import java.util.List;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -32,21 +37,89 @@ import javax.swing.JScrollPane;
|
||||
*/
|
||||
public class DumpViewPanel extends JPanel {
|
||||
|
||||
private final JLabel selectedByteInfo;
|
||||
private final JLabel dumpViewLabel;
|
||||
private final HexView dumpViewHexTable;
|
||||
private final DumpTree dumpTree;
|
||||
private DumpInfo selectedDumpInfo;
|
||||
private boolean skipNextScroll;
|
||||
private boolean skipValueChange;
|
||||
|
||||
public DumpViewPanel() {
|
||||
public DumpViewPanel(final DumpTree dumpTree) {
|
||||
super(new BorderLayout());
|
||||
|
||||
this.dumpTree = dumpTree;
|
||||
|
||||
selectedByteInfo = new JLabel();
|
||||
selectedByteInfo.setMinimumSize(new Dimension(100, 20));
|
||||
selectedByteInfo.setText("-");
|
||||
add(selectedByteInfo, BorderLayout.NORTH);
|
||||
|
||||
dumpViewLabel = new JLabel();
|
||||
dumpViewLabel.setMinimumSize(new Dimension(100, 20));
|
||||
dumpViewLabel.setText("-");
|
||||
add(dumpViewLabel, BorderLayout.SOUTH);
|
||||
|
||||
dumpViewHexTable = new HexView();
|
||||
dumpViewHexTable.addListener(new HexViewListener() {
|
||||
|
||||
@Override
|
||||
public void byteValueChanged(int address, byte b) {
|
||||
if (skipValueChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeModel model = dumpTree.getModel();
|
||||
DumpInfo di = DumpInfoSwfNode.getSwfNode(selectedDumpInfo);
|
||||
while (model.getChildCount(di) > 0) {
|
||||
boolean found = false;
|
||||
for (DumpInfo child : di.getChildInfos()) {
|
||||
if (child.startByte > address) {
|
||||
break;
|
||||
}
|
||||
if (child.getEndByte() >= address) {
|
||||
di = child;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<Object> path = new ArrayList<>();
|
||||
while (di != null) {
|
||||
path.add(0, di);
|
||||
di = di.parent;
|
||||
}
|
||||
path.add(0, model.getRoot());
|
||||
TreePath tp = new TreePath(path.toArray());
|
||||
skipNextScroll = true;
|
||||
dumpTree.setSelectionPath(tp);
|
||||
dumpTree.scrollPathToVisible(tp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void byteMouseMoved(int address, byte b) {
|
||||
int b2 = b & 0xff;
|
||||
selectedByteInfo.setText("Addr: " + Helper.padZeros(address, 8) +
|
||||
" Hex: " + Helper.padZeros(Integer.toHexString(b2), 2) +
|
||||
" Dec: " + b2 +
|
||||
" Bin: " + Helper.padZeros(Integer.toBinaryString(b2), 8) +
|
||||
" Ascii: " + (char) b2);
|
||||
}
|
||||
});
|
||||
|
||||
add(new JScrollPane(dumpViewHexTable), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setData(byte[] data, DumpInfo dumpInfo) {
|
||||
public void setSelectedNode(DumpInfo dumpInfo) {
|
||||
if (this.selectedDumpInfo == dumpInfo) {
|
||||
skipNextScroll = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectedDumpInfo = dumpInfo;
|
||||
byte[] data = DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf().originalUncompressedData;
|
||||
List<DumpInfo> dumpInfos = new ArrayList<>();
|
||||
DumpInfo di = dumpInfo;
|
||||
while (di.parent != null) {
|
||||
@@ -61,12 +134,17 @@ public class DumpViewPanel extends JPanel {
|
||||
highlightEnds[i] = di2.getEndByte();
|
||||
}
|
||||
dumpViewHexTable.setData(data, highlightStarts, highlightEnds);
|
||||
dumpViewHexTable.revalidate();
|
||||
|
||||
if (dumpInfo.lengthBytes != 0 || dumpInfo.lengthBits != 0) {
|
||||
int selectionStart = (int) dumpInfo.startByte;
|
||||
int selectionEnd = (int) dumpInfo.getEndByte();
|
||||
|
||||
dumpViewHexTable.scrollToByte(highlightStarts, highlightEnds);
|
||||
if (!skipNextScroll) {
|
||||
skipValueChange = true;
|
||||
dumpViewHexTable.scrollToByte(highlightStarts, highlightEnds);
|
||||
skipValueChange = false;
|
||||
}
|
||||
|
||||
setLabelText("startByte: " + dumpInfo.startByte
|
||||
+ " startBit: " + dumpInfo.startBit
|
||||
@@ -76,6 +154,7 @@ public class DumpViewPanel extends JPanel {
|
||||
+ " selectionEnd: " + selectionEnd);
|
||||
}
|
||||
|
||||
skipNextScroll = false;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
235
src/com/jpexs/decompiler/flash/gui/hexview/HexView.java
Normal file
235
src/com/jpexs/decompiler/flash/gui/hexview/HexView.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.hexview;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionAdapter;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class HexView extends JTable {
|
||||
|
||||
private static final int bytesInRow = 16;
|
||||
private long[] highlightStarts;
|
||||
private long[] highlightEnds;
|
||||
private final String[] highlightColorsStr = new String[]{/*"EEEEEE", */"29AEC2", "9AC88C", "DF5F80", "EEA32E", "FFD200", "5E9B4C", "D3E976", "A3AEC2"};
|
||||
private final Color[] highlightColors;
|
||||
private final Color bgColor = Color.decode("#F7F7F7");
|
||||
private final Color bgColorAlternate = Color.decode("#EDEDED");
|
||||
private int itsRow = 0;
|
||||
private int itsColumn = 0;
|
||||
private HexViewListener listener;
|
||||
|
||||
private class HighlightCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
public int byteIndex;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
|
||||
JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
|
||||
int level = -1;
|
||||
if (col > 0 && highlightStarts != null && col != bytesInRow + 1) {
|
||||
int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1));
|
||||
byteIndex = idx;
|
||||
for (int i = 0; i < highlightStarts.length; i++) {
|
||||
if (highlightStarts[i] <= idx && highlightEnds[i] >= idx) {
|
||||
level++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Color foreground;
|
||||
Color background;
|
||||
if (level > -1) {
|
||||
foreground = Color.white;
|
||||
background = highlightColors[level % highlightColors.length];
|
||||
} else {
|
||||
foreground = Color.black;
|
||||
background = row % 2 == 0 ? bgColor : bgColorAlternate;
|
||||
}
|
||||
|
||||
if (col == itsColumn && row == itsRow) {
|
||||
foreground = new Color(255 - foreground.getRed(), 255 - foreground.getGreen(), 255 - foreground.getBlue());
|
||||
background = new Color(255 - background.getRed(), 255 - background.getGreen(), 255 - background.getBlue());
|
||||
}
|
||||
l.setForeground(foreground);
|
||||
l.setBackground(background);
|
||||
|
||||
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
private class HexViewSelectionListener implements ListSelectionListener {
|
||||
|
||||
private final HexView table;
|
||||
|
||||
public HexViewSelectionListener(HexView table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
|
||||
int col = table.getSelectedColumn();
|
||||
int row = table.getSelectedRow();
|
||||
|
||||
if (col > 0 && highlightStarts != null && col != bytesInRow + 1) {
|
||||
int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1));
|
||||
byte[] data = getModel().getData();
|
||||
if (idx < data.length) {
|
||||
if (listener != null) {
|
||||
listener.byteValueChanged(idx, data[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class HexViewMouseAdapter extends MouseAdapter {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
|
||||
private class HexViewMouseMotionAdapter extends MouseMotionAdapter {
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
HexView table = (HexView) e.getSource();
|
||||
Point point = e.getPoint();
|
||||
int col = table.columnAtPoint(point);
|
||||
int row = table.rowAtPoint(point);
|
||||
itsColumn = col;
|
||||
itsRow = row;
|
||||
getModel().fireTableCellUpdated(row, col);
|
||||
|
||||
if (listener != null) {
|
||||
int idx = row * bytesInRow + ((col > bytesInRow + 1) ? (col - bytesInRow - 2) : (col - 1));
|
||||
listener.byteMouseMoved(idx, getModel().getData()[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HexView() {
|
||||
super(new HexViewTableModel(bytesInRow));
|
||||
highlightColors = new Color[highlightColorsStr.length];
|
||||
for (int i = 0; i < highlightColors.length; i++) {
|
||||
highlightColors[i] = Color.decode("#" + highlightColorsStr[i]);
|
||||
}
|
||||
|
||||
setBackground(Color.white);
|
||||
setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||
setTableHeader(new JTableHeader());
|
||||
setMaximumSize(new Dimension(200, 200));
|
||||
|
||||
setShowHorizontalLines(false);
|
||||
setShowVerticalLines(false);
|
||||
setRowSelectionAllowed(false);
|
||||
setColumnSelectionAllowed(false);
|
||||
|
||||
HighlightCellRenderer cellRenderer = new HighlightCellRenderer();
|
||||
TableColumn column = columnModel.getColumn(0);
|
||||
column.setMaxWidth(80);
|
||||
for (int i = 0; i < bytesInRow; i++) {
|
||||
column = columnModel.getColumn(i + 1);
|
||||
column.setMaxWidth(25);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
|
||||
column = columnModel.getColumn(bytesInRow + 1);
|
||||
column.setMaxWidth(10);
|
||||
|
||||
for (int i = 0; i < bytesInRow; i++) {
|
||||
column = columnModel.getColumn(i + bytesInRow + 1 + 1);
|
||||
column.setMaxWidth(10);
|
||||
column.setCellRenderer(cellRenderer);
|
||||
}
|
||||
|
||||
addMouseListener(new HexViewMouseAdapter());
|
||||
addMouseMotionListener(new HexViewMouseMotionAdapter());
|
||||
ListSelectionModel rowSelModel = getSelectionModel();
|
||||
ListSelectionModel colSelModel = getColumnModel().getSelectionModel();
|
||||
ListSelectionListener selectionListener = new HexViewSelectionListener(this);
|
||||
rowSelModel.addListSelectionListener(selectionListener);
|
||||
colSelModel.addListSelectionListener(selectionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HexViewTableModel getModel() {
|
||||
TableModel model = super.getModel();
|
||||
return (HexViewTableModel) model;
|
||||
}
|
||||
|
||||
public void setData(byte[] data, long[] highlightStarts, long[] highlightEnds) {
|
||||
|
||||
if ((highlightStarts == null) ^ (highlightEnds == null)) {
|
||||
throw new Error("highlightStarts and highlightEnds should be both null or not null.");
|
||||
}
|
||||
|
||||
if (highlightStarts != null && highlightStarts.length != highlightEnds.length) {
|
||||
throw new Error("highlightStarts and highlightEnds should have the same number of elements.");
|
||||
}
|
||||
|
||||
getModel().setData(data);
|
||||
this.highlightStarts = highlightStarts;
|
||||
this.highlightEnds = highlightEnds;
|
||||
}
|
||||
|
||||
public void scrollToByte(long byteNum) {
|
||||
|
||||
int row = (int) (byteNum / bytesInRow);
|
||||
|
||||
//final int pageSize = (int) (getParent().getSize().getHeight() / getRowHeight());
|
||||
getSelectionModel().setSelectionInterval(row, row);
|
||||
scrollRectToVisible(new Rectangle(getCellRect(row, 0, true)));
|
||||
}
|
||||
|
||||
public void scrollToByte(long[] byteNumStarts, long[] byteNumEnds) {
|
||||
for (int i = 0; i < byteNumStarts.length; i++) {
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
scrollToByte(byteNumEnds[i]);
|
||||
scrollToByte(byteNumStarts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void addListener(HexViewListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.hexview;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface HexViewListener {
|
||||
|
||||
public void byteValueChanged(int address, byte b);
|
||||
|
||||
public void byteMouseMoved(int address, byte b);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.hexview;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class HexViewTableModel extends AbstractTableModel {
|
||||
|
||||
private byte[] data;
|
||||
private final int bytesInRow;
|
||||
|
||||
public HexViewTableModel(int bytesInRow) {
|
||||
this.bytesInRow = bytesInRow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
if (data == null) {
|
||||
return 0;
|
||||
}
|
||||
int byteCount = data.length;
|
||||
int rowCount = byteCount / bytesInRow;
|
||||
if (byteCount % bytesInRow != 0) {
|
||||
rowCount++;
|
||||
}
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2 * bytesInRow + 1 + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
if (column == 0) {
|
||||
return "Address";
|
||||
} else if (column <= bytesInRow) {
|
||||
return String.format("%01X", column - 1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int row, int column) {
|
||||
if (column == 0) {
|
||||
return String.format("%08X", (long) row * bytesInRow);
|
||||
} else if (column <= bytesInRow) {
|
||||
int pos = row * bytesInRow + column - 1;
|
||||
if (pos < data.length) {
|
||||
return String.format("%02X", data[pos]);
|
||||
}
|
||||
return null;
|
||||
} else if (column == 1 + bytesInRow) {
|
||||
return null;
|
||||
} else {
|
||||
int pos = row * bytesInRow + column - bytesInRow - 1 - 1;
|
||||
if (pos < data.length) {
|
||||
return (char) (data[pos] & 0xff);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireTableCellUpdated(int row, int columnd) {
|
||||
super.fireTableCellUpdated(bytesInRow, bytesInRow);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user