├── .gitignore ├── README.md ├── demo.gif ├── jbeditor.iml ├── pom.xml └── src └── main ├── java ├── com │ └── sun │ │ └── xml │ │ └── internal │ │ └── messaging │ │ └── saaj │ │ └── util │ │ └── ByteInputStream.java └── net │ └── ptnkjke │ └── jbeditor │ ├── Configutation.java │ ├── Main.java │ ├── MissingInstruction.java │ ├── gui │ ├── about │ │ ├── Controller.java │ │ └── View.fxml │ ├── error │ │ ├── Controller.java │ │ └── View.fxml │ ├── main │ │ ├── Controller.java │ │ ├── FlowListCell.java │ │ ├── Static.java │ │ ├── View.fxml │ │ ├── constantpanes │ │ │ ├── constantpane_class │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_double │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_fieldref │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_float │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_integer │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_interfacemethodref │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_long │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_methodhandle │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_methodref │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_methodtype │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_nameandtype │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_string │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ ├── constantpane_utf8 │ │ │ │ ├── Controller.java │ │ │ │ └── View.fxml │ │ │ └── table │ │ │ │ ├── ConstantTableCell.java │ │ │ │ ├── Controller.java │ │ │ │ ├── Static.java │ │ │ │ └── View.fxml │ │ ├── model │ │ │ ├── ConsoleMessage.java │ │ │ ├── MessageType.java │ │ │ └── classtree │ │ │ │ ├── Attribute.java │ │ │ │ ├── Attributes.java │ │ │ │ ├── Constant.java │ │ │ │ ├── ConstantPool.java │ │ │ │ ├── Field.java │ │ │ │ ├── Fields.java │ │ │ │ ├── GeneralInformation.java │ │ │ │ ├── Info.java │ │ │ │ ├── Interface.java │ │ │ │ ├── Interfaces.java │ │ │ │ ├── Method.java │ │ │ │ ├── Methods.java │ │ │ │ └── Root.java │ │ └── panes │ │ │ ├── defaultpane │ │ │ ├── Controller.java │ │ │ └── View.fxml │ │ │ ├── descriptionerror │ │ │ ├── Controller.java │ │ │ ├── Static.java │ │ │ └── View.fxml │ │ │ ├── generalinfopane │ │ │ ├── Controller.java │ │ │ ├── Utils.java │ │ │ └── View.fxml │ │ │ └── methodpane │ │ │ ├── Controller.java │ │ │ ├── MethodController.java │ │ │ ├── MethodModel.java │ │ │ ├── MethodUtils.java │ │ │ ├── Utils.java │ │ │ └── View.fxml │ └── preferences │ │ ├── Controller.java │ │ └── View.fxml │ ├── logic │ ├── Core.java │ ├── asm │ │ ├── ASMCore.java │ │ ├── JAsmByteParser.java │ │ └── bytecode │ │ │ ├── BCClassVisitor.java │ │ │ └── BCMethodVisitor.java │ ├── bcel │ │ ├── BCELCore.java │ │ ├── GraphVizCreator.java │ │ ├── JBcelByteParser.java │ │ └── bytecode │ │ │ ├── CellConstantWorker.java │ │ │ ├── ConstanstWorker.java │ │ │ ├── Editor.java │ │ │ ├── InstructionHandleWorker.java │ │ │ └── TextConstantWorker.java │ └── own │ │ └── bytecode │ │ ├── AbstractConstant.java │ │ ├── ConstantClass.java │ │ ├── ConstantDouble.java │ │ ├── ConstantFieldref.java │ │ ├── ConstantFloat.java │ │ ├── ConstantInteger.java │ │ ├── ConstantInterfaceMethodref.java │ │ ├── ConstantInvokeDynamic.java │ │ ├── ConstantLong.java │ │ ├── ConstantMethodHandle.java │ │ ├── ConstantMethodType.java │ │ ├── ConstantMethodref.java │ │ ├── ConstantNameAndType.java │ │ ├── ConstantPool.java │ │ ├── ConstantString.java │ │ ├── ConstantUtf8.java │ │ ├── Constants.java │ │ └── OClass.java │ └── utils │ ├── CellConstantWorker.java │ ├── ConstanstWorker.java │ ├── Editor.java │ ├── GraphVizCreator.java │ ├── InstructionHandleWorker.java │ ├── JByteParser.java │ ├── JarClassLoader.java │ ├── TextConstantWorker.java │ └── Utils.java └── resources ├── messages_en.properties └── messages_ru.properties /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jbedit 2 | ====== 3 | 4 | jbedit is a tool that visualizes information about Java class file. 5 | With this tool you can modify bytecode and cosntruct a graph of bytecode instructions. 6 | 7 | 8 | 9 | This requires java8. 10 | 11 | mini demonstration: 12 | ![thumbs up](demo.gif) 13 | 14 | 15 | 16 | Step for using: 17 | 18 | 1) Install maven 19 | 2) to do mvn clean install 20 | 3) mvn package and run 21 | 22 | 23 | I recommend to run this project in ide, because its not finished. 24 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptnkjke/Java-Bytecode-Editor/0564b99dcfc8ef461eac23a506a19890b6b8ea26/demo.gif -------------------------------------------------------------------------------- /jbeditor.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | jbeditor 8 | jbeditor 9 | 1.0 10 | jar 11 | 12 | 13 | 1.8 14 | 1.8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.bcel 21 | bcel 22 | 6.0 23 | 24 | 25 | 26 | net.lingala.zip4j 27 | zip4j 28 | 1.3.2 29 | 30 | 31 | 32 | org.ow2.asm 33 | asm-debug-all 34 | 5.0.3 35 | 36 | 37 | 38 | org.codehaus.groovy 39 | groovy-all 40 | 2.4.0-beta-4 41 | 42 | 43 | 44 | 45 | 46 | 47 | src/main/resources 48 | 49 | 50 | src/main/java 51 | 52 | **/*.java 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-jar-plugin 60 | 2.4 61 | 62 | 63 | 64 | net.ptnkjke.jbeditor.Main 65 | lib/ 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | maven-dependency-plugin 74 | 75 | 76 | package 77 | 78 | copy-dependencies 79 | 80 | 81 | ${project.build.directory}/lib 82 | 83 | 84 | 85 | 86 | 87 | 88 | org.codehaus.gmaven 89 | gmaven-plugin 90 | 91 | 92 | 93 | compile 94 | 95 | 96 | 97 | 98 | ${pom.basedir}/src/main/script 99 | 100 | **/*.groovy 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/main/java/com/sun/xml/internal/messaging/saaj/util/ByteInputStream.java: -------------------------------------------------------------------------------- 1 | // 2 | // Source code recreated from a .class file by IntelliJ IDEA 3 | // (powered by Fernflower decompiler) 4 | // 5 | 6 | package com.sun.xml.internal.messaging.saaj.util; 7 | 8 | import java.io.ByteArrayInputStream; 9 | import java.io.IOException; 10 | 11 | public class ByteInputStream extends ByteArrayInputStream { 12 | private static final byte[] EMPTY_ARRAY = new byte[0]; 13 | 14 | public ByteInputStream() { 15 | this(EMPTY_ARRAY, 0); 16 | } 17 | 18 | public ByteInputStream(byte[] buf, int length) { 19 | super(buf, 0, length); 20 | } 21 | 22 | public ByteInputStream(byte[] buf, int offset, int length) { 23 | super(buf, offset, length); 24 | } 25 | 26 | public byte[] getBytes() { 27 | return this.buf; 28 | } 29 | 30 | public int getCount() { 31 | return this.count; 32 | } 33 | 34 | public void close() throws IOException { 35 | this.reset(); 36 | } 37 | 38 | public void setBuf(byte[] buf) { 39 | this.buf = buf; 40 | this.pos = 0; 41 | this.count = buf.length; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/Configutation.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.Properties; 8 | 9 | public class Configutation { 10 | public static String graphVizPath = "C:\\soft\\graphviz\\bin\\dot.exe"; 11 | public static String workDir = "C:\\temp"; 12 | 13 | private static final String config = "config.ini"; 14 | 15 | public static void save() { 16 | File f = new File(config); 17 | Properties properties = new Properties(); 18 | 19 | properties.setProperty("graphVizPath", graphVizPath); 20 | properties.setProperty("workDir", workDir); 21 | try { 22 | properties.store(new FileOutputStream(f), "jbedit file options"); 23 | } catch (IOException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | public static void read() { 29 | File con = new File(config); 30 | if (!con.exists()) { 31 | save(); 32 | } 33 | 34 | Properties properties = new Properties(); 35 | 36 | try { 37 | properties.load(new FileInputStream(con)); 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | 42 | graphVizPath = properties.getProperty("graphVizPath"); 43 | workDir = properties.getProperty("workDir"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/Main.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.fxml.JavaFXBuilderFactory; 6 | import javafx.scene.Parent; 7 | import javafx.scene.Scene; 8 | import javafx.scene.input.Dragboard; 9 | import javafx.scene.input.TransferMode; 10 | import javafx.stage.Stage; 11 | import net.ptnkjke.jbeditor.gui.main.Controller; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.util.List; 16 | 17 | public class Main extends Application { 18 | 19 | @Override 20 | public void start(Stage primaryStage) throws Exception { 21 | 22 | // Считываем параметры по умолчанию 23 | Configutation.read(); 24 | 25 | // 26 | Parent root = null; 27 | FXMLLoader fxmlLoader = null; 28 | fxmlLoader = new FXMLLoader(); 29 | fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()); 30 | 31 | Controller controller = null; 32 | 33 | try { 34 | root = fxmlLoader.load(getClass().getResource("gui/main/View.fxml").openStream()); 35 | controller = fxmlLoader.getController(); 36 | } catch (IOException e) { 37 | e.printStackTrace(); 38 | } 39 | 40 | primaryStage.setTitle("Java Byte Editor rc1"); 41 | 42 | 43 | // Вешаем dragAndDrop 44 | final Controller finalController = controller; 45 | 46 | root.setOnDragOver(event -> { 47 | event.consume(); 48 | event.acceptTransferModes(TransferMode.ANY); 49 | }); 50 | 51 | root.setOnDragDropped(event -> { 52 | Dragboard db = event.getDragboard(); 53 | 54 | if (db.hasFiles()) { 55 | List files = db.getFiles(); 56 | File file = files.get(0); 57 | 58 | if (!file.isFile()) { 59 | return; 60 | } 61 | 62 | finalController.openFile(file); 63 | 64 | event.consume(); 65 | } 66 | }); 67 | primaryStage.setScene(new Scene(root, 300, 275)); 68 | 69 | primaryStage.show(); 70 | 71 | } 72 | 73 | 74 | public static void main(String[] args) { 75 | try { 76 | launch(args); 77 | } catch (Throwable t) { 78 | t.printStackTrace(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/MissingInstruction.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor; 2 | 3 | 4 | public class MissingInstruction extends Exception { 5 | public MissingInstruction(String msg) { 6 | super(msg); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/about/Controller.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor.gui.about; 2 | 3 | /** 4 | * Created by Lopatin on 25.06.2014. 5 | */ 6 | public class Controller { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/about/View.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/error/Controller.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor.gui.error; 2 | 3 | /** 4 | * Created by Lopatin on 09.07.2014. 5 | */ 6 | public class Controller { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/error/View.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/main/Controller.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor.gui.main; 2 | 3 | import javafx.collections.FXCollections; 4 | import javafx.event.EventHandler; 5 | import javafx.fxml.FXML; 6 | import javafx.fxml.FXMLLoader; 7 | import javafx.fxml.JavaFXBuilderFactory; 8 | import javafx.scene.Parent; 9 | import javafx.scene.Scene; 10 | import javafx.scene.control.ListView; 11 | import javafx.scene.control.TabPane; 12 | import javafx.scene.control.TreeItem; 13 | import javafx.scene.control.TreeView; 14 | import javafx.scene.layout.GridPane; 15 | import javafx.scene.layout.VBox; 16 | import javafx.stage.*; 17 | import net.ptnkjke.jbeditor.Configutation; 18 | import net.ptnkjke.jbeditor.gui.main.model.ConsoleMessage; 19 | import net.ptnkjke.jbeditor.gui.main.model.MessageType; 20 | import net.ptnkjke.jbeditor.gui.main.model.classtree.*; 21 | import net.ptnkjke.jbeditor.gui.main.model.classtree.ConstantPool; 22 | import net.ptnkjke.jbeditor.gui.main.panes.methodpane.MethodModel; 23 | import net.ptnkjke.jbeditor.gui.main.panes.methodpane.MethodUtils; 24 | import net.ptnkjke.jbeditor.gui.main.panes.generalinfopane.Utils; 25 | import net.ptnkjke.jbeditor.logic.Core; 26 | import org.apache.bcel.Const; 27 | import org.apache.bcel.classfile.*; 28 | import org.apache.bcel.generic.ClassGen; 29 | 30 | import java.io.File; 31 | import java.io.FileInputStream; 32 | import java.io.IOException; 33 | import java.util.jar.JarInputStream; 34 | import java.util.zip.ZipEntry; 35 | 36 | /** 37 | * Created by Lopatin on 25.06.2014. 38 | */ 39 | public class Controller { 40 | 41 | @FXML 42 | private VBox root; 43 | @FXML 44 | private GridPane firstPane; 45 | @FXML 46 | private GridPane secondPane; 47 | @FXML 48 | private TreeView mainTree; 49 | @FXML 50 | private ListView consoleid; 51 | 52 | private ClassGen classGen; 53 | 54 | private boolean classFile = false; 55 | 56 | private File source; 57 | 58 | @FXML 59 | private void initialize() { 60 | // 61 | Static.setConsoleid(consoleid); 62 | 63 | // Загружаем по умолчанию mainPain 64 | GridPane root = null; 65 | FXMLLoader fxmlLoader = null; 66 | 67 | fxmlLoader = new FXMLLoader(); 68 | fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()); 69 | 70 | try { 71 | root = (GridPane) fxmlLoader.load(getClass().getResource("/net/ptnkjke/jbeditor/gui/main/panes/defaultpane/View.fxml").openStream()); 72 | } catch (IOException e) { 73 | e.printStackTrace(); 74 | } 75 | 76 | root.setMaxWidth(10000); 77 | root.setMaxHeight(10000); 78 | secondPane.getChildren().add(root); 79 | 80 | 81 | // Вешаем слушателя 82 | mainTree.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> { 83 | if (newValue == null) { 84 | return; 85 | } 86 | 87 | if (newValue.getValue() instanceof net.ptnkjke.jbeditor.gui.main.model.classtree.Method) { 88 | net.ptnkjke.jbeditor.gui.main.model.classtree.Method method = (net.ptnkjke.jbeditor.gui.main.model.classtree.Method) newValue.getValue(); 89 | 90 | // Загружаем для правой части 91 | MethodModel m = new MethodModel(method.getClassGen().getClassName(), method.getMethodIndex()); 92 | 93 | GridPane gridPane = MethodUtils.loadView(m); 94 | 95 | secondPane.getChildren().clear(); 96 | secondPane.getChildren().add(gridPane); 97 | } else if (newValue.getValue() instanceof ConstantPool) { 98 | ConstantPool constantPool = (ConstantPool) newValue.getValue(); 99 | TabPane pane = net.ptnkjke.jbeditor.gui.main.constantpanes.table.Static.loadView(constantPool.getClassGen()); 100 | secondPane.getChildren().clear(); 101 | secondPane.getChildren().add(pane); 102 | } else if (newValue.getValue() instanceof net.ptnkjke.jbeditor.gui.main.model.classtree.Constant) { 103 | net.ptnkjke.jbeditor.gui.main.model.classtree.Constant constant = (net.ptnkjke.jbeditor.gui.main.model.classtree.Constant) newValue.getValue(); 104 | org.apache.bcel.classfile.Constant const_bcel = constant.getConstant(); 105 | switch (constant.getConstant().getTag()) { 106 | case Const.CONSTANT_Utf8: 107 | ConstantUtf8 utf8 = (ConstantUtf8) const_bcel; 108 | break; 109 | case Const.CONSTANT_Integer: 110 | ConstantInteger integer = (ConstantInteger) const_bcel; 111 | break; 112 | case Const.CONSTANT_Float: 113 | ConstantFloat constantFloat = (ConstantFloat) const_bcel; 114 | break; 115 | case Const.CONSTANT_Long: 116 | ConstantLong constantLong = (ConstantLong) const_bcel; 117 | break; 118 | case Const.CONSTANT_Double: 119 | ConstantDouble constantDouble = (ConstantDouble) const_bcel; 120 | break; 121 | case Const.CONSTANT_Class: 122 | ConstantClass constantClass = (ConstantClass) const_bcel; 123 | break; 124 | case Const.CONSTANT_Fieldref: 125 | ConstantFieldref fieldref = (ConstantFieldref) const_bcel; 126 | break; 127 | case Const.CONSTANT_String: 128 | ConstantString string = (ConstantString) const_bcel; 129 | break; 130 | case Const.CONSTANT_Methodref: 131 | ConstantMethodref methodref = (ConstantMethodref) const_bcel; 132 | break; 133 | case Const.CONSTANT_InterfaceMethodref: 134 | ConstantInterfaceMethodref interfaceMethodref = (ConstantInterfaceMethodref) const_bcel; 135 | break; 136 | case Const.CONSTANT_NameAndType: 137 | ConstantNameAndType nameAndType = (ConstantNameAndType) const_bcel; 138 | break; 139 | case Const.CONSTANT_MethodHandle: 140 | ConstantMethodHandle methodHandle = (ConstantMethodHandle) const_bcel; 141 | break; 142 | case Const.CONSTANT_MethodType: 143 | ConstantMethodType methodType = (ConstantMethodType) const_bcel; 144 | break; 145 | default: 146 | try { 147 | throw new Exception(""); 148 | } catch (Exception e) { 149 | e.printStackTrace(); 150 | } 151 | } 152 | } else if (newValue.getValue() instanceof GeneralInformation) { 153 | ClassGen cg = ((GeneralInformation) newValue.getValue()).getClassGen(); 154 | 155 | // Загружаем для правой части 156 | VBox vbox = Utils.loadView(cg); 157 | secondPane.getChildren().clear(); 158 | secondPane.getChildren().add(vbox); 159 | } 160 | }); 161 | 162 | // Свой виджет 163 | consoleid.setCellFactory(param -> new FlowListCell()); 164 | } 165 | 166 | public void onButtonLoadClass() { 167 | // Вызываем диалоговое окно для выбора файла 168 | 169 | FileChooser fileChooser = new FileChooser(); 170 | fileChooser.getExtensionFilters() 171 | .addAll( 172 | new FileChooser.ExtensionFilter("Java Class", "*.class"), 173 | new FileChooser.ExtensionFilter("Jar", "*.jar") 174 | ); 175 | 176 | source = fileChooser.showOpenDialog(null); 177 | 178 | // Если файл не пустой, то производим открытие 179 | if (source == null) { 180 | return; 181 | } 182 | 183 | // Заполняем дерево 184 | openFile(source); 185 | } 186 | 187 | public void openFile(File file) { 188 | 189 | TreeItem rootNode = Info.createInfo(file.getName(), Root.class); 190 | mainTree.setRoot(rootNode); 191 | 192 | Core.INSTANCE.read(file.getAbsolutePath()); 193 | 194 | if (file.getName().contains(".jar")) { 195 | openJarFile(file); 196 | } else { 197 | classFile = true; 198 | openClassFile(file); 199 | } 200 | } 201 | 202 | private void openJarFile(File file) { 203 | // Принудительно загружаем класс 204 | //JarClassLoader classLoader = new JarClassLoader(file.getAbsolutePath()); 205 | 206 | JarInputStream jarInputStream = null; 207 | 208 | try{ 209 | jarInputStream = new JarInputStream(new FileInputStream(file)); 210 | } catch (IOException e) { 211 | ConsoleMessage consoleMessage = new ConsoleMessage( 212 | e.getClass().getName() + " " + e.getMessage(), 213 | MessageType.WARNING, 214 | "exception.openJarfile.IOException", 215 | e); 216 | Static.addMessage(consoleMessage); 217 | } 218 | 219 | try { 220 | ZipEntry next = jarInputStream.getNextEntry(); 221 | while (next != null) { 222 | if (next.getName().contains(".class")) { 223 | JavaClass javaClass = new ClassParser(file.getAbsolutePath(), next.getName()).parse(); 224 | 225 | addClassToTree(javaClass, false); 226 | } 227 | next = jarInputStream.getNextEntry(); 228 | } 229 | 230 | // Сортируем дерево на выходе 231 | FXCollections.sort(mainTree.getRoot().getChildren(), (o1, o2) -> o1.getValue().getTitle().compareTo(o2.getValue().getTitle())); 232 | 233 | } catch (IOException e) { 234 | ConsoleMessage consoleMessage = new ConsoleMessage( 235 | e.getClass().getName() + " " + e.getMessage(), 236 | MessageType.WARNING, 237 | "exception.openJarfile.IOException2", 238 | e); 239 | Static.addMessage(consoleMessage); 240 | } 241 | 242 | try { 243 | jarInputStream.close(); 244 | } catch (IOException e) { 245 | ConsoleMessage consoleMessage = new ConsoleMessage( 246 | e.getClass().getName() + " " + e.getMessage(), 247 | MessageType.WARNING, 248 | "exception.openJarfile.IOException3", 249 | e); 250 | Static.addMessage(consoleMessage); 251 | } 252 | } 253 | 254 | private void openClassFile(final File file) { 255 | 256 | JavaClass javaClass; 257 | try { 258 | javaClass = new ClassParser(file.getAbsolutePath()).parse(); 259 | } catch (IOException e) { 260 | e.printStackTrace(); 261 | return; 262 | } 263 | addClassToTree(javaClass, false); 264 | 265 | 266 | } 267 | 268 | private void addClassToTree(JavaClass javaClass, boolean toRoot) { 269 | ClassGen classGen = new ClassGen(javaClass); 270 | TreeItem rootNode = mainTree.getRoot(); 271 | 272 | TreeItem classNode = Info.createInfo(javaClass.getClassName(), Root.class); 273 | rootNode.getChildren().add(classNode); 274 | rootNode = classNode; 275 | 276 | TreeItem node = null; 277 | // GENERAL INFORMATION 278 | node = Info.createInfo("General Information", GeneralInformation.class); 279 | ((GeneralInformation) node.getValue()).setClassGen(classGen); 280 | rootNode.getChildren().add(node); 281 | 282 | // CONSTANT POOL 283 | node = Info.createInfo("Constant Pool", ConstantPool.class); 284 | rootNode.getChildren().add(node); 285 | ((ConstantPool) node.getValue()).setClassGen(classGen); 286 | 287 | org.apache.bcel.classfile.Constant[] constants = javaClass.getConstantPool().getConstantPool(); 288 | for (int i = 0; i < constants.length; i++) { 289 | org.apache.bcel.classfile.Constant constant = constants[i]; 290 | if (constant == null) { 291 | continue; 292 | } 293 | TreeItem inner = Info.createInfo("[" + i + "] " + constant.toString(), net.ptnkjke.jbeditor.gui.main.model.classtree.Constant.class); 294 | ((net.ptnkjke.jbeditor.gui.main.model.classtree.Constant) inner.getValue()).setConstant(constant); 295 | node.getChildren().add(inner); 296 | } 297 | 298 | // INTERFACES 299 | node = Info.createInfo("Interfaces", Interfaces.class); 300 | rootNode.getChildren().add(node); 301 | 302 | try { 303 | JavaClass[] intrefaces = javaClass.getInterfaces(); 304 | for (JavaClass inter : intrefaces) { 305 | TreeItem inner = Info.createInfo(inter.toString(), Interface.class); 306 | node.getChildren().add(inner); 307 | } 308 | } catch (ClassNotFoundException e) { 309 | ConsoleMessage consoleMessage = new ConsoleMessage( 310 | e.getMessage(), 311 | MessageType.WARNING, 312 | "exception.addClassToTree.ClassNotFound", 313 | e); 314 | Static.addMessage(consoleMessage); 315 | } 316 | 317 | // METHODS 318 | node = Info.createInfo("Methods", Methods.class); 319 | rootNode.getChildren().add(node); 320 | 321 | org.apache.bcel.classfile.Method[] methods = javaClass.getMethods(); 322 | int methodIndex = 0; 323 | for (org.apache.bcel.classfile.Method method : methods) { 324 | TreeItem inner = Info.createInfo(method.toString(), net.ptnkjke.jbeditor.gui.main.model.classtree.Method.class); 325 | ((net.ptnkjke.jbeditor.gui.main.model.classtree.Method) inner.getValue()).setMethodIndex(methodIndex); 326 | ((net.ptnkjke.jbeditor.gui.main.model.classtree.Method) inner.getValue()).setClassGen(classGen); 327 | 328 | node.getChildren().add(inner); 329 | methodIndex++; 330 | } 331 | 332 | // ATTRIBUTES 333 | node = Info.createInfo("Attributes", Attributes.class); 334 | rootNode.getChildren().add(node); 335 | 336 | org.apache.bcel.classfile.Attribute[] attributes = javaClass.getAttributes(); 337 | for (org.apache.bcel.classfile.Attribute attribute : attributes) { 338 | TreeItem inner = Info.createInfo(attribute.toString(), net.ptnkjke.jbeditor.gui.main.model.classtree.Attribute.class); 339 | node.getChildren().add(inner); 340 | } 341 | } 342 | 343 | /** 344 | * Save Change 345 | */ 346 | public void saveChange() { 347 | Core.INSTANCE.save(); 348 | } 349 | 350 | // Окно с настройками 351 | public void openPreferences() { 352 | Parent root = null; 353 | try { 354 | FXMLLoader fxmlLoader = new FXMLLoader(); 355 | //fxmlLoader.setResources(ResourceBundle.getBundle("translation")); 356 | 357 | root = fxmlLoader.load(this.getClass().getResource("/net/ptnkjke/jbeditor/gui/preferences/View.fxml").openStream()); 358 | } catch (IOException e) { 359 | e.printStackTrace(); 360 | } 361 | Stage dialog = new Stage(); 362 | dialog.initStyle(StageStyle.UTILITY); 363 | dialog.setResizable(false); 364 | dialog.initModality(Modality.APPLICATION_MODAL); 365 | dialog.setScene(new Scene(root)); 366 | dialog.setTitle("preferences"); 367 | 368 | // Событие на закрытие окна 369 | dialog.setOnCloseRequest(new EventHandler() { 370 | @Override 371 | public void handle(WindowEvent windowEvent) { 372 | Configutation.save(); 373 | } 374 | }); 375 | 376 | dialog.show(); 377 | } 378 | 379 | public void onAbout() { 380 | 381 | } 382 | } 383 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/main/FlowListCell.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor.gui.main; 2 | 3 | import javafx.scene.control.Hyperlink; 4 | import javafx.scene.control.ListCell; 5 | import javafx.scene.paint.Color; 6 | import javafx.scene.text.Text; 7 | import javafx.scene.text.TextFlow; 8 | import net.ptnkjke.jbeditor.gui.main.model.ConsoleMessage; 9 | import net.ptnkjke.jbeditor.gui.main.model.MessageType; 10 | 11 | /** 12 | * Created by Lopatin on 08.07.2014. 13 | */ 14 | public class FlowListCell extends ListCell { 15 | 16 | @Override 17 | protected void updateItem(ConsoleMessage item, boolean empty) { 18 | super.updateItem(item, empty); 19 | 20 | if (item != null) { 21 | TextFlow textFlow = new TextFlow(); 22 | Text text = new Text(item.getMessage()); 23 | 24 | if (item.getType() == MessageType.CRITICAL) { 25 | text.setFill(Color.RED); 26 | } else if (item.getType() == MessageType.WARNING) { 27 | text.setFill(Color.DARKBLUE); 28 | } 29 | 30 | Hyperlink hyperlink = new Hyperlink("[description]"); 31 | 32 | 33 | textFlow.getChildren().addAll(text); 34 | textFlow.getChildren().add(hyperlink); 35 | 36 | setGraphic(textFlow); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/main/Static.java: -------------------------------------------------------------------------------- 1 | package net.ptnkjke.jbeditor.gui.main; 2 | 3 | import javafx.scene.control.ListView; 4 | import net.ptnkjke.jbeditor.gui.main.model.ConsoleMessage; 5 | 6 | /** 7 | * Created by Lopatin on 09.07.2014. 8 | */ 9 | public class Static { 10 | private static ListView consoleid; 11 | 12 | public static void setConsoleid(ListView consoleid_) { 13 | consoleid = consoleid_; 14 | } 15 | 16 | public static void addMessage(ConsoleMessage consoleMessage) { 17 | consoleid.getItems().addAll(consoleMessage); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/net/ptnkjke/jbeditor/gui/main/View.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |