diff --git a/README.md b/README.md index f740b14..743894e 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,6 @@ To open up a file, drag it onto the left side. To save a class, press CTRL + S o To search/replace in a file, press CTRL + F. +To open a class, press CTRL + T. + To change settings like auto-computation of stack frames and max locals/stack press CTRL + O. diff --git a/src/me/ByteEdit/main/Assembler.java b/src/me/ByteEdit/main/Assembler.java index d871c70..14feef5 100644 --- a/src/me/ByteEdit/main/Assembler.java +++ b/src/me/ByteEdit/main/Assembler.java @@ -63,6 +63,12 @@ public class Assembler { clazz.signature = s.substring(15).equals("null") ? null : s.substring(15); } else if (s.startsWith("// #OuterClass: ")) { clazz.outerClass = s.substring(16).equals("null") ? null : s.substring(16); + } else if (s.startsWith("// #OuterMethod: ")) { + String[] split = s.split(" "); + if (split.length > 3) { + clazz.outerMethod = split[2]; + clazz.outerMethodDesc = split[3]; + } } else if (s.equals("// #InnerClasses:")) { clazz.innerClasses = new ArrayList<>(); } else { diff --git a/src/me/ByteEdit/main/Disassembler.java b/src/me/ByteEdit/main/Disassembler.java index 46d9a21..b57f811 100644 --- a/src/me/ByteEdit/main/Disassembler.java +++ b/src/me/ByteEdit/main/Disassembler.java @@ -100,6 +100,8 @@ public class Disassembler { } s += "// #Class v:" + classNode.version + "\n"; s += "// #Signature: " + classNode.signature + "\n"; + s += "// #OuterMethod: " + (classNode.outerMethod == null ? "null" : (classNode.outerMethod + " " + classNode.outerMethodDesc)) + + "\n"; s += "// #OuterClass: " + classNode.outerClass + "\n"; s += "// #InnerClasses:\n"; if (classNode.innerClasses != null) { diff --git a/src/me/ByteEdit/main/Main.java b/src/me/ByteEdit/main/Main.java index 3292adf..2c185ec 100644 --- a/src/me/ByteEdit/main/Main.java +++ b/src/me/ByteEdit/main/Main.java @@ -78,6 +78,7 @@ public class Main extends JFrame { public static String currentNodeName; public static RSyntaxTextArea textArea; public static SearchBox searchBox; + public static TypeOpenBox typeOpenBox; public static OptionBox optionBox; public static JTree tree; @@ -149,6 +150,7 @@ public class Main extends JFrame { public Main() { INSTANCE = this; searchBox = new SearchBox(); + typeOpenBox = new TypeOpenBox(); optionBox = new OptionBox(); setTitle("ByteEdit"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -211,6 +213,16 @@ public class Main extends JFrame { searchBox.txtFind.select(0, searchBox.txtFind.getText().length()); } }, ctrlF, JComponent.WHEN_IN_FOCUSED_WINDOW); + KeyStroke ctrlT = KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.CTRL_DOWN_MASK); + textArea.registerKeyboardAction(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + typeOpenBox.setVisible(true); + typeOpenBox.txtSearch.requestFocusInWindow(); + typeOpenBox.txtSearch.select(0, typeOpenBox.txtSearch.getText().length()); + } + }, ctrlT, JComponent.WHEN_IN_FOCUSED_WINDOW); KeyStroke ctrlS = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK); textArea.registerKeyboardAction(new ActionListener() { @@ -299,22 +311,7 @@ public class Main extends JFrame { } s += (s.isEmpty() || s.replace("/", "").isEmpty() ? "" : "/") + (path.toString().isEmpty() ? "/" : path.toString()); } - if (s.endsWith(".class")) { - currentNodeName = s; - ClassNode classNode = classNodes.get(s); - String dis = Disassembler.disassemble(classNode); - String substr = s.substring(0, s.length() - 6); - for (String key : Main.classNodes.keySet()) { - if (key.contains("$")) { - String[] split = key.split("\\$"); - if (split[0].equals(substr)) { - dis += "\n" + Disassembler.disassemble(classNodes.get(key)); - } - } - } - textArea.setText(dis); - textArea.setCaretPosition(0); - } + selectFile(s); } } }); @@ -372,6 +369,25 @@ public class Main extends JFrame { }); } + public static void selectFile(String s) { + if (s.endsWith(".class")) { + currentNodeName = s; + ClassNode classNode = classNodes.get(s); + String dis = Disassembler.disassemble(classNode); + String substr = s.substring(0, s.length() - 6); + for (String key : Main.classNodes.keySet()) { + if (key.contains("$")) { + String[] split = key.split("\\$"); + if (split[0].equals(substr)) { + dis += "\n" + Disassembler.disassemble(classNodes.get(key)); + } + } + } + textArea.setText(dis); + textArea.setCaretPosition(0); + } + } + public void save() { final JFileChooser fileChooser = new JFileChooser() { diff --git a/src/me/ByteEdit/main/TypeOpenBox.java b/src/me/ByteEdit/main/TypeOpenBox.java new file mode 100644 index 0000000..6e9f3db --- /dev/null +++ b/src/me/ByteEdit/main/TypeOpenBox.java @@ -0,0 +1,117 @@ +package me.ByteEdit.main; + +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.DefaultListModel; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +public class TypeOpenBox extends JFrame { + + public JPanel contentPane; + public JTextField txtSearch; + + /** + * Create the frame. + */ + public TypeOpenBox() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + setResizable(false); + setTitle("Open Type"); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 200), + (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 140), 400, 280); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + + DefaultListModel model = new DefaultListModel<>(); + JList list = new JList(model); + list.addListSelectionListener(new ListSelectionListener() { + + public void valueChanged(ListSelectionEvent e) { + String val = list.getSelectedValue(); + if (val != null && !val.equals(Main.currentNodeName)) { + Main.selectFile(val); + } + } + }); + + txtSearch = new JTextField(); + txtSearch.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + if (model.size() == 1) { + list.setSelectedIndex(0); + } + } + }); + txtSearch.getDocument().addDocumentListener(new DocumentListener() { + + public void changedUpdate(DocumentEvent e) { + updateList(); + } + + public void removeUpdate(DocumentEvent e) { + updateList(); + } + + public void insertUpdate(DocumentEvent e) { + updateList(); + } + + public void updateList() { + model.clear(); + if (txtSearch.getText().isEmpty()) { + return; + } + String search = txtSearch.getText().toLowerCase(); + if (search.contains("/")) { + for (String s : Main.classNodes.keySet()) { + String className = s.substring(0, s.length() - 6); + if (!className.contains("$") && className.toLowerCase().startsWith(search)) { + model.addElement(s); + } + } + } else { + for (String s : Main.classNodes.keySet()) { + String[] split = s.split("/"); + String className = split[split.length - 1]; + className = className.substring(0, className.length() - 6); + if (!className.contains("$") && className.toLowerCase().startsWith(search)) { + model.addElement(s); + } + } + } + } + }); + txtSearch.setBounds(10, 11, 374, 20); + contentPane.add(txtSearch); + txtSearch.setColumns(10); + + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBounds(10, 46, 374, 194); + contentPane.add(scrollPane); + + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + scrollPane.setViewportView(list); + } + +}