feat(theme): 实现深色和浅色主题支持

- 在 MainWindow 中添加深色主题支持
- 修改 ModernJarViewer 以适配不同主题
- 在 build.gradle 中添加系统类加载器配置
This commit is contained in:
tzdwindows 7
2025-08-16 10:33:48 +08:00
parent 1a1750d5a6
commit 7d07e6d0e1
5 changed files with 86 additions and 35 deletions

View File

@@ -172,5 +172,8 @@ task runClient(type: JavaExec) {
description = "运行 com.axis.innovators.box.Main"
classpath = sourceSets.main.runtimeClasspath
mainClass = "com.axis.innovators.box.Main"
jvmArgs = ["-Dfile.encoding=UTF-8"]
jvmArgs = [
"-Dfile.encoding=UTF-8",
"-Djava.system.class.loader=com.axis.innovators.box.plugins.BoxClassLoader"
]
}

View File

@@ -1,3 +1,3 @@
#Current Loaded Language
#Thu Aug 14 20:44:49 CST 2025
#Fri Aug 15 19:03:09 CST 2025
loadedLanguage=system\:zh_CN

BIN
logo.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,5 +1,6 @@
package com.axis.innovators.box.decompilation.gui;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.window.LoadIcon;
import com.axis.innovators.box.util.AdvancedJFileChooser;
import com.github.javaparser.JavaParser;
@@ -294,6 +295,12 @@ public class ModernJarViewer extends JFrame {
setupKeyBindings();
}
private static boolean isDarkTheme() {
if (AxisInnovatorsBox.getMain() == null){
return false;
}
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
}
private File getAnnotationsFileForJar() {
if (currentJarFile == null) {
// fallback 存到 config 文件同目录或者用户家目录
@@ -864,9 +871,7 @@ public class ModernJarViewer extends JFrame {
"<ul>" +
"<li><b>CFR 0.152</b>: 当前支持的反混淆器</li>" +
"<li><b>Fernflower</b>: IntelliJ IDEA使用的反混淆器预留</li>" +
"<li><b>Procyon</b>: 另一个开源反混淆器(预留)</li>" +
"</ul>" +
"<p>注意: 当前仅支持CFR反混淆器其他选项为预留功能。</p>" +
"<li><b>Procyon</b>: 另一个开源反混淆器</li>" +
"</div></html>";
JOptionPane.showMessageDialog(this, helpText, "设置帮助", JOptionPane.INFORMATION_MESSAGE);
@@ -874,19 +879,27 @@ public class ModernJarViewer extends JFrame {
private void registerFileIcons() {
fileTree.setCellRenderer(new DefaultTreeCellRenderer() {
private final ImageIcon jarIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/file_jar.png", 18).getImage());
private final ImageIcon classIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/java_file.png", 18).getImage());
private final ImageIcon zipIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/zip_file.png", 12).getImage());
private final ImageIcon mcmetaIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/mcmeta_file.png", 12).getImage());
private final ImageIcon cfgIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/cfg_file.png", 12).getImage());
private final ImageIcon tomlIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/toml_file.png", 12).getImage());
private final ImageIcon exeIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/exe_file.png", 12).getImage());
private final Icon jarIcon = loadThemeAwareIcon("programming/JarApiViewer/file_jar.png", 18);
private final Icon classIcon = loadThemeAwareIcon("programming/JarApiViewer/java_file.png", 18);
private final Icon zipIcon = loadThemeAwareIcon("programming/JarApiViewer/zip_file.png", 12);
private final Icon mcmetaIcon = loadThemeAwareIcon("programming/JarApiViewer/mcmeta_file.png", 12);
private final Icon cfgIcon = loadThemeAwareIcon("programming/JarApiViewer/cfg_file.png", 12);
private final Icon tomlIcon = loadThemeAwareIcon("programming/JarApiViewer/toml_file.png", 12);
private final Icon exeIcon = loadThemeAwareIcon("programming/JarApiViewer/exe_file.png", 12);
private final Icon fileIcon = loadThemeAwareIcon("programming/JarApiViewer/file.png", 12);
private final Icon folderIcon = UIManager.getIcon("Tree.closedIcon"); // Changed to Icon
private final ImageIcon fileIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/file.png", 12).getImage()); // Changed to Icon
private final Icon folderIcon = UIManager.getIcon("Tree.closedIcon");
private Icon loadThemeAwareIcon(String path, int size) {
String actualPath = !isDarkTheme() ?
path.replace(".png", "_dark.png") :
path;
return new ImageIcon(LoadIcon.loadIcon(actualPath, size).getImage());
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
String name = node.getUserObject().toString();
@@ -2480,12 +2493,16 @@ public class ModernJarViewer extends JFrame {
}
private void configureIDEATheme(SyntaxScheme scheme, RSyntaxTextArea editor) {
Color background = new Color(0x1E1F22);
Color foreground = new Color(0xE0E0E0);
// 根据当前主题是深色还是浅色设置不同的背景和前景色
Color background = isDarkTheme() ? new Color(0x1E1F22) : new Color(0xFFFFFF);
Color foreground = isDarkTheme() ? new Color(0xE0E0E0) : new Color(0x000000);
Style defaultStyle = scheme.getStyle(Token.NULL);
defaultStyle.foreground = foreground;
defaultStyle.background = background;
// 深色主题和浅色主题的不同颜色配置
if (isDarkTheme()) {
setTokenStyle(scheme, Token.RESERVED_WORD, 0xCC7832);
setTokenStyle(scheme, Token.SEPARATOR, 0x4EC9B0);
setTokenStyle(scheme, Token.OPERATOR, 0xFFD700);
@@ -2499,9 +2516,27 @@ public class ModernJarViewer extends JFrame {
setTokenStyle(scheme, Token.FUNCTION, 0xFFC66D);
setTokenStyle(scheme, Token.DATA_TYPE, 0xE8BF6A);
editor.setBackground(background);
editor.setSelectionColor(new Color(0x214283));
editor.setCurrentLineHighlightColor(new Color(0x323232));
} else {
setTokenStyle(scheme, Token.RESERVED_WORD, 0x0000FF);
setTokenStyle(scheme, Token.SEPARATOR, 0x008000);
setTokenStyle(scheme, Token.OPERATOR, 0x000000);
setTokenStyle(scheme, Token.IDENTIFIER, 0x000000);
setTokenStyle(scheme, Token.LITERAL_STRING_DOUBLE_QUOTE, 0x008000);
setTokenStyle(scheme, Token.LITERAL_NUMBER_DECIMAL_INT, 0x0000FF);
setTokenStyle(scheme, Token.COMMENT_EOL, 0x008000);
setTokenStyle(scheme, Token.COMMENT_MULTILINE, 0x008000);
setTokenStyle(scheme, Token.COMMENT_DOCUMENTATION, 0x008000);
setTokenStyle(scheme, Token.ANNOTATION, 0x808000);
setTokenStyle(scheme, Token.FUNCTION, 0x000080);
setTokenStyle(scheme, Token.DATA_TYPE, 0x000080);
editor.setSelectionColor(new Color(0xADD6FF));
editor.setCurrentLineHighlightColor(new Color(0xE8E8E8));
}
editor.setBackground(background);
editor.setHighlightCurrentLine(true);
}

View File

@@ -127,6 +127,9 @@ public class MainWindow extends JFrame {
});
setLocationRelativeTo(null);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(1200, 800);
}
/**
@@ -154,8 +157,6 @@ public class MainWindow extends JFrame {
getContentPane().removeAll();
setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.title"));
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(1200, 800);
// 主容器
JPanel mainPanel = new JPanel(new BorderLayout());
@@ -877,7 +878,7 @@ public class MainWindow extends JFrame {
return card;
}
private boolean isDarkTheme() {
private static boolean isDarkTheme() {
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
}
@@ -1183,7 +1184,19 @@ public class MainWindow extends JFrame {
}
public void addTool(ToolItem tool) { tools.add(tool); }
public String getDescription() { return description; }
public String getIcon() { return icon; }
public String getIcon() {
if (isDarkTheme()) {
int lastDotIndex = 0;
if (icon != null) {
lastDotIndex = icon.lastIndexOf('.');
}
if (lastDotIndex > 0) {
return icon.substring(0, lastDotIndex) + "_dark" + icon.substring(lastDotIndex);
}
return icon + "_dark";
}
return icon;
}
public String getName() { return name; }
public List<ToolItem> getTools() { return tools; }
public ImageIcon getIconImage() { return iconImage; }