feat(theme): 实现深色和浅色主题支持
- 在 MainWindow 中添加深色主题支持 - 修改 ModernJarViewer 以适配不同主题 - 在 build.gradle 中添加系统类加载器配置
This commit is contained in:
@@ -172,5 +172,8 @@ task runClient(type: JavaExec) {
|
|||||||
description = "运行 com.axis.innovators.box.Main"
|
description = "运行 com.axis.innovators.box.Main"
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
mainClass = "com.axis.innovators.box.Main"
|
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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#Current Loaded Language
|
#Current Loaded Language
|
||||||
#Thu Aug 14 20:44:49 CST 2025
|
#Fri Aug 15 19:03:09 CST 2025
|
||||||
loadedLanguage=system\:zh_CN
|
loadedLanguage=system\:zh_CN
|
||||||
|
|||||||
BIN
logo.ico
BIN
logo.ico
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 17 KiB |
@@ -1,5 +1,6 @@
|
|||||||
package com.axis.innovators.box.decompilation.gui;
|
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.window.LoadIcon;
|
||||||
import com.axis.innovators.box.util.AdvancedJFileChooser;
|
import com.axis.innovators.box.util.AdvancedJFileChooser;
|
||||||
import com.github.javaparser.JavaParser;
|
import com.github.javaparser.JavaParser;
|
||||||
@@ -294,6 +295,12 @@ public class ModernJarViewer extends JFrame {
|
|||||||
setupKeyBindings();
|
setupKeyBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isDarkTheme() {
|
||||||
|
if (AxisInnovatorsBox.getMain() == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
|
||||||
|
}
|
||||||
private File getAnnotationsFileForJar() {
|
private File getAnnotationsFileForJar() {
|
||||||
if (currentJarFile == null) {
|
if (currentJarFile == null) {
|
||||||
// fallback 存到 config 文件同目录或者用户家目录
|
// fallback 存到 config 文件同目录或者用户家目录
|
||||||
@@ -864,9 +871,7 @@ public class ModernJarViewer extends JFrame {
|
|||||||
"<ul>" +
|
"<ul>" +
|
||||||
"<li><b>CFR 0.152</b>: 当前支持的反混淆器</li>" +
|
"<li><b>CFR 0.152</b>: 当前支持的反混淆器</li>" +
|
||||||
"<li><b>Fernflower</b>: IntelliJ IDEA使用的反混淆器(预留)</li>" +
|
"<li><b>Fernflower</b>: IntelliJ IDEA使用的反混淆器(预留)</li>" +
|
||||||
"<li><b>Procyon</b>: 另一个开源反混淆器(预留)</li>" +
|
"<li><b>Procyon</b>: 另一个开源反混淆器</li>" +
|
||||||
"</ul>" +
|
|
||||||
"<p>注意: 当前仅支持CFR反混淆器,其他选项为预留功能。</p>" +
|
|
||||||
"</div></html>";
|
"</div></html>";
|
||||||
|
|
||||||
JOptionPane.showMessageDialog(this, helpText, "设置帮助", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(this, helpText, "设置帮助", JOptionPane.INFORMATION_MESSAGE);
|
||||||
@@ -874,19 +879,27 @@ public class ModernJarViewer extends JFrame {
|
|||||||
|
|
||||||
private void registerFileIcons() {
|
private void registerFileIcons() {
|
||||||
fileTree.setCellRenderer(new DefaultTreeCellRenderer() {
|
fileTree.setCellRenderer(new DefaultTreeCellRenderer() {
|
||||||
private final ImageIcon jarIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/file_jar.png", 18).getImage());
|
private final Icon jarIcon = loadThemeAwareIcon("programming/JarApiViewer/file_jar.png", 18);
|
||||||
private final ImageIcon classIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/java_file.png", 18).getImage());
|
private final Icon classIcon = loadThemeAwareIcon("programming/JarApiViewer/java_file.png", 18);
|
||||||
private final ImageIcon zipIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/zip_file.png", 12).getImage());
|
private final Icon zipIcon = loadThemeAwareIcon("programming/JarApiViewer/zip_file.png", 12);
|
||||||
private final ImageIcon mcmetaIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/mcmeta_file.png", 12).getImage());
|
private final Icon mcmetaIcon = loadThemeAwareIcon("programming/JarApiViewer/mcmeta_file.png", 12);
|
||||||
private final ImageIcon cfgIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/cfg_file.png", 12).getImage());
|
private final Icon cfgIcon = loadThemeAwareIcon("programming/JarApiViewer/cfg_file.png", 12);
|
||||||
private final ImageIcon tomlIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/toml_file.png", 12).getImage());
|
private final Icon tomlIcon = loadThemeAwareIcon("programming/JarApiViewer/toml_file.png", 12);
|
||||||
private final ImageIcon exeIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/exe_file.png", 12).getImage());
|
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 Icon folderIcon = UIManager.getIcon("Tree.closedIcon");
|
||||||
private final ImageIcon fileIcon = new ImageIcon(LoadIcon.loadIcon("programming/JarApiViewer/file.png", 12).getImage()); // Changed to Icon
|
|
||||||
|
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
|
@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);
|
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
||||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
|
||||||
String name = node.getUserObject().toString();
|
String name = node.getUserObject().toString();
|
||||||
@@ -2480,28 +2493,50 @@ public class ModernJarViewer extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void configureIDEATheme(SyntaxScheme scheme, RSyntaxTextArea editor) {
|
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);
|
Style defaultStyle = scheme.getStyle(Token.NULL);
|
||||||
defaultStyle.foreground = foreground;
|
defaultStyle.foreground = foreground;
|
||||||
defaultStyle.background = background;
|
defaultStyle.background = background;
|
||||||
|
|
||||||
setTokenStyle(scheme, Token.RESERVED_WORD, 0xCC7832);
|
// 深色主题和浅色主题的不同颜色配置
|
||||||
setTokenStyle(scheme, Token.SEPARATOR, 0x4EC9B0);
|
if (isDarkTheme()) {
|
||||||
setTokenStyle(scheme, Token.OPERATOR, 0xFFD700);
|
setTokenStyle(scheme, Token.RESERVED_WORD, 0xCC7832);
|
||||||
setTokenStyle(scheme, Token.IDENTIFIER, 0xE0E0E0);
|
setTokenStyle(scheme, Token.SEPARATOR, 0x4EC9B0);
|
||||||
setTokenStyle(scheme, Token.LITERAL_STRING_DOUBLE_QUOTE, 0x6A8759);
|
setTokenStyle(scheme, Token.OPERATOR, 0xFFD700);
|
||||||
setTokenStyle(scheme, Token.LITERAL_NUMBER_DECIMAL_INT, 0x6897BB);
|
setTokenStyle(scheme, Token.IDENTIFIER, 0xE0E0E0);
|
||||||
setTokenStyle(scheme, Token.COMMENT_EOL, 0x6A8759);
|
setTokenStyle(scheme, Token.LITERAL_STRING_DOUBLE_QUOTE, 0x6A8759);
|
||||||
setTokenStyle(scheme, Token.COMMENT_MULTILINE, 0x6A8759);
|
setTokenStyle(scheme, Token.LITERAL_NUMBER_DECIMAL_INT, 0x6897BB);
|
||||||
setTokenStyle(scheme, Token.COMMENT_DOCUMENTATION, 0x629755);
|
setTokenStyle(scheme, Token.COMMENT_EOL, 0x6A8759);
|
||||||
setTokenStyle(scheme, Token.ANNOTATION, 0xBBB529);
|
setTokenStyle(scheme, Token.COMMENT_MULTILINE, 0x6A8759);
|
||||||
setTokenStyle(scheme, Token.FUNCTION, 0xFFC66D);
|
setTokenStyle(scheme, Token.COMMENT_DOCUMENTATION, 0x629755);
|
||||||
setTokenStyle(scheme, Token.DATA_TYPE, 0xE8BF6A);
|
setTokenStyle(scheme, Token.ANNOTATION, 0xBBB529);
|
||||||
|
setTokenStyle(scheme, Token.FUNCTION, 0xFFC66D);
|
||||||
|
setTokenStyle(scheme, Token.DATA_TYPE, 0xE8BF6A);
|
||||||
|
|
||||||
|
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.setBackground(background);
|
||||||
editor.setSelectionColor(new Color(0x214283));
|
|
||||||
editor.setCurrentLineHighlightColor(new Color(0x323232));
|
|
||||||
editor.setHighlightCurrentLine(true);
|
editor.setHighlightCurrentLine(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,9 @@ public class MainWindow extends JFrame {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
|
setSize(1200, 800);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,8 +157,6 @@ public class MainWindow extends JFrame {
|
|||||||
getContentPane().removeAll();
|
getContentPane().removeAll();
|
||||||
|
|
||||||
setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.title"));
|
setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.title"));
|
||||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
|
||||||
setSize(1200, 800);
|
|
||||||
|
|
||||||
// 主容器
|
// 主容器
|
||||||
JPanel mainPanel = new JPanel(new BorderLayout());
|
JPanel mainPanel = new JPanel(new BorderLayout());
|
||||||
@@ -877,7 +878,7 @@ public class MainWindow extends JFrame {
|
|||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDarkTheme() {
|
private static boolean isDarkTheme() {
|
||||||
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
|
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1183,7 +1184,19 @@ public class MainWindow extends JFrame {
|
|||||||
}
|
}
|
||||||
public void addTool(ToolItem tool) { tools.add(tool); }
|
public void addTool(ToolItem tool) { tools.add(tool); }
|
||||||
public String getDescription() { return description; }
|
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 String getName() { return name; }
|
||||||
public List<ToolItem> getTools() { return tools; }
|
public List<ToolItem> getTools() { return tools; }
|
||||||
public ImageIcon getIconImage() { return iconImage; }
|
public ImageIcon getIconImage() { return iconImage; }
|
||||||
|
|||||||
Reference in New Issue
Block a user