feat(gui): use SVG icons, xml resources impovements (PR #1221)

* fix(xml): add more file based resources type to skip
* fix(res): fix #1060, styles might contain dots in name
* fix(res): use lowercase name on deobfuscated\renamed resources names and id in hex format
* feat(gui): update gui under FlatLaf
* fix(gui): use FlatSVGIcon to fix icons brightness difference
* fix(gui): use source lines only decompiled java code
Co-authored-by: MrIkso <mrkso821@gmail.com>
This commit is contained in:
Yaroslav 2021-08-04 20:40:49 +03:00 committed by GitHub
parent 5f24193c49
commit ee12f0bd18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
193 changed files with 825 additions and 261 deletions

View File

@ -80,7 +80,7 @@ public class AndroidResourcesUtils {
@SuppressWarnings("RedundantCast")
public static boolean handleResourceFieldValue(ClassNode cls, ICodeWriter code, EncodedValue encodedValue) {
if (encodedValue.getType() == EncodedType.ENCODED_INT && isResourceClass(cls)) {
code.add(String.format("0x%X", ((Integer) encodedValue.getValue())));
code.add(String.format("0x%08x", ((Integer) encodedValue.getValue())));
return true;
}
return false;

View File

@ -191,7 +191,7 @@ public class ResTableParser extends CommonBinaryParser {
}
private String makeNewKeyName(int idx) {
return "JADX_DEOBF_" + idx;
return String.format("jadx_deobf_0x%08x", idx);
}
@SuppressWarnings("unused")
@ -251,7 +251,7 @@ public class ResTableParser extends CommonBinaryParser {
int resRef = pkg.getId() << 24 | typeId << 16 | entryId;
String typeName = pkg.getTypeStrings()[typeId - 1];
String origKeyName = pkg.getKeyStrings()[key];
ResourceEntry newResEntry = new ResourceEntry(resRef, pkg.getName(), typeName, getResName(resRef, origKeyName), config);
ResourceEntry newResEntry = new ResourceEntry(resRef, pkg.getName(), typeName, getResName(typeName, resRef, origKeyName), config);
ResourceEntry prevResEntry = resStorage.searchEntryWithSameName(newResEntry);
if (prevResEntry != null) {
newResEntry = newResEntry.copyWithId();
@ -280,7 +280,7 @@ public class ResTableParser extends CommonBinaryParser {
resStorage.add(newResEntry);
}
private String getResName(int resRef, String origKeyName) {
private String getResName(String typeName, int resRef, String origKeyName) {
if (this.useRawResName) {
return origKeyName;
}
@ -288,14 +288,17 @@ public class ResTableParser extends CommonBinaryParser {
if (renamedKey != null) {
return renamedKey;
}
if (VALID_RES_KEY_PATTERN.matcher(origKeyName).matches()) {
return origKeyName;
}
FieldNode constField = root.getConstValues().getGlobalConstFields().get(resRef);
if (constField != null) {
constField.add(AFlag.DONT_RENAME);
return constField.getName();
}
// styles might contain dots in name, use VALID_RES_KEY_PATTERN only for resource file name
if (typeName.equals("style")) {
return origKeyName;
} else if (VALID_RES_KEY_PATTERN.matcher(origKeyName).matches()) {
return origKeyName;
}
// Making sure origKeyName compliant with resource file name rules
Matcher m = VALID_RES_KEY_PATTERN.matcher(origKeyName);
StringBuilder sb = new StringBuilder();
@ -308,7 +311,7 @@ public class ResTableParser extends CommonBinaryParser {
first = false;
}
// autogenerate key name, appended with cleaned origKeyName to be human-friendly
String newResName = "res_" + resRef;
String newResName = String.format("res_0x%08x",resRef);
String cleanedResName = sb.toString();
if (!cleanedResName.isEmpty()) {
newResName += "_" + cleanedResName.toLowerCase();

View File

@ -23,10 +23,23 @@ import static jadx.core.xmlgen.ParserConstants.TYPE_REFERENCE;
public class ResXmlGen {
/**
* Skip only file based resource type
*/
private static final Set<String> SKIP_RES_TYPES = new HashSet<>(Arrays.asList(
"anim",
"animator",
"font",
"id", // skip id type, it is usually auto generated when used this syntax "@+id/my_id"
"interpolator",
"layout",
"menu",
"mipmap",
"id"));
"navigation",
"raw",
"transition",
"xml"
));
private final ResourceStorage resStorage;
private final ValuesParser vp;

View File

@ -35,7 +35,7 @@ public class XmlGenUtils {
Set<String> addedValues = new HashSet<>();
for (ResourceEntry ri : resStorage.getResources()) {
if (addedValues.add(ri.getTypeName() + '.' + ri.getKeyName())) {
String format = String.format("<public type=\"%s\" name=\"%s\" id=\"0x%X\" />",
String format = String.format("<public type=\"%s\" name=\"%s\" id=\"0x%08x\" />",
ri.getTypeName(), ri.getKeyName(), ri.getId());
writer.startLine(format);
}

View File

@ -33,7 +33,7 @@ public final class ResourceEntry {
}
public ResourceEntry copyWithId() {
return copy(keyName + "_RES_" + id);
return copy(String.format("%s_res_0x%08x",keyName,id));
}
public int getId() {

View File

@ -17,6 +17,8 @@ dependencies {
implementation 'com.formdev:flatlaf:1.4'
implementation 'com.formdev:flatlaf-intellij-themes:1.4'
implementation 'com.formdev:flatlaf-extras:1.4'
implementation 'com.formdev:svgSalamander:1.1.2.4'
implementation 'org.reflections:reflections:0.9.12'
implementation 'com.google.code.gson:gson:2.8.6'

View File

@ -22,9 +22,9 @@ import jadx.gui.device.debugger.SmaliDebugger.*;
import jadx.gui.device.debugger.smali.Smali;
import jadx.gui.device.debugger.smali.SmaliRegister;
import jadx.gui.treemodel.JClass;
import jadx.gui.ui.IDebugController;
import jadx.gui.ui.JDebuggerPanel;
import jadx.gui.ui.JDebuggerPanel.*;
import jadx.gui.ui.panel.IDebugController;
import jadx.gui.ui.panel.JDebuggerPanel;
import jadx.gui.ui.panel.JDebuggerPanel.*;
import static jadx.gui.device.debugger.SmaliDebugger.RuntimeType;

View File

@ -16,7 +16,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.ProgressPanel;
import jadx.gui.ui.panel.ProgressPanel;
import jadx.gui.utils.UiUtils;
/**

View File

@ -16,8 +16,8 @@ import com.google.gson.GsonBuilder;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.HtmlPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.panel.HtmlPanel;
import jadx.gui.ui.TabbedPane;
import jadx.gui.utils.UiUtils;
@ -29,7 +29,7 @@ public class QuarkReportNode extends JNode {
private static final Gson GSON = new GsonBuilder().create();
private static final ImageIcon ICON = UiUtils.openIcon("icon_quark");
private static final ImageIcon ICON = UiUtils.openSvgIcon("ui/analyze");
private final Path apkFile;
private String errorContent;

View File

@ -38,7 +38,7 @@ import jadx.core.utils.Utils;
import jadx.gui.JadxWrapper;
import jadx.gui.jobs.BackgroundExecutor;
import jadx.gui.treemodel.JMethod;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.TabbedPane;
import jadx.gui.utils.JNodeCache;

View File

@ -19,8 +19,8 @@ import com.android.apksig.ApkVerifier;
import jadx.api.ResourceFile;
import jadx.api.ResourceType;
import jadx.gui.JadxWrapper;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.HtmlPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.panel.HtmlPanel;
import jadx.gui.ui.TabbedPane;
import jadx.gui.utils.CertificateManager;
import jadx.gui.utils.NLS;
@ -31,7 +31,7 @@ public class ApkSignature extends JNode {
private static final Logger LOG = LoggerFactory.getLogger(ApkSignature.class);
private static final ImageIcon CERTIFICATE_ICON = UiUtils.openIcon("certificate_obj");
private static final ImageIcon CERTIFICATE_ICON = UiUtils.openSvgIcon("nodes/styleKeyPack");
private final transient File openFile;
private String content;

View File

@ -2,6 +2,7 @@ package jadx.gui.treemodel;
import javax.swing.*;
import jadx.gui.ui.panel.ContentPanel;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.jetbrains.annotations.Nullable;
@ -12,7 +13,6 @@ import jadx.api.JavaMethod;
import jadx.api.JavaNode;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.info.AccessInfo;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.TabbedPane;
import jadx.gui.ui.codearea.ClassCodeContentPanel;
import jadx.gui.utils.NLS;
@ -21,13 +21,14 @@ import jadx.gui.utils.UiUtils;
public class JClass extends JLoadableNode {
private static final long serialVersionUID = -1239986875244097177L;
private static final ImageIcon ICON_CLASS = UiUtils.openIcon("class_obj");
private static final ImageIcon ICON_CLASS_DEFAULT = UiUtils.openIcon("class_default_obj");
private static final ImageIcon ICON_CLASS_PRIVATE = UiUtils.openIcon("innerclass_private_obj");
private static final ImageIcon ICON_CLASS_PROTECTED = UiUtils.openIcon("innerclass_protected_obj");
private static final ImageIcon ICON_INTERFACE = UiUtils.openIcon("int_obj");
private static final ImageIcon ICON_ENUM = UiUtils.openIcon("enum_obj");
private static final ImageIcon ICON_ANNOTATION = UiUtils.openIcon("annotation_obj");
private static final ImageIcon ICON_CLASS = UiUtils.openSvgIcon("nodes/class");
private static final ImageIcon ICON_CLASS_ABSTRACT = UiUtils.openSvgIcon("nodes/abstractClass");
private static final ImageIcon ICON_CLASS_PUBLIC = UiUtils.openSvgIcon("nodes/publicClass");
private static final ImageIcon ICON_CLASS_PRIVATE = UiUtils.openSvgIcon("nodes/privateClass");
private static final ImageIcon ICON_CLASS_PROTECTED = UiUtils.openSvgIcon("nodes/protectedClass");
private static final ImageIcon ICON_INTERFACE = UiUtils.openSvgIcon("nodes/interface");
private static final ImageIcon ICON_ENUM = UiUtils.openSvgIcon("nodes/enum");
private static final ImageIcon ICON_ANNOTATION = UiUtils.openSvgIcon("nodes/annotationtype");
private final transient JavaClass cls;
private final transient JClass jParent;
@ -130,6 +131,9 @@ public class JClass extends JLoadableNode {
if (accessInfo.isInterface()) {
return ICON_INTERFACE;
}
if (accessInfo.isAbstract()) {
return ICON_CLASS_ABSTRACT;
}
if (accessInfo.isProtected()) {
return ICON_CLASS_PROTECTED;
}
@ -137,9 +141,9 @@ public class JClass extends JLoadableNode {
return ICON_CLASS_PRIVATE;
}
if (accessInfo.isPublic()) {
return ICON_CLASS;
return ICON_CLASS_PUBLIC;
}
return ICON_CLASS_DEFAULT;
return ICON_CLASS;
}
@Override

View File

@ -15,14 +15,10 @@ import jadx.gui.utils.UiUtils;
public class JField extends JNode {
private static final long serialVersionUID = 1712572192106793359L;
private static final ImageIcon ICON_FLD_DEF = UiUtils.openIcon("field_default_obj");
private static final ImageIcon ICON_FLD_PRI = UiUtils.openIcon("field_private_obj");
private static final ImageIcon ICON_FLD_PRO = UiUtils.openIcon("field_protected_obj");
private static final ImageIcon ICON_FLD_PUB = UiUtils.openIcon("field_public_obj");
private static final ImageIcon ICON_TRANSIENT = UiUtils.openIcon("transient_co");
private static final ImageIcon ICON_VOLATILE = UiUtils.openIcon("volatile_co");
private static final ImageIcon ICON_FLD_DEF = UiUtils.openSvgIcon("nodes/field");
private static final ImageIcon ICON_FLD_PRI = UiUtils.openSvgIcon("nodes/privateField");
private static final ImageIcon ICON_FLD_PRO = UiUtils.openSvgIcon("nodes/protectedField");
private static final ImageIcon ICON_FLD_PUB = UiUtils.openSvgIcon("nodes/publicField");
private final transient JavaField field;
private final transient JClass jParent;
@ -64,12 +60,6 @@ public class JField extends JNode {
public Icon getIcon() {
AccessInfo af = field.getAccessFlags();
OverlayIcon icon = UiUtils.makeIcon(af, ICON_FLD_PUB, ICON_FLD_PRI, ICON_FLD_PRO, ICON_FLD_DEF);
if (af.isTransient()) {
icon.add(ICON_TRANSIENT);
}
if (af.isVolatile()) {
icon.add(ICON_VOLATILE);
}
return icon;
}

View File

@ -12,22 +12,23 @@ import jadx.api.JavaNode;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.TabbedPane;
import jadx.gui.ui.codearea.ClassCodeContentPanel;
import jadx.gui.utils.OverlayIcon;
import jadx.gui.utils.UiUtils;
import sun.security.mscapi.PRNG;
public class JMethod extends JNode {
private static final long serialVersionUID = 3834526867464663751L;
private static final ImageIcon ICON_MTH_DEF = UiUtils.openIcon("methdef_obj");
private static final ImageIcon ICON_MTH_PRI = UiUtils.openIcon("methpri_obj");
private static final ImageIcon ICON_MTH_PRO = UiUtils.openIcon("methpro_obj");
private static final ImageIcon ICON_MTH_PUB = UiUtils.openIcon("methpub_obj");
private static final ImageIcon ICON_CONSTRUCTOR = UiUtils.openIcon("constr_ovr");
private static final ImageIcon ICON_SYNC = UiUtils.openIcon("synch_co");
private static final ImageIcon ICON_METHOD = UiUtils.openSvgIcon("nodes/method");
private static final ImageIcon ICON_METHOD_ABSTRACT = UiUtils.openSvgIcon("nodes/abstractMethod");
private static final ImageIcon ICON_METHOD_PRIVATE = UiUtils.openSvgIcon("nodes/privateMethod");
private static final ImageIcon ICON_METHOD_PROTECTED = UiUtils.openSvgIcon("nodes/protectedMethod");
private static final ImageIcon ICON_METHOD_PUBLIC = UiUtils.openSvgIcon("nodes/publicMethod");
private static final ImageIcon ICON_METHOD_CONSTRUCTOR = UiUtils.openSvgIcon("nodes/constructorMethod");
private static final ImageIcon ICON_METHOD_SYNC = UiUtils.openSvgIcon("nodes/methodReference");
private final transient JavaMethod mth;
private final transient JClass jParent;
@ -73,14 +74,35 @@ public class JMethod extends JNode {
@Override
public Icon getIcon() {
AccessInfo accessFlags = mth.getAccessFlags();
OverlayIcon icon = UiUtils.makeIcon(accessFlags, ICON_MTH_PUB, ICON_MTH_PRI, ICON_MTH_PRO, ICON_MTH_DEF);
Icon icon = ICON_METHOD;
if(accessFlags.isAbstract()){
icon = ICON_METHOD_ABSTRACT;
}
if (accessFlags.isConstructor()) {
icon.add(ICON_CONSTRUCTOR);
icon = ICON_METHOD_CONSTRUCTOR;
}
if(accessFlags.isPublic()){
icon= ICON_METHOD_PUBLIC;
}
if(accessFlags.isPrivate()){
icon = ICON_METHOD_PRIVATE;
}
if(accessFlags.isProtected()){
icon = ICON_METHOD_PROTECTED;
}
if (accessFlags.isSynchronized()) {
icon.add(ICON_SYNC);
icon= ICON_METHOD_SYNC;
}
return icon;
OverlayIcon overIcon = new OverlayIcon(icon);
if (accessFlags.isFinal()) {
overIcon.add(UiUtils.ICON_FINAL);
}
if (accessFlags.isStatic()) {
overIcon.add(UiUtils.ICON_STATIC);
}
return overIcon;
}
@Override

View File

@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
import jadx.api.ICodeInfo;
import jadx.api.JadxDecompiler;
import jadx.api.JavaNode;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.TabbedPane;
public abstract class JNode extends DefaultMutableTreeNode {

View File

@ -16,7 +16,7 @@ import jadx.gui.utils.UiUtils;
public class JPackage extends JNode implements Comparable<JPackage> {
private static final long serialVersionUID = -4120718634156839804L;
private static final ImageIcon PACKAGE_ICON = UiUtils.openIcon("package_obj");
private static final ImageIcon PACKAGE_ICON = UiUtils.openSvgIcon("nodes/package");
private String fullName;
private String name;

View File

@ -21,8 +21,8 @@ import jadx.api.ResourcesLoader;
import jadx.api.impl.SimpleCodeInfo;
import jadx.core.utils.Utils;
import jadx.core.xmlgen.ResContainer;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.ImagePanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.panel.ImagePanel;
import jadx.gui.ui.TabbedPane;
import jadx.gui.ui.codearea.CodeContentPanel;
import jadx.gui.utils.NLS;
@ -32,12 +32,16 @@ import jadx.gui.utils.UiUtils;
public class JResource extends JLoadableNode implements Comparable<JResource> {
private static final long serialVersionUID = -201018424302612434L;
private static final ImageIcon ROOT_ICON = UiUtils.openIcon("cf_obj");
private static final ImageIcon FOLDER_ICON = UiUtils.openIcon("folder");
private static final ImageIcon FILE_ICON = UiUtils.openIcon("file_obj");
private static final ImageIcon MANIFEST_ICON = UiUtils.openIcon("template_obj");
private static final ImageIcon JAVA_ICON = UiUtils.openIcon("java_ovr");
private static final ImageIcon ERROR_ICON = UiUtils.openIcon("error_co");
private static final ImageIcon ROOT_ICON = UiUtils.openSvgIcon("nodes/resourcesRoot");
private static final ImageIcon FOLDER_ICON = UiUtils.openSvgIcon("nodes/folder");
private static final ImageIcon FILE_ICON = UiUtils.openSvgIcon("nodes/file_any_type");
private static final ImageIcon ARSC_ICON = UiUtils.openSvgIcon("nodes/resourceBundle");
private static final ImageIcon XML_ICON = UiUtils.openSvgIcon("nodes/xml");
private static final ImageIcon IMAGE_ICON = UiUtils.openSvgIcon("nodes/ImagesFileType");
private static final ImageIcon SO_ICON = UiUtils.openSvgIcon("nodes/binaryFile");
private static final ImageIcon MANIFEST_ICON = UiUtils.openSvgIcon("nodes/manifest");
private static final ImageIcon JAVA_ICON = UiUtils.openSvgIcon("nodes/java");
private static final ImageIcon UNKNOWN_ICON = UiUtils.openSvgIcon("nodes/unknown");
public enum JResType {
ROOT,
@ -274,16 +278,23 @@ public class JResource extends JLoadableNode implements Comparable<JResource> {
case FILE:
ResourceType resType = resFile.getType();
if (resType == ResourceType.MANIFEST) {
return MANIFEST_ICON;
switch (resType){
case MANIFEST:
return MANIFEST_ICON;
case ARSC:
return ARSC_ICON;
case XML:
return XML_ICON;
case IMG:
return IMAGE_ICON;
case LIB:
return SO_ICON;
case CODE:
return JAVA_ICON;
case UNKNOWN:
return UNKNOWN_ICON;
}
if (resType == ResourceType.CODE) {
return new OverlayIcon(FILE_ICON, ERROR_ICON, JAVA_ICON);
}
if (!isSupportedForView(resType)) {
return new OverlayIcon(FILE_ICON, ERROR_ICON);
}
return FILE_ICON;
return UNKNOWN_ICON;
}
return FILE_ICON;
}

View File

@ -22,7 +22,7 @@ import jadx.gui.utils.UiUtils;
public class JRoot extends JNode {
private static final long serialVersionUID = 8888495789773527342L;
private static final ImageIcon ROOT_ICON = UiUtils.openIcon("java_model_obj");
private static final ImageIcon ROOT_ICON = UiUtils.openSvgIcon("nodes/rootPackageFolder");
private final transient JadxWrapper wrapper;

View File

@ -18,7 +18,7 @@ import jadx.gui.utils.UiUtils;
public class JSources extends JNode {
private static final long serialVersionUID = 8962924556824862801L;
private static final ImageIcon ROOT_ICON = UiUtils.openIcon("packagefolder_obj");
private static final ImageIcon ROOT_ICON = UiUtils.openSvgIcon("nodes/packageClasses");
private final transient JadxWrapper wrapper;
private final transient boolean flatPackages;

View File

@ -74,6 +74,11 @@ import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import jadx.gui.ui.dialog.*;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.panel.JDebuggerPanel;
import jadx.gui.ui.panel.ProgressPanel;
import jadx.gui.ui.popupmenu.JPackagePopupMenu;
import org.fife.ui.rsyntaxtextarea.Theme;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -137,24 +142,24 @@ public class MainWindow extends JFrame {
private static final double WINDOW_RATIO = 1 - BORDER_RATIO * 2;
public static final double SPLIT_PANE_RESIZE_WEIGHT = 0.15;
private static final ImageIcon ICON_OPEN = UiUtils.openIcon("folder");
private static final ImageIcon ICON_ADD_FILES = UiUtils.openIcon("folder_add");
private static final ImageIcon ICON_SAVE_ALL = UiUtils.openIcon("disk_multiple");
private static final ImageIcon ICON_EXPORT = UiUtils.openIcon("database_save");
private static final ImageIcon ICON_CLOSE = UiUtils.openIcon("cross");
private static final ImageIcon ICON_SYNC = UiUtils.openIcon("sync");
private static final ImageIcon ICON_FLAT_PKG = UiUtils.openIcon("empty_logical_package_obj");
private static final ImageIcon ICON_SEARCH = UiUtils.openIcon("wand");
private static final ImageIcon ICON_FIND = UiUtils.openIcon("magnifier");
private static final ImageIcon ICON_COMMENT_SEARCH = UiUtils.openIcon("table_edit");
private static final ImageIcon ICON_BACK = UiUtils.openIcon("icon_back");
private static final ImageIcon ICON_FORWARD = UiUtils.openIcon("icon_forward");
private static final ImageIcon ICON_QUARK = UiUtils.openIcon("icon_quark");
private static final ImageIcon ICON_PREF = UiUtils.openIcon("wrench");
private static final ImageIcon ICON_DEOBF = UiUtils.openIcon("lock_edit");
private static final ImageIcon ICON_LOG = UiUtils.openIcon("report");
private static final ImageIcon ICON_JADX = UiUtils.openIcon("jadx-logo");
private static final ImageIcon ICON_DEBUGGER = UiUtils.openIcon("debugger");
private static final ImageIcon ICON_OPEN = UiUtils.openSvgIcon("ui/openDisk");
private static final ImageIcon ICON_ADD_FILES = UiUtils.openSvgIcon("ui/addFile");
private static final ImageIcon ICON_SAVE_ALL = UiUtils.openSvgIcon("ui/menu-saveall");
private static final ImageIcon ICON_EXPORT = UiUtils.openSvgIcon("ui/export");
private static final ImageIcon ICON_EXIT = UiUtils.openSvgIcon("ui/exit");
private static final ImageIcon ICON_SYNC = UiUtils.openSvgIcon("ui/pagination");
private static final ImageIcon ICON_FLAT_PKG = UiUtils.openSvgIcon("ui/moduleGroup");
private static final ImageIcon ICON_SEARCH = UiUtils.openSvgIcon("ui/find");
private static final ImageIcon ICON_FIND = UiUtils.openSvgIcon("ui/ejbFinderMethod");
private static final ImageIcon ICON_COMMENT_SEARCH = UiUtils.openSvgIcon("ui/usagesFinder");
private static final ImageIcon ICON_BACK = UiUtils.openSvgIcon("ui/left");
private static final ImageIcon ICON_FORWARD = UiUtils.openSvgIcon("ui/right");
private static final ImageIcon ICON_QUARK = UiUtils.openSvgIcon("ui/analyze");
private static final ImageIcon ICON_PREF = UiUtils.openSvgIcon("ui/settings");
private static final ImageIcon ICON_DEOBF = UiUtils.openSvgIcon("ui/helmChartLock");
private static final ImageIcon ICON_LOG = UiUtils.openSvgIcon("ui/logVerbose");
private static final ImageIcon ICON_INFO = UiUtils.openSvgIcon("ui/showInfos");
private static final ImageIcon ICON_DEBUGGER = UiUtils.openSvgIcon("ui/startDebugger");
private final transient JadxWrapper wrapper;
private final transient JadxSettings settings;
@ -833,7 +838,7 @@ public class MainWindow extends JFrame {
prefsAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_P,
UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK));
Action exitAction = new AbstractAction(NLS.str("file.exit"), ICON_CLOSE) {
Action exitAction = new AbstractAction(NLS.str("file.exit"), ICON_EXIT) {
@Override
public void actionPerformed(ActionEvent e) {
closeWindow();
@ -917,14 +922,14 @@ public class MainWindow extends JFrame {
Action logAction = new AbstractAction(NLS.str("menu.log"), ICON_LOG) {
@Override
public void actionPerformed(ActionEvent e) {
new LogViewer(MainWindow.this).setVisible(true);
new LogViewerDialog(MainWindow.this).setVisible(true);
}
};
logAction.putValue(Action.SHORT_DESCRIPTION, NLS.str("menu.log"));
logAction.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_L,
UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK));
Action aboutAction = new AbstractAction(NLS.str("menu.about"), ICON_JADX) {
Action aboutAction = new AbstractAction(NLS.str("menu.about"), ICON_INFO) {
@Override
public void actionPerformed(ActionEvent e) {
new AboutDialog().setVisible(true);

View File

@ -12,14 +12,15 @@ import javax.swing.plaf.basic.BasicButtonUI;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
public class TabComponent extends JPanel {
private static final long serialVersionUID = -8147035487543610321L;
private static final ImageIcon ICON_CLOSE = UiUtils.openIcon("cross");
private static final ImageIcon ICON_CLOSE_INACTIVE = UiUtils.openIcon("cross_grayed");
private static final ImageIcon ICON_CLOSE = UiUtils.openSvgIcon("ui/closeHovered");
private static final ImageIcon ICON_CLOSE_INACTIVE = UiUtils.openSvgIcon("ui/close");
private final TabbedPane tabbedPane;
private final ContentPanel contentPanel;

View File

@ -16,6 +16,9 @@ import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.panel.HtmlPanel;
import jadx.gui.ui.panel.ImagePanel;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -119,7 +122,7 @@ public class TabbedPane extends JTabbedPane {
lastTab = null;
return;
}
FocusManager.focusOnCodePanel(tab);
// FocusManager.focusOnCodePanel(tab);
if (tab == curTab) { // a tab was closed by not the current one.
if (lastTab != null && indexOfComponent(lastTab) == -1) { // lastTab was closed
setLastTabAdjacentToCurTab();
@ -194,7 +197,7 @@ public class TabbedPane extends JTabbedPane {
codeArea.scrollToLine(line);
}
}
codeArea.requestFocus();
//codeArea.requestFocus();
});
}
@ -237,7 +240,7 @@ public class TabbedPane extends JTabbedPane {
smaliArea.scrollToDebugPos(pos);
}
smaliArea.scrollToPos(pos);
smaliArea.requestFocus();
//smaliArea.requestFocus();
}
@Nullable
@ -303,7 +306,7 @@ public class TabbedPane extends JTabbedPane {
}
@Nullable
ContentPanel getSelectedCodePanel() {
public ContentPanel getSelectedCodePanel() {
return (ContentPanel) getSelectedComponent();
}

View File

@ -32,7 +32,7 @@ import jadx.core.utils.StringUtils;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.DefaultPopupMenuListener;
import jadx.gui.utils.JumpPosition;
@ -53,6 +53,9 @@ public abstract class AbstractCodeArea extends RSyntaxTextArea {
setMarkOccurrences(false);
setEditable(false);
setCodeFoldingEnabled(false);
setFadeCurrentLineHighlight(true);
setCloseCurlyBraces(true);
setAntiAliasingEnabled(true);
loadSettings();
JadxSettings settings = contentPanel.getTabbedPane().getMainWindow().getSettings();
setLineWrap(settings.isCodeAreaLineWrap());

View File

@ -1,7 +1,7 @@
package jadx.gui.ui.codearea;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.TabbedPane;
/**

View File

@ -21,7 +21,7 @@ import jadx.api.JavaNode;
import jadx.gui.settings.JadxProject;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.CaretPositionFix;
import jadx.gui.utils.DefaultPopupMenuListener;
@ -37,12 +37,13 @@ public final class CodeArea extends AbstractCodeArea {
private static final Logger LOG = LoggerFactory.getLogger(CodeArea.class);
private static final long serialVersionUID = 6312736869579635796L;
private final boolean isJavaCode;
CodeArea(ContentPanel contentPanel) {
super(contentPanel);
setSyntaxEditingStyle(node.getSyntaxName());
boolean isJavaCode = node instanceof JClass;
isJavaCode = node instanceof JClass;
if (isJavaCode) {
((RSyntaxDocument) getDocument()).setSyntaxStyle(new JadxTokenMaker(this));
addMenuItems();
@ -243,4 +244,8 @@ public final class CodeArea extends AbstractCodeArea {
public JadxProject getProject() {
return getMainWindow().getProject();
}
public boolean isJavaCode() {
return isJavaCode;
}
}

View File

@ -1,23 +1,14 @@
package jadx.gui.ui.codearea;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.*;
import javax.swing.JPopupMenu.Separator;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.PopupMenuEvent;
@ -28,7 +19,7 @@ import org.slf4j.LoggerFactory;
import jadx.api.ICodeInfo;
import jadx.core.utils.StringUtils;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.SearchDialog;
import jadx.gui.ui.dialog.SearchDialog;
import jadx.gui.utils.CaretPositionFix;
import jadx.gui.utils.DefaultPopupMenuListener;
import jadx.gui.utils.NLS;
@ -133,16 +124,23 @@ public class CodePanel extends JPanel {
if (codeArea instanceof SmaliArea) {
return false;
}
ICodeInfo codeInfo = codeArea.getNode().getCodeInfo();
if (codeInfo == null) {
return false;
if (codeArea instanceof CodeArea) {
CodeArea code = (CodeArea) codeArea;
if (!code.isJavaCode()) {
return false;
}
ICodeInfo codeInfo = code.getNode().getCodeInfo();
if (codeInfo == null) {
return false;
}
Map<Integer, Integer> lineMapping = codeInfo.getLineMapping();
if (lineMapping.isEmpty()) {
return false;
}
Set<Integer> uniqueSourceLines = new HashSet<>(lineMapping.values());
return uniqueSourceLines.size() > 3;
}
Map<Integer, Integer> lineMapping = codeInfo.getLineMapping();
if (lineMapping.isEmpty()) {
return false;
}
Set<Integer> uniqueSourceLines = new HashSet<>(lineMapping.values());
return uniqueSourceLines.size() > 3;
return false;
}
public SearchBar getSearchBar() {

View File

@ -22,7 +22,7 @@ import jadx.api.data.impl.JadxCodeComment;
import jadx.api.data.impl.JadxNodeRef;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.CommentDialog;
import jadx.gui.ui.dialog.CommentDialog;
import jadx.gui.utils.CodeLinesInfo;
import jadx.gui.utils.DefaultPopupMenuListener;
import jadx.gui.utils.NLS;

View File

@ -7,7 +7,7 @@ import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.KeyStroke;
import jadx.gui.ui.SearchDialog;
import jadx.gui.ui.dialog.SearchDialog;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;

View File

@ -8,7 +8,7 @@ import javax.swing.*;
import org.jetbrains.annotations.Nullable;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.UsageDialog;
import jadx.gui.ui.dialog.UsageDialog;
import jadx.gui.utils.NLS;
import static javax.swing.KeyStroke.getKeyStroke;

View File

@ -74,13 +74,20 @@ public class LineNumbers extends JPanel implements CaretListener {
setPreferredWidth();
codeArea.addCaretListener(this);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
useSourceLines = !useSourceLines;
repaint();
// use source lines only decompiled java code
if (codeArea instanceof CodeArea) {
CodeArea code = (CodeArea) codeArea;
if (code.isJavaCode()) {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
useSourceLines = !useSourceLines;
repaint();
}
});
}
});
}
}
public void setBorderGap(int borderGap) {

View File

@ -10,7 +10,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.RenameDialog;
import jadx.gui.ui.dialog.RenameDialog;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;

View File

@ -27,11 +27,11 @@ class SearchBar extends JToolBar {
private static final Color COLOR_BG_ERROR = new Color(0xFFDFDE);
private static final Color COLOR_BG_WARN = new Color(0xFFFDD9);
private static final Color COLOR_BG_NORMAL = new Color(0xFFFFFF);
//private static final Color COLOR_BG_NORMAL = new Color(0xFFFFFF);
private static final Icon ICON_UP = UiUtils.openIcon("arrow_up");
private static final Icon ICON_DOWN = UiUtils.openIcon("arrow_down");
private static final Icon ICON_CLOSE = UiUtils.openIcon("cross");
private static final Icon ICON_UP = UiUtils.openSvgIcon("ui/top");
private static final Icon ICON_DOWN = UiUtils.openSvgIcon("ui/bottom");
private static final Icon ICON_CLOSE = UiUtils.openSvgIcon("ui/close");
private RSyntaxTextArea rTextArea;
@ -148,7 +148,7 @@ class SearchBar extends JToolBar {
context.setMarkAll(markAllCB.isSelected());
// TODO hack: move cursor before previous search for not jump to next occurrence
if (direction == 0 && !COLOR_BG_ERROR.equals(searchField.getBackground())) {
/*if (direction == 0) {
try {
int caretPos = rTextArea.getCaretPosition();
int lineNum = rTextArea.getLineOfOffset(caretPos) - 1;
@ -158,7 +158,7 @@ class SearchBar extends JToolBar {
} catch (BadLocationException e) {
LOG.error("Caret move error", e);
}
}
}*/
SearchResult result = SearchEngine.find(rTextArea, context);
if (!result.wasFound()) {
@ -166,12 +166,12 @@ class SearchBar extends JToolBar {
if (pos != -1) {
rTextArea.setCaretPosition(forward ? 0 : rTextArea.getDocument().getLength() - 1);
search(direction);
searchField.setBackground(COLOR_BG_WARN);
//searchField.setBackground(COLOR_BG_WARN);
return;
}
searchField.setBackground(COLOR_BG_ERROR);
//searchField.setBackground(COLOR_BG_ERROR);
} else {
searchField.setBackground(COLOR_BG_NORMAL);
//searchField.setBackground(COLOR_BG_NORMAL);
}
}

View File

@ -23,17 +23,17 @@ import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.TextNode;
import jadx.gui.ui.ContentPanel;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
public final class SmaliArea extends AbstractCodeArea {
private static final long serialVersionUID = 1334485631870306494L;
private static final Icon ICON_BREAKPOINT = UiUtils.openIcon("breakpoint");
private static final Icon ICON_BREAKPOINT_DISABLED = UiUtils.openIcon("breakpoint_disabled");
private static final Color BREAKPOINT_LINE_COLOR = Color.decode("#FF986E");
private static final Color DEBUG_LINE_COLOR = Color.decode("#80B4FF");
private static final Icon ICON_BREAKPOINT = UiUtils.openSvgIcon("debugger/db_set_breakpoint");
private static final Icon ICON_BREAKPOINT_DISABLED = UiUtils.openSvgIcon("debugger/db_disabled_breakpoint");
private static final Color BREAKPOINT_LINE_COLOR = Color.decode("#ad103c");
private static final Color DEBUG_LINE_COLOR = Color.decode("#9c1138");
private final JNode textNode;
private final JCheckBoxMenuItem cbUseSmaliV2;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import java.awt.event.MouseAdapter;
@ -17,6 +17,8 @@ import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.device.debugger.DbgUtils;
import jadx.gui.device.protocol.ADB;
import jadx.gui.treemodel.JClass;
import jadx.gui.ui.panel.IDebugController;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
@ -24,8 +26,8 @@ import static jadx.gui.device.protocol.ADB.Device.*;
public class ADBDialog extends JDialog implements ADB.DeviceStateListener, ADB.JDWPProcessListener {
private static final long serialVersionUID = -1111111202102181630L;
private static final ImageIcon ICON_DEVICE = UiUtils.openIcon("device");
private static final ImageIcon ICON_PROCESS = UiUtils.openIcon("process");
private static final ImageIcon ICON_DEVICE = UiUtils.openSvgIcon("adb/androidDevice");
private static final ImageIcon ICON_PROCESS = UiUtils.openSvgIcon("adb/addToWatch");
private static DebugSetting debugSetter = null;
private final transient MainWindow mainWindow;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import java.net.URL;
@ -9,7 +9,7 @@ import jadx.api.JadxDecompiler;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
class AboutDialog extends JDialog {
public class AboutDialog extends JDialog {
private static final long serialVersionUID = 5763493590584039096L;
public AboutDialog() {

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.BorderLayout;
import java.awt.Component;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.Color;
import java.awt.Component;
@ -38,6 +38,9 @@ import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.panel.ProgressPanel;
import jadx.gui.ui.TabbedPane;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rtextarea.SearchContext;
import org.fife.ui.rtextarea.SearchEngine;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import java.awt.event.MouseAdapter;
@ -12,12 +12,13 @@ import javax.swing.*;
import javax.swing.tree.*;
import jadx.api.JavaPackage;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
public class ExcludePkgDialog extends JDialog {
private static final long serialVersionUID = -1111111202104151030L;
private static final ImageIcon PACKAGE_ICON = UiUtils.openIcon("package_obj");
private static final ImageIcon PACKAGE_ICON = UiUtils.openSvgIcon("nodes/package");
private final transient MainWindow mainWindow;
private transient JTree tree;
@ -285,8 +286,8 @@ public class ExcludePkgDialog extends JDialog {
boolean hasFocus) {
if (value instanceof PkgNode) {
PkgNode node = (PkgNode) value;
node.checkbox.setBackground(Color.white);
node.checkbox.setForeground(Color.black);
node.checkbox.setBackground(tree.getBackground());
node.checkbox.setForeground(tree.getForeground());
return node.checkbox;
}
Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);

View File

@ -1,9 +1,10 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import javax.swing.*;
import jadx.gui.ui.MainWindow;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import ch.qos.logback.classic.Level;
@ -14,7 +15,7 @@ import jadx.gui.utils.NLS;
import jadx.gui.utils.logs.ILogListener;
import jadx.gui.utils.logs.LogCollector;
class LogViewer extends JDialog {
public class LogViewerDialog extends JDialog {
private static final long serialVersionUID = -2188700277429054641L;
private static final Level[] LEVEL_ITEMS = { Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR };
@ -23,7 +24,7 @@ class LogViewer extends JDialog {
private final transient JadxSettings settings;
private transient RSyntaxTextArea textPane;
public LogViewer(MainWindow mainWindow) {
public LogViewerDialog(MainWindow mainWindow) {
this.settings = mainWindow.getSettings();
initUI(mainWindow);
registerLogListener();

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.BorderLayout;
import java.awt.Container;
@ -23,6 +23,9 @@ import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.TabbedPane;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import java.awt.event.KeyAdapter;
@ -21,6 +21,7 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import jadx.gui.ui.MainWindow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import java.awt.event.ActionEvent;
@ -11,7 +11,8 @@ import javax.swing.*;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.ui.JDebuggerPanel.ValueTreeNode;
import jadx.gui.ui.panel.JDebuggerPanel.ValueTreeNode;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.NLS;
import jadx.gui.utils.TextStandardActions;
import jadx.gui.utils.UiUtils;

View File

@ -1,10 +1,11 @@
package jadx.gui.ui;
package jadx.gui.ui.dialog;
import java.awt.*;
import javax.swing.*;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.CodeUsageInfo;
import jadx.gui.utils.NLS;

View File

@ -1,7 +1,8 @@
package jadx.gui.ui;
package jadx.gui.ui.panel;
import javax.swing.*;
import jadx.gui.ui.TabbedPane;
import org.jetbrains.annotations.Nullable;
import jadx.gui.treemodel.JClass;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.panel;
import java.awt.*;
@ -6,6 +6,7 @@ import javax.swing.*;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.TabbedPane;
public final class HtmlPanel extends ContentPanel {
private static final long serialVersionUID = -6251262855835426245L;

View File

@ -1,7 +1,8 @@
package jadx.gui.ui;
package jadx.gui.ui.panel;
import jadx.core.dex.instructions.args.ArgType;
import jadx.gui.ui.JDebuggerPanel.ValueTreeNode;
import jadx.gui.ui.panel.JDebuggerPanel;
import jadx.gui.ui.panel.JDebuggerPanel.ValueTreeNode;
public interface IDebugController {
boolean startDebugger(JDebuggerPanel panel, String[] args);

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.panel;
import java.awt.*;
import java.awt.image.BufferedImage;
@ -6,6 +6,7 @@ import java.io.ByteArrayInputStream;
import javax.imageio.ImageIO;
import jadx.gui.ui.TabbedPane;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import hu.kazocsaba.imageviewer.ImageViewer;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.panel;
import java.awt.*;
import java.awt.event.*;
@ -12,21 +12,24 @@ import io.reactivex.annotations.Nullable;
import jadx.core.utils.StringUtils;
import jadx.gui.device.debugger.DebugController;
import jadx.gui.treemodel.JClass;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.popupmenu.VarTreePopupMenu;
import jadx.gui.ui.codearea.SmaliArea;
import jadx.gui.ui.dialog.ADBDialog;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;
public class JDebuggerPanel extends JPanel {
private static final long serialVersionUID = -1111111202102181631L;
private static final ImageIcon ICON_RUN = UiUtils.openIcon("run");
private static final ImageIcon ICON_RERUN = UiUtils.openIcon("rerun");
private static final ImageIcon ICON_PAUSE = UiUtils.openIcon("pause");
private static final ImageIcon ICON_STOP = UiUtils.openIcon("stop");
private static final ImageIcon ICON_STOP_GRAY = UiUtils.openIcon("stop_gray");
private static final ImageIcon ICON_STEP_INTO = UiUtils.openIcon("step_into");
private static final ImageIcon ICON_STEP_OVER = UiUtils.openIcon("step_over");
private static final ImageIcon ICON_STEP_OUT = UiUtils.openIcon("step_out");
private static final ImageIcon ICON_RUN = UiUtils.openSvgIcon("debugger/execute");
private static final ImageIcon ICON_RERUN = UiUtils.openSvgIcon("debugger/rerun");
private static final ImageIcon ICON_PAUSE = UiUtils.openSvgIcon("debugger/threadFrozen");
private static final ImageIcon ICON_STOP = UiUtils.openSvgIcon("debugger/suspend");
private static final ImageIcon ICON_STOP_GRAY = UiUtils.openSvgIcon("debugger/suspendGray");
private static final ImageIcon ICON_STEP_INTO = UiUtils.openSvgIcon("debugger/traceInto");
private static final ImageIcon ICON_STEP_OVER = UiUtils.openSvgIcon("debugger/traceOver");
private static final ImageIcon ICON_STEP_OUT = UiUtils.openSvgIcon("debugger/stepOut");
private final transient MainWindow mainWindow;
private final transient JList<IListElement> stackFrameList;
@ -86,12 +89,8 @@ public class JDebuggerPanel extends JPanel {
boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof ValueTreeNode) {
if (sel) {
setForeground(Color.WHITE);
} else if (((ValueTreeNode) value).isUpdated()) {
if (((ValueTreeNode) value).isUpdated()) {
setForeground(Color.RED);
} else {
setForeground(Color.BLACK);
}
}
return c;
@ -117,7 +116,7 @@ public class JDebuggerPanel extends JPanel {
JPanel headerPanel = new JPanel(new BorderLayout());
headerPanel.add(new Label(), BorderLayout.WEST);
headerPanel.add(initToolBar(), BorderLayout.CENTER);
JButton closeBtn = new JButton(UiUtils.openIcon("cross"));
JButton closeBtn = new JButton(UiUtils.openSvgIcon("ui/close"));
closeBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.panel;
import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
@ -13,13 +13,14 @@ import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.UiUtils;
public class ProgressPanel extends JPanel implements PropertyChangeListener {
private static final long serialVersionUID = -3238438119672015733L;
private static final Icon ICON_CANCEL = UiUtils.openIcon("cross");
private static final Icon ICON_CANCEL = UiUtils.openSvgIcon("ui/close");
private final JProgressBar progressBar;
private final JLabel progressLabel;

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.popupmenu;
import java.awt.event.ActionEvent;
import java.util.Arrays;
@ -6,6 +6,9 @@ import java.util.List;
import javax.swing.*;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.dialog.ExcludePkgDialog;
import jadx.gui.ui.dialog.RenameDialog;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -15,7 +18,7 @@ import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JPackage;
import jadx.gui.utils.NLS;
class JPackagePopupMenu extends JPopupMenu {
public class JPackagePopupMenu extends JPopupMenu {
private static final long serialVersionUID = -7781009781149224131L;
private static final Logger LOG = LoggerFactory.getLogger(JPackagePopupMenu.class);

View File

@ -1,4 +1,4 @@
package jadx.gui.ui;
package jadx.gui.ui.popupmenu;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
@ -8,7 +8,9 @@ import java.awt.event.ActionEvent;
import javax.swing.*;
import jadx.core.dex.instructions.args.ArgType;
import jadx.gui.ui.JDebuggerPanel.ValueTreeNode;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.panel.JDebuggerPanel.ValueTreeNode;
import jadx.gui.ui.dialog.SetValueDialog;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;

View File

@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
import jadx.gui.jobs.IndexService;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JRoot;
import jadx.gui.ui.SearchDialog;
import jadx.gui.ui.dialog.SearchDialog;
import jadx.gui.utils.search.CommentsIndex;
import jadx.gui.utils.search.TextSearchIndex;

View File

@ -1,25 +1,16 @@
package jadx.gui.utils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import ch.qos.logback.classic.Level;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
import jadx.cli.LogHelper;
import jadx.gui.settings.JadxSettings;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.formdev.flatlaf.FlatLaf;
import ch.qos.logback.classic.Level;
import jadx.cli.LogHelper;
import jadx.gui.settings.JadxSettings;
import javax.swing.*;
import java.util.*;
public class LafManager {
private static final Logger LOG = LoggerFactory.getLogger(LafManager.class);
@ -38,7 +29,9 @@ public class LafManager {
public static void updateLaf(JadxSettings settings) {
if (setupLaf(getThemeClass(settings))) {
// update all components
FlatLaf.updateUI();
FlatAnimatedLafChange.hideSnapshotWithAnimation();
}
}
@ -89,6 +82,7 @@ public class LafManager {
private static boolean applyLaf(String theme) {
try {
FlatAnimatedLafChange.showSnapshot();
UIManager.setLookAndFeel(theme);
return true;
} catch (Exception e) {

View File

@ -1,11 +1,16 @@
package jadx.gui.utils;
import java.awt.Component;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.ui.codearea.AbstractCodeArea;
import org.intellij.lang.annotations.MagicConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
@ -15,31 +20,11 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import org.intellij.lang.annotations.MagicConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.gui.ui.codearea.AbstractCodeArea;
public class UiUtils {
private static final Logger LOG = LoggerFactory.getLogger(UiUtils.class);
private static final ImageIcon ICON_STATIC = openIcon("static_co");
private static final ImageIcon ICON_FINAL = openIcon("final_co");
private static final ImageIcon ICON_ABSTRACT = openIcon("abstract_co");
private static final ImageIcon ICON_NATIVE = openIcon("native_co");
public static final ImageIcon ICON_STATIC = openSvgIcon("nodes/staticMark");
public static final ImageIcon ICON_FINAL = openSvgIcon("nodes/finalMark");
/**
* The minimum about of memory in bytes we are trying to keep free, otherwise the application may
@ -56,6 +41,11 @@ public class UiUtils {
private UiUtils() {
}
public static FlatSVGIcon openSvgIcon(String name) {
String iconPath = "icons/" + name + ".svg";
return new FlatSVGIcon(iconPath);
}
public static ImageIcon openIcon(String name) {
String iconPath = "/icons-16/" + name + ".png";
URL resource = UiUtils.class.getResource(iconPath);
@ -134,12 +124,6 @@ public class UiUtils {
if (af.isStatic()) {
overIcon.add(ICON_STATIC);
}
if (af.isAbstract()) {
overIcon.add(ICON_ABSTRACT);
}
if (af.isNative()) {
overIcon.add(ICON_NATIVE);
}
return overIcon;
}

View File

@ -19,22 +19,22 @@ import jadx.api.JavaNode;
import jadx.gui.treemodel.CodeNode;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.SearchDialog;
import jadx.gui.ui.dialog.SearchDialog;
import jadx.gui.utils.CacheObject;
import jadx.gui.utils.CodeLinesInfo;
import jadx.gui.utils.JNodeCache;
import jadx.gui.utils.JumpPosition;
import jadx.gui.utils.UiUtils;
import static jadx.gui.ui.SearchDialog.SearchOptions.ACTIVE_TAB;
import static jadx.gui.ui.SearchDialog.SearchOptions.CLASS;
import static jadx.gui.ui.SearchDialog.SearchOptions.CODE;
import static jadx.gui.ui.SearchDialog.SearchOptions.COMMENT;
import static jadx.gui.ui.SearchDialog.SearchOptions.FIELD;
import static jadx.gui.ui.SearchDialog.SearchOptions.IGNORE_CASE;
import static jadx.gui.ui.SearchDialog.SearchOptions.METHOD;
import static jadx.gui.ui.SearchDialog.SearchOptions.RESOURCE;
import static jadx.gui.ui.SearchDialog.SearchOptions.USE_REGEX;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.ACTIVE_TAB;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.CLASS;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.CODE;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.COMMENT;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.FIELD;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.IGNORE_CASE;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.METHOD;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.RESOURCE;
import static jadx.gui.ui.dialog.SearchDialog.SearchOptions.USE_REGEX;
public class TextSearchIndex {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Some files were not shown because too many files have changed in this diff Show More