[Go-To] Move caret to requested field.
- Also added enum constant declarations to the token parser.
This commit is contained in:
parent
afeab95f0b
commit
e756324245
|
@ -30,9 +30,7 @@ import the.bytecode.club.bytecodeviewer.util.JTextAreaUtils;
|
|||
import javax.swing.*;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* Searching on an RSyntaxTextArea using swing highlighting
|
||||
|
@ -87,6 +85,24 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
|
|||
GlobalHotKeys.keyPressed(keyEvent);
|
||||
}));
|
||||
|
||||
setCursor(new Cursor(Cursor.TEXT_CURSOR));
|
||||
getCaret().setBlinkRate(0);
|
||||
getCaret().setVisible(true);
|
||||
addFocusListener(new FocusAdapter()
|
||||
{
|
||||
@Override
|
||||
public void focusGained(FocusEvent e)
|
||||
{
|
||||
getCaret().setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e)
|
||||
{
|
||||
getCaret().setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
final Font newFont = getFont().deriveFont((float) BytecodeViewer.viewer.getFontSize());
|
||||
|
||||
//set number-bar font
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
package the.bytecode.club.bytecodeviewer.gui.components.actions;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.Token;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel;
|
||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.util.BytecodeViewPanelUpdater;
|
||||
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.locations.ClassFieldLocation;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.parser.TokenUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.text.Element;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by Bl3nd.
|
||||
|
@ -36,20 +39,14 @@ public class GoToAction extends AbstractAction
|
|||
container.fieldMembers.values().forEach(fields -> fields.forEach(field -> {
|
||||
if (field.line == line && field.columnStart - 1 <= column && field.columnEnd >= column)
|
||||
{
|
||||
Element root = textArea.getDocument().getDefaultRootElement();
|
||||
// Open the class that is associated with the field's owner.
|
||||
if (!field.owner.equals(container.getName()))
|
||||
{
|
||||
ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer());
|
||||
if (resourceContainer != null)
|
||||
{
|
||||
String s = container.getImport(field.owner);
|
||||
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, s + ".class");
|
||||
}
|
||||
|
||||
openFieldClass(field, textArea);
|
||||
return;
|
||||
}
|
||||
|
||||
Element root = textArea.getDocument().getDefaultRootElement();
|
||||
ClassFieldLocation first = fields.get(0);
|
||||
int startOffset = root.getElement(first.line - 1).getStartOffset() + (first.columnStart - 1);
|
||||
textArea.setCaretPosition(startOffset);
|
||||
|
@ -100,4 +97,82 @@ public class GoToAction extends AbstractAction
|
|||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void openFieldClass(ClassFieldLocation field, RSyntaxTextArea textArea)
|
||||
{
|
||||
String token = textArea.modelToToken(textArea.getCaretPosition()).getLexeme();
|
||||
ResourceContainer resourceContainer = BytecodeViewer.getFileContainer(container.getParentContainer());
|
||||
if (resourceContainer != null)
|
||||
{
|
||||
String s = container.getImport(field.owner);
|
||||
BytecodeViewer.viewer.workPane.addClassResource(resourceContainer, s + ".class");
|
||||
ClassViewer activeResource = (ClassViewer) BytecodeViewer.viewer.workPane.getActiveResource();
|
||||
HashMap<String, ClassFileContainer> classFiles = BytecodeViewer.viewer.workPane.classFiles;
|
||||
Thread thread = new Thread(() -> {
|
||||
try
|
||||
{
|
||||
BytecodeViewer.updateBusyStatus(true);
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
} finally
|
||||
{
|
||||
BytecodeViewer.updateBusyStatus(false);
|
||||
}
|
||||
|
||||
String s2 = activeResource.resource.workingName + "-" + this.container.getDecompiler();
|
||||
ClassFileContainer classFileContainer = classFiles.get(s2);
|
||||
classFileContainer.fieldMembers.forEach((field1, field2) -> {
|
||||
if (field1.equals(token))
|
||||
{
|
||||
field2.forEach(classFieldLocation -> {
|
||||
if (classFieldLocation.type.equals("declaration"))
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
BytecodeViewPanel panel = activeResource.getPanel(i);
|
||||
if (panel.textArea != null)
|
||||
{
|
||||
if (panel.decompiler.getDecompilerName().equals(this.container.getDecompiler()))
|
||||
{
|
||||
Element root = panel.textArea.getDocument().getDefaultRootElement();
|
||||
int startOffset = root.getElement(classFieldLocation.line - 1).getStartOffset() + (classFieldLocation.columnStart - 1);
|
||||
panel.textArea.setCaretPosition(startOffset);
|
||||
for (CaretListener caretListener : panel.textArea.getCaretListeners())
|
||||
{
|
||||
if (caretListener instanceof BytecodeViewPanelUpdater.MarkerCaretListener)
|
||||
{
|
||||
BytecodeViewPanelUpdater.MarkerCaretListener markerCaretListener = (BytecodeViewPanelUpdater.MarkerCaretListener) caretListener;
|
||||
markerCaretListener.caretUpdate(new CaretEvent(panel.textArea)
|
||||
{
|
||||
@Override
|
||||
public int getDot()
|
||||
{
|
||||
return panel.textArea.getCaret().getDot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMark()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
panel.textArea.requestFocusInWindow();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
|
|||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.FileViewer;
|
||||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
|
||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJButton;
|
||||
|
@ -33,13 +34,10 @@ import the.bytecode.club.uikit.tabpopup.closer.PopupMenuTabsCloseConfiguration;
|
|||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.Constants.BLOCK_TAB_MENU;
|
||||
|
||||
/**
|
||||
* This pane contains all the resources, as tabs.
|
||||
*
|
||||
|
@ -54,6 +52,7 @@ public class Workspace extends TranslatedVisibleComponent {
|
|||
public final JPanel buttonPanel;
|
||||
public final JButton refreshClass;
|
||||
public final Set<String> openedTabs = new HashSet<>();
|
||||
public HashMap<String, ClassFileContainer> classFiles = new HashMap<>();
|
||||
|
||||
public Workspace() {
|
||||
super("Workspace", TranslatedComponents.WORK_SPACE);
|
||||
|
|
|
@ -27,7 +27,6 @@ import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
|
|||
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel;
|
||||
import the.bytecode.club.bytecodeviewer.resources.Resource;
|
||||
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
|
||||
import the.bytecode.club.bytecodeviewer.resources.classcontainer.ClassFileContainer;
|
||||
import the.bytecode.club.bytecodeviewer.util.MethodParser;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -38,7 +37,6 @@ import java.awt.event.ComponentEvent;
|
|||
import java.awt.event.HierarchyEvent;
|
||||
import java.awt.event.HierarchyListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static the.bytecode.club.bytecodeviewer.util.MethodParser.Method;
|
||||
|
@ -53,307 +51,316 @@ import static the.bytecode.club.bytecodeviewer.util.MethodParser.Method;
|
|||
|
||||
public class ClassViewer extends ResourceViewer
|
||||
{
|
||||
public JSplitPane sp;
|
||||
public JSplitPane sp2;
|
||||
public BytecodeViewPanel bytecodeViewPanel1 = new BytecodeViewPanel(0, this);
|
||||
public BytecodeViewPanel bytecodeViewPanel2 = new BytecodeViewPanel(1, this);
|
||||
public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this);
|
||||
public List<MethodParser> methods = Arrays.asList(new MethodParser(), new MethodParser(), new MethodParser());
|
||||
public HashMap<String, ClassFileContainer> classFiles = new HashMap<>();
|
||||
public JSplitPane sp;
|
||||
public JSplitPane sp2;
|
||||
public BytecodeViewPanel bytecodeViewPanel1 = new BytecodeViewPanel(0, this);
|
||||
public BytecodeViewPanel bytecodeViewPanel2 = new BytecodeViewPanel(1, this);
|
||||
public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this);
|
||||
public List<MethodParser> methods = Arrays.asList(new MethodParser(), new MethodParser(), new MethodParser());
|
||||
|
||||
public ClassViewer(ResourceContainer container, String name)
|
||||
{
|
||||
super(new Resource(name, container.getWorkingName(name), container));
|
||||
public ClassViewer(ResourceContainer container, String name)
|
||||
{
|
||||
super(new Resource(name, container.getWorkingName(name), container));
|
||||
|
||||
this.setName(name);
|
||||
this.setLayout(new BorderLayout());
|
||||
this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bytecodeViewPanel1, bytecodeViewPanel2);
|
||||
this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, bytecodeViewPanel3);
|
||||
this.add(sp2, BorderLayout.CENTER);
|
||||
this.setName(name);
|
||||
this.setLayout(new BorderLayout());
|
||||
this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bytecodeViewPanel1, bytecodeViewPanel2);
|
||||
this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, bytecodeViewPanel3);
|
||||
this.add(sp2, BorderLayout.CENTER);
|
||||
|
||||
this.addComponentListener(new ComponentAdapter()
|
||||
{
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e)
|
||||
{
|
||||
resetDivider();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.addComponentListener(new ComponentAdapter()
|
||||
{
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e)
|
||||
{
|
||||
resetDivider();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(JButton button)
|
||||
{
|
||||
setPanes();
|
||||
refreshTitle();
|
||||
@Override
|
||||
public void refresh(JButton button)
|
||||
{
|
||||
setPanes();
|
||||
refreshTitle();
|
||||
|
||||
bytecodeViewPanel1.createPane(this);
|
||||
bytecodeViewPanel2.createPane(this);
|
||||
bytecodeViewPanel3.createPane(this);
|
||||
bytecodeViewPanel1.createPane(this);
|
||||
bytecodeViewPanel2.createPane(this);
|
||||
bytecodeViewPanel3.createPane(this);
|
||||
|
||||
byte[] classBytes = getResourceBytes();
|
||||
byte[] classBytes = getResourceBytes();
|
||||
|
||||
//TODO remove this once all of the importers have been properly updated to use a FileContainerImporter
|
||||
if (classBytes == null || classBytes.length == 0 || Configuration.forceResourceUpdateFromClassNode)
|
||||
{
|
||||
//TODO remove this error message when all of the importers have been updated
|
||||
// only APK and DEX are left
|
||||
if (!Configuration.forceResourceUpdateFromClassNode)
|
||||
{
|
||||
System.err.println("WARNING: Class Resource imported using the old importer!");
|
||||
System.err.println("TODO: Update it to use the FileContainerImporter");
|
||||
}
|
||||
//TODO remove this once all of the importers have been properly updated to use a FileContainerImporter
|
||||
if (classBytes == null || classBytes.length == 0 || Configuration.forceResourceUpdateFromClassNode)
|
||||
{
|
||||
//TODO remove this error message when all of the importers have been updated
|
||||
// only APK and DEX are left
|
||||
if (!Configuration.forceResourceUpdateFromClassNode)
|
||||
{
|
||||
System.err.println("WARNING: Class Resource imported using the old importer!");
|
||||
System.err.println("TODO: Update it to use the FileContainerImporter");
|
||||
}
|
||||
|
||||
classBytes = ASMUtil.nodeToBytes(resource.getResourceClassNode());
|
||||
}
|
||||
classBytes = ASMUtil.nodeToBytes(resource.getResourceClassNode());
|
||||
}
|
||||
|
||||
bytecodeViewPanel1.updatePane(this, classBytes, button, isPanel1Editable());
|
||||
bytecodeViewPanel2.updatePane(this, classBytes, button, isPanel2Editable());
|
||||
bytecodeViewPanel3.updatePane(this, classBytes, button, isPanel3Editable());
|
||||
bytecodeViewPanel1.updatePane(this, classBytes, button, isPanel1Editable());
|
||||
bytecodeViewPanel2.updatePane(this, classBytes, button, isPanel2Editable());
|
||||
bytecodeViewPanel3.updatePane(this, classBytes, button, isPanel3Editable());
|
||||
|
||||
Thread dumpBuild = new Thread(() ->
|
||||
{
|
||||
BytecodeViewer.updateBusyStatus(true);
|
||||
Thread dumpBuild = new Thread(() ->
|
||||
{
|
||||
BytecodeViewer.updateBusyStatus(true);
|
||||
|
||||
while (Configuration.currentlyDumping)
|
||||
{
|
||||
//wait until it's not dumping
|
||||
try
|
||||
{
|
||||
Thread.sleep(100);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
while (Configuration.currentlyDumping)
|
||||
{
|
||||
//wait until it's not dumping
|
||||
try
|
||||
{
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeViewer.updateBusyStatus(false);
|
||||
BytecodeViewer.updateBusyStatus(false);
|
||||
|
||||
if (bytecodeViewPanel1.decompiler != Decompiler.NONE)
|
||||
bytecodeViewPanel1.updateThread.startNewThread();
|
||||
if (bytecodeViewPanel1.decompiler != Decompiler.NONE)
|
||||
bytecodeViewPanel1.updateThread.startNewThread();
|
||||
|
||||
if (bytecodeViewPanel2.decompiler != Decompiler.NONE)
|
||||
bytecodeViewPanel2.updateThread.startNewThread();
|
||||
if (bytecodeViewPanel2.decompiler != Decompiler.NONE)
|
||||
bytecodeViewPanel2.updateThread.startNewThread();
|
||||
|
||||
if (bytecodeViewPanel3.decompiler != Decompiler.NONE)
|
||||
bytecodeViewPanel3.updateThread.startNewThread();
|
||||
}, "ClassViewer Temp Dump");
|
||||
if (bytecodeViewPanel3.decompiler != Decompiler.NONE)
|
||||
bytecodeViewPanel3.updateThread.startNewThread();
|
||||
}, "ClassViewer Temp Dump");
|
||||
|
||||
dumpBuild.start();
|
||||
dumpBuild.start();
|
||||
|
||||
if (isPanel1Editable() || isPanel2Editable() || isPanel3Editable())
|
||||
{
|
||||
if (Configuration.warnForEditing)
|
||||
return;
|
||||
if (isPanel1Editable() || isPanel2Editable() || isPanel3Editable())
|
||||
{
|
||||
if (Configuration.warnForEditing)
|
||||
return;
|
||||
|
||||
Configuration.warnForEditing = true;
|
||||
Configuration.warnForEditing = true;
|
||||
|
||||
if (!BytecodeViewer.viewer.autoCompileOnRefresh.isSelected() && !BytecodeViewer.viewer.compileOnSave.isSelected())
|
||||
{
|
||||
BytecodeViewer.showMessage("Make sure to compile (File>Compile or Ctrl + T) whenever you want to " + "test or export your changes.\nYou can set compile automatically on refresh or on save " + "in the settings menu.");
|
||||
if (!BytecodeViewer.viewer.autoCompileOnRefresh.isSelected() && !BytecodeViewer.viewer.compileOnSave.isSelected())
|
||||
{
|
||||
BytecodeViewer.showMessage("Make sure to compile (File>Compile or Ctrl + T) whenever you want to " + "test or export your changes.\nYou can set compile automatically on refresh or on save " + "in the settings menu.");
|
||||
|
||||
SettingsSerializer.saveSettingsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingsSerializer.saveSettingsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPanes()
|
||||
{
|
||||
bytecodeViewPanel1.decompiler = BytecodeViewer.viewer.viewPane1.getSelectedDecompiler();
|
||||
bytecodeViewPanel2.decompiler = BytecodeViewer.viewer.viewPane2.getSelectedDecompiler();
|
||||
bytecodeViewPanel3.decompiler = BytecodeViewer.viewer.viewPane3.getSelectedDecompiler();
|
||||
}
|
||||
public void setPanes()
|
||||
{
|
||||
bytecodeViewPanel1.decompiler = BytecodeViewer.viewer.viewPane1.getSelectedDecompiler();
|
||||
bytecodeViewPanel2.decompiler = BytecodeViewer.viewer.viewPane2.getSelectedDecompiler();
|
||||
bytecodeViewPanel3.decompiler = BytecodeViewer.viewer.viewPane3.getSelectedDecompiler();
|
||||
}
|
||||
|
||||
public boolean isPanel1Editable()
|
||||
{
|
||||
setPanes();
|
||||
return BytecodeViewer.viewer.viewPane1.isPaneEditable();
|
||||
}
|
||||
public boolean isPanel1Editable()
|
||||
{
|
||||
setPanes();
|
||||
return BytecodeViewer.viewer.viewPane1.isPaneEditable();
|
||||
}
|
||||
|
||||
public boolean isPanel2Editable()
|
||||
{
|
||||
setPanes();
|
||||
return BytecodeViewer.viewer.viewPane2.isPaneEditable();
|
||||
}
|
||||
public boolean isPanel2Editable()
|
||||
{
|
||||
setPanes();
|
||||
return BytecodeViewer.viewer.viewPane2.isPaneEditable();
|
||||
}
|
||||
|
||||
public boolean isPanel3Editable()
|
||||
{
|
||||
setPanes();
|
||||
return BytecodeViewer.viewer.viewPane3.isPaneEditable();
|
||||
}
|
||||
public boolean isPanel3Editable()
|
||||
{
|
||||
setPanes();
|
||||
return BytecodeViewer.viewer.viewPane3.isPaneEditable();
|
||||
}
|
||||
|
||||
public BytecodeViewPanel getPanel(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return bytecodeViewPanel1;
|
||||
case 1:
|
||||
return bytecodeViewPanel2;
|
||||
case 2:
|
||||
return bytecodeViewPanel3;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void selectMethod(RSyntaxTextArea area, int methodLine)
|
||||
{
|
||||
if (methodLine != area.getCaretLineNumber())
|
||||
{
|
||||
setCaretLine(area, methodLine);
|
||||
setViewLine(area, methodLine);
|
||||
}
|
||||
}
|
||||
public static void selectMethod(RSyntaxTextArea area, int methodLine)
|
||||
{
|
||||
if (methodLine != area.getCaretLineNumber())
|
||||
{
|
||||
setCaretLine(area, methodLine);
|
||||
setViewLine(area, methodLine);
|
||||
}
|
||||
}
|
||||
|
||||
public static void selectMethod(ClassViewer classViewer, int paneId, Method method)
|
||||
{
|
||||
RSyntaxTextArea area = null;
|
||||
switch (paneId)
|
||||
{
|
||||
case 0:
|
||||
area = classViewer.bytecodeViewPanel1.updateThread.updateUpdaterTextArea;
|
||||
break;
|
||||
public static void selectMethod(ClassViewer classViewer, int paneId, Method method)
|
||||
{
|
||||
RSyntaxTextArea area = null;
|
||||
switch (paneId)
|
||||
{
|
||||
case 0:
|
||||
area = classViewer.bytecodeViewPanel1.updateThread.updateUpdaterTextArea;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
area = classViewer.bytecodeViewPanel2.updateThread.updateUpdaterTextArea;
|
||||
break;
|
||||
case 1:
|
||||
area = classViewer.bytecodeViewPanel2.updateThread.updateUpdaterTextArea;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
area = classViewer.bytecodeViewPanel3.updateThread.updateUpdaterTextArea;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
area = classViewer.bytecodeViewPanel3.updateThread.updateUpdaterTextArea;
|
||||
break;
|
||||
}
|
||||
|
||||
if (area != null)
|
||||
{
|
||||
MethodParser methods = classViewer.methods.get(paneId);
|
||||
if (methods != null)
|
||||
{
|
||||
int methodLine = methods.findMethod(method);
|
||||
if (area != null)
|
||||
{
|
||||
MethodParser methods = classViewer.methods.get(paneId);
|
||||
if (methods != null)
|
||||
{
|
||||
int methodLine = methods.findMethod(method);
|
||||
|
||||
if (methodLine != -1)
|
||||
selectMethod(area, methodLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (methodLine != -1)
|
||||
selectMethod(area, methodLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMaxViewLine(RSyntaxTextArea area)
|
||||
{
|
||||
Container parent = area.getParent();
|
||||
public static int getMaxViewLine(RSyntaxTextArea area)
|
||||
{
|
||||
Container parent = area.getParent();
|
||||
|
||||
if (parent instanceof JViewport)
|
||||
{
|
||||
JViewport viewport = (JViewport) parent;
|
||||
int y = viewport.getViewSize().height - viewport.getExtentSize().height;
|
||||
int lineHeight = area.getLineHeight();
|
||||
return y >= lineHeight ? y / lineHeight : 0;
|
||||
}
|
||||
if (parent instanceof JViewport)
|
||||
{
|
||||
JViewport viewport = (JViewport) parent;
|
||||
int y = viewport.getViewSize().height - viewport.getExtentSize().height;
|
||||
int lineHeight = area.getLineHeight();
|
||||
return y >= lineHeight ? y / lineHeight : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getViewLine(RSyntaxTextArea area)
|
||||
{
|
||||
Container parent = area.getParent();
|
||||
public static int getViewLine(RSyntaxTextArea area)
|
||||
{
|
||||
Container parent = area.getParent();
|
||||
|
||||
if (parent instanceof JViewport)
|
||||
{
|
||||
JViewport viewport = (JViewport) parent;
|
||||
Point point = viewport.getViewPosition();
|
||||
int lineHeight = area.getLineHeight();
|
||||
return point.y >= lineHeight ? point.y / lineHeight : 0;
|
||||
}
|
||||
if (parent instanceof JViewport)
|
||||
{
|
||||
JViewport viewport = (JViewport) parent;
|
||||
Point point = viewport.getViewPosition();
|
||||
int lineHeight = area.getLineHeight();
|
||||
return point.y >= lineHeight ? point.y / lineHeight : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void setViewLine(RSyntaxTextArea area, int line)
|
||||
{
|
||||
Container parent = area.getParent();
|
||||
public static void setViewLine(RSyntaxTextArea area, int line)
|
||||
{
|
||||
Container parent = area.getParent();
|
||||
|
||||
if (parent instanceof JViewport)
|
||||
{
|
||||
JViewport viewport = (JViewport) parent;
|
||||
int maxLine = ClassViewer.getMaxViewLine(area);
|
||||
line = Math.min(line, maxLine);
|
||||
viewport.setViewPosition(new Point(0, line * area.getLineHeight()));
|
||||
}
|
||||
}
|
||||
if (parent instanceof JViewport)
|
||||
{
|
||||
JViewport viewport = (JViewport) parent;
|
||||
int maxLine = ClassViewer.getMaxViewLine(area);
|
||||
line = Math.min(line, maxLine);
|
||||
viewport.setViewPosition(new Point(0, line * area.getLineHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void setCaretLine(RSyntaxTextArea area, int line)
|
||||
{
|
||||
try
|
||||
{
|
||||
area.setCaretPosition(area.getLineStartOffset(line));
|
||||
}
|
||||
catch (BadLocationException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
public static void setCaretLine(RSyntaxTextArea area, int line)
|
||||
{
|
||||
try
|
||||
{
|
||||
area.setCaretPosition(area.getLineStartOffset(line));
|
||||
} catch (BadLocationException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void resetDivider()
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
sp.setResizeWeight(0.5);
|
||||
public void resetDivider()
|
||||
{
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
sp.setResizeWeight(0.5);
|
||||
|
||||
if (bytecodeViewPanel2.decompiler != Decompiler.NONE && bytecodeViewPanel1.decompiler != Decompiler.NONE)
|
||||
setDividerLocation(sp, 0.5);
|
||||
else if (bytecodeViewPanel1.decompiler != Decompiler.NONE)
|
||||
setDividerLocation(sp, 1);
|
||||
else if (bytecodeViewPanel2.decompiler != Decompiler.NONE)
|
||||
{
|
||||
sp.setResizeWeight(1);
|
||||
setDividerLocation(sp, 0);
|
||||
}
|
||||
else
|
||||
setDividerLocation(sp, 0);
|
||||
if (bytecodeViewPanel2.decompiler != Decompiler.NONE && bytecodeViewPanel1.decompiler != Decompiler.NONE)
|
||||
setDividerLocation(sp, 0.5);
|
||||
else if (bytecodeViewPanel1.decompiler != Decompiler.NONE)
|
||||
setDividerLocation(sp, 1);
|
||||
else if (bytecodeViewPanel2.decompiler != Decompiler.NONE)
|
||||
{
|
||||
sp.setResizeWeight(1);
|
||||
setDividerLocation(sp, 0);
|
||||
} else
|
||||
setDividerLocation(sp, 0);
|
||||
|
||||
if (bytecodeViewPanel3.decompiler != Decompiler.NONE)
|
||||
{
|
||||
sp2.setResizeWeight(0.7);
|
||||
setDividerLocation(sp2, 0.7);
|
||||
if ((bytecodeViewPanel2.decompiler == Decompiler.NONE && bytecodeViewPanel1.decompiler != Decompiler.NONE) || (bytecodeViewPanel1.decompiler == Decompiler.NONE && bytecodeViewPanel2.decompiler != Decompiler.NONE))
|
||||
setDividerLocation(sp2, 0.5);
|
||||
else if (bytecodeViewPanel1.decompiler == Decompiler.NONE)
|
||||
setDividerLocation(sp2, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sp.setResizeWeight(1);
|
||||
sp2.setResizeWeight(0);
|
||||
setDividerLocation(sp2, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (bytecodeViewPanel3.decompiler != Decompiler.NONE)
|
||||
{
|
||||
sp2.setResizeWeight(0.7);
|
||||
setDividerLocation(sp2, 0.7);
|
||||
if ((bytecodeViewPanel2.decompiler == Decompiler.NONE && bytecodeViewPanel1.decompiler != Decompiler.NONE) || (bytecodeViewPanel1.decompiler == Decompiler.NONE && bytecodeViewPanel2.decompiler != Decompiler.NONE))
|
||||
setDividerLocation(sp2, 0.5);
|
||||
else if (bytecodeViewPanel1.decompiler == Decompiler.NONE)
|
||||
setDividerLocation(sp2, 0);
|
||||
} else
|
||||
{
|
||||
sp.setResizeWeight(1);
|
||||
sp2.setResizeWeight(0);
|
||||
setDividerLocation(sp2, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whoever wrote this function, THANK YOU!
|
||||
*/
|
||||
public static JSplitPane setDividerLocation(JSplitPane splitter, double proportion)
|
||||
{
|
||||
if (splitter.isShowing())
|
||||
{
|
||||
if (splitter.getWidth() > 0 && splitter.getHeight() > 0)
|
||||
splitter.setDividerLocation(proportion);
|
||||
else
|
||||
{
|
||||
splitter.addComponentListener(new ComponentAdapter()
|
||||
{
|
||||
@Override
|
||||
public void componentResized(ComponentEvent ce)
|
||||
{
|
||||
splitter.removeComponentListener(this);
|
||||
setDividerLocation(splitter, proportion);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
splitter.addHierarchyListener(new HierarchyListener()
|
||||
{
|
||||
@Override
|
||||
public void hierarchyChanged(HierarchyEvent e)
|
||||
{
|
||||
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && splitter.isShowing())
|
||||
{
|
||||
splitter.removeHierarchyListener(this);
|
||||
setDividerLocation(splitter, proportion);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Whoever wrote this function, THANK YOU!
|
||||
*/
|
||||
public static JSplitPane setDividerLocation(JSplitPane splitter, double proportion)
|
||||
{
|
||||
if (splitter.isShowing())
|
||||
{
|
||||
if (splitter.getWidth() > 0 && splitter.getHeight() > 0)
|
||||
splitter.setDividerLocation(proportion);
|
||||
else
|
||||
{
|
||||
splitter.addComponentListener(new ComponentAdapter()
|
||||
{
|
||||
@Override
|
||||
public void componentResized(ComponentEvent ce)
|
||||
{
|
||||
splitter.removeComponentListener(this);
|
||||
setDividerLocation(splitter, proportion);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else
|
||||
{
|
||||
splitter.addHierarchyListener(new HierarchyListener()
|
||||
{
|
||||
@Override
|
||||
public void hierarchyChanged(HierarchyEvent e)
|
||||
{
|
||||
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && splitter.isShowing())
|
||||
{
|
||||
splitter.removeHierarchyListener(this);
|
||||
setDividerLocation(splitter, proportion);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return splitter;
|
||||
}
|
||||
return splitter;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -8650495368920680024L;
|
||||
private static final long serialVersionUID = -8650495368920680024L;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ public class BytecodeViewPanelUpdater implements Runnable
|
|||
private final JButton button;
|
||||
private final byte[] classBytes;
|
||||
|
||||
public MarkerCaretListener markerCaretListener;
|
||||
private MyErrorStripe errorStripe;
|
||||
public SearchableRSyntaxTextArea updateUpdaterTextArea;
|
||||
public JComboBox<Integer> methodsList;
|
||||
public boolean isPanelEditable;
|
||||
|
@ -118,7 +120,7 @@ public class BytecodeViewPanelUpdater implements Runnable
|
|||
if (!container.hasBeenParsed)
|
||||
{
|
||||
container.parse();
|
||||
viewer.classFiles.put(viewer.resource.workingName + "-" + decompiler.getDecompilerName(), container);
|
||||
BytecodeViewer.viewer.workPane.classFiles.put(viewer.resource.workingName + "-" + decompiler.getDecompilerName(), container);
|
||||
container.hasBeenParsed = true;
|
||||
}
|
||||
|
||||
|
@ -399,9 +401,6 @@ public class BytecodeViewPanelUpdater implements Runnable
|
|||
bytecodeViewPanel.textArea = updateUpdaterTextArea;
|
||||
|
||||
bytecodeViewPanel.textArea.setMarkOccurrencesColor(Color.ORANGE);
|
||||
bytecodeViewPanel.textArea.setCursor(new Cursor(Cursor.TEXT_CURSOR));
|
||||
bytecodeViewPanel.textArea.getCaret().setVisible(true);
|
||||
bytecodeViewPanel.textArea.getCaret().setBlinkRate(0);
|
||||
bytecodeViewPanel.textArea.setHighlighter(new RSyntaxTextAreaHighlighterEx());
|
||||
|
||||
if (bytecodeViewPanel.decompiler != Decompiler.BYTECODE_DISASSEMBLER)
|
||||
|
@ -426,26 +425,19 @@ public class BytecodeViewPanelUpdater implements Runnable
|
|||
String editable = isPanelEditable ? " - " + EDITABLE : "";
|
||||
bytecodeViewPanel.textArea.getTextAreaSearchPanel().getTitleHeader().setText(decompiler.getDecompilerName() + editable);
|
||||
|
||||
MyErrorStripe errorStripe = new MyErrorStripe(bytecodeViewPanel.textArea);
|
||||
errorStripe = new MyErrorStripe(bytecodeViewPanel.textArea);
|
||||
bytecodeViewPanel.add(errorStripe, BorderLayout.LINE_END);
|
||||
|
||||
bytecodeViewPanel.revalidate();
|
||||
bytecodeViewPanel.repaint();
|
||||
|
||||
String classContainerName = viewer.resource.workingName + "-" + decompiler.getDecompilerName();
|
||||
ClassFileContainer classFileContainer = viewer.classFiles.get(classContainerName);
|
||||
ClassFileContainer classFileContainer = BytecodeViewer.viewer.workPane.classFiles.get(classContainerName);
|
||||
bytecodeViewPanel.textArea.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_DOWN_MASK), "goToAction");
|
||||
bytecodeViewPanel.textArea.getActionMap().put("goToAction", new GoToAction(classFileContainer));
|
||||
|
||||
bytecodeViewPanel.textArea.addCaretListener(e -> {
|
||||
if (bytecodeViewPanel.textArea.isFocusOwner())
|
||||
{
|
||||
RSyntaxTextAreaHighlighterEx highlighterEx = (RSyntaxTextAreaHighlighterEx) bytecodeViewPanel.textArea.getHighlighter();
|
||||
highlighterEx.clearMarkOccurrencesHighlights();
|
||||
RSyntaxTextArea textArea = (RSyntaxTextArea) e.getSource();
|
||||
markOccurrences(textArea, viewer.classFiles.get(classContainerName), errorStripe);
|
||||
}
|
||||
});
|
||||
markerCaretListener = new MarkerCaretListener(classContainerName);
|
||||
bytecodeViewPanel.textArea.addCaretListener(markerCaretListener);
|
||||
}
|
||||
|
||||
private void markOccurrences(RSyntaxTextArea textArea, ClassFileContainer classFileContainer, MyErrorStripe errorStripe)
|
||||
|
@ -627,4 +619,24 @@ public class BytecodeViewPanelUpdater implements Runnable
|
|||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public class MarkerCaretListener implements CaretListener
|
||||
{
|
||||
|
||||
private final String classContainerName;
|
||||
|
||||
public MarkerCaretListener(String classContainerName)
|
||||
{
|
||||
this.classContainerName = classContainerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void caretUpdate(CaretEvent e)
|
||||
{
|
||||
SearchableRSyntaxTextArea textArea = (SearchableRSyntaxTextArea) e.getSource();
|
||||
RSyntaxTextAreaHighlighterEx highlighterEx = (RSyntaxTextAreaHighlighterEx) bytecodeViewPanel.textArea.getHighlighter();
|
||||
highlighterEx.clearMarkOccurrencesHighlights();
|
||||
markOccurrences(textArea, BytecodeViewer.viewer.workPane.classFiles.get(classContainerName), errorStripe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,10 @@ public class ClassFileContainer
|
|||
return this.className.substring(this.className.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
public String getDecompiler() {
|
||||
return getName().substring(6);
|
||||
}
|
||||
|
||||
public String getParentContainer()
|
||||
{
|
||||
return this.parentContainer;
|
||||
|
|
|
@ -1312,6 +1312,12 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit all {@link LambdaExpr}'s.
|
||||
*
|
||||
* @param n The current {@code LambdaExpr}
|
||||
* @param arg Don't worry about it.
|
||||
*/
|
||||
@Override
|
||||
public void visit(LambdaExpr n, Object arg)
|
||||
{
|
||||
|
@ -1337,6 +1343,27 @@ public class MyVoidVisitor extends VoidVisitorAdapter<Object>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit all {@link EnumDeclaration}'s.
|
||||
*
|
||||
* @param n The current {@code EnumDeclaration}
|
||||
* @param arg Don't worry about it.
|
||||
*/
|
||||
@Override
|
||||
public void visit(EnumDeclaration n, Object arg)
|
||||
{
|
||||
super.visit(n, arg);
|
||||
n.getEntries().forEach(entry -> {
|
||||
SimpleName simpleName = entry.getName();
|
||||
String name = simpleName.getIdentifier();
|
||||
Range range = simpleName.getRange().get();
|
||||
int line = range.begin.line;
|
||||
int columnStart = range.begin.column;
|
||||
int columnEnd = range.end.column;
|
||||
this.classFileContainer.putField(name, new ClassFieldLocation(getOwner(), "declaration", line, columnStart, columnEnd + 1));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Look through the {@link CompilationUnit} for the specific statement within its methods.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue
Block a user