feat(gui): 添加深色模式支持并优化主题

- 增加了对 macOS、Windows 和 Linux 深色模式的检测- 添加了多个 FlatLaf 主题支持
- 优化了窗口主题设置逻辑,根据系统模式自动选择深浅主题
-调整了侧边栏、卡片背景和文本颜色等样式,以适应不同主题
- 更新了语言文件,增加了新主题的翻译
This commit is contained in:
tzdwindows 7
2025-08-14 15:23:25 +08:00
parent 9136ad8827
commit 5da71f05e7
7 changed files with 222 additions and 34 deletions

View File

@@ -1,3 +1,3 @@
#Current Loaded Language
#Tue Aug 12 21:57:11 CST 2025
#Thu Aug 14 15:17:57 CST 2025
loadedLanguage=system\:zh_CN

View File

@@ -1,9 +1,34 @@
default_theme.system.topicName=\u9ED8\u8BA4\u4E3B\u9898
default_theme.default.tip=\u9ED8\u8BA4\u7684\u4E3B\u9898
metal_theme.system.topicName=Metal\u98CE\u683C
metal_theme.default.tip=Metal\u98CE\u683C
motif_theme.system.topicName=Motif\u98CE\u683C
motif_theme.default.tip=Motif\u98CE\u683C
# \u9ED8\u8BA4\u4E3B\u9898
default_theme.system.topicName=\u7CFB\u7EDF\u9ED8\u8BA4\u4E3B\u9898
default_theme.default.tip=\u4F7F\u7528\u64CD\u4F5C\u7CFB\u7EDF\u9ED8\u8BA4\u5916\u89C2
# Metal \u4E3B\u9898
metal_theme.system.topicName=Metal \u4E3B\u9898 (Java \u7ECF\u5178)
metal_theme.default.tip=Java \u9ED8\u8BA4\u7684 Metal \u98CE\u683C\u754C\u9762
# Motif \u4E3B\u9898
motif_theme.system.topicName=Motif \u4E3B\u9898 (UNIX \u98CE\u683C)
motif_theme.default.tip=\u4F20\u7EDF\u7684 UNIX Motif \u5916\u89C2
# FlatLaf \u4E3B\u9898
flatLight_theme.system.topicName=Flat Light (\u6D45\u8272)
flatLight_theme.default.tip=\u73B0\u4EE3\u5316\u6D45\u8272\u4E3B\u9898\uFF0C\u7B80\u6D01\u660E\u4EAE
flatDark_theme.system.topicName=Flat Dark (\u6DF1\u8272)
flatDark_theme.default.tip=\u73B0\u4EE3\u5316\u6DF1\u8272\u4E3B\u9898\uFF0C\u62A4\u773C\u8212\u9002
flatIntelliJ_theme.system.topicName=IntelliJ \u6D45\u8272
flatIntelliJ_theme.default.tip=\u7C7B\u4F3C IntelliJ IDEA \u7684\u6D45\u8272\u4E3B\u9898
flatDarcula_theme.system.topicName=Darcula \u6DF1\u8272
flatDarcula_theme.default.tip=\u7C7B\u4F3C IntelliJ IDEA \u7684 Darcula \u6DF1\u8272\u4E3B\u9898
flatMacLight_theme.system.topicName=macOS \u6D45\u8272
flatMacLight_theme.default.tip=\u7C7B\u4F3C macOS \u7684\u6D45\u8272\u98CE\u683C
flatMacDark_theme.system.topicName=macOS \u6DF1\u8272
flatMacDark_theme.default.tip=\u7C7B\u4F3C macOS \u7684\u6DF1\u8272\u6A21\u5F0F\uFF0C\u4F18\u96C5\u73B0\u4EE3
flatLightLaf_theme.system.topicName=flatLightLaf\u98CE\u683C
flatLightLaf_theme.default.tip=flatLightLaf\u98CE\u683C

View File

@@ -16,7 +16,10 @@ import com.axis.innovators.box.util.PythonResult;
import com.axis.innovators.box.util.Tray;
import com.axis.innovators.box.util.UserLocalInformation;
import com.axis.innovators.box.verification.UserTags;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
import com.formdev.flatlaf.themes.FlatMacLightLaf;
import com.sun.management.HotSpotDiagnosticMXBean;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -714,38 +717,96 @@ public class AxisInnovatorsBox {
*/
private void setTopic() {
try {
main.registrationTopic.addTopic(new com.formdev.flatlaf.FlatDarculaLaf(),
"Darcula主题",
"Darcula主题",
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:darcula_theme");
main.registrationTopic.addTopic(UIManager.getSystemLookAndFeelClassName(),
boolean isDarkMode = SystemInfoUtil.isSystemDarkMode();
// 1. 默认系统主题
main.registrationTopic.addTopic(
UIManager.getSystemLookAndFeelClassName(),
LanguageManager.getLoadedLanguages().getText("default_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("default_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:default_theme");
main.registrationTopic.setLoading("system:default_theme");
"system:default_theme"
);
main.registrationTopic.addTopic("javax.swing.plaf.metal.MetalLookAndFeel",
// 2. Metal (Java默认主题)
main.registrationTopic.addTopic(
"javax.swing.plaf.metal.MetalLookAndFeel",
LanguageManager.getLoadedLanguages().getText("metal_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("metal_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:metal_theme");
"system:metal_theme"
);
main.registrationTopic.addTopic("com.sun.java.swing.plaf.motif.MotifLookAndFeel",
// 3. Motif (UNIX风格)
main.registrationTopic.addTopic(
"com.sun.java.swing.plaf.motif.MotifLookAndFeel",
LanguageManager.getLoadedLanguages().getText("motif_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("motif_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:motif_theme");
"system:motif_theme"
);
main.registrationTopic.addTopic(new FlatLightLaf(),
LanguageManager.getLoadedLanguages().getText("flatLightLaf_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatLightLaf_theme.default.tip"),
// 4. FlatLaf 主题注册
// 4.1 FlatLight (默认浅色)
main.registrationTopic.addTopic(
new com.formdev.flatlaf.FlatLightLaf(),
LanguageManager.getLoadedLanguages().getText("flatLight_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatLight_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatLightLaf_theme");
"system:flatLight_theme"
);
UIManager.setLookAndFeel(new com.formdev.flatlaf.FlatDarculaLaf());
// 4.2 FlatDark (默认深色)
main.registrationTopic.addTopic(
new com.formdev.flatlaf.FlatDarkLaf(),
LanguageManager.getLoadedLanguages().getText("flatDark_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatDark_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatDark_theme"
);
// 4.3 FlatIntelliJ (类似IDEA浅色)
main.registrationTopic.addTopic(
new com.formdev.flatlaf.FlatIntelliJLaf(),
LanguageManager.getLoadedLanguages().getText("flatIntelliJ_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatIntelliJ_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatIntelliJ_theme"
);
// 4.4 FlatDarcula (类似IDEA深色)
main.registrationTopic.addTopic(
new com.formdev.flatlaf.FlatDarculaLaf(),
LanguageManager.getLoadedLanguages().getText("flatDarcula_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatDarcula_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatDarcula_theme"
);
// 4.5 FlatMacLight (macOS风格浅色)
main.registrationTopic.addTopic(
new FlatMacLightLaf(),
LanguageManager.getLoadedLanguages().getText("flatMacLight_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatMacLight_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatMacLight_theme"
);
// 4.6 FlatMacDark (macOS风格深色)
main.registrationTopic.addTopic(
new FlatMacDarkLaf(),
LanguageManager.getLoadedLanguages().getText("flatMacDark_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatMacDark_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatMacDark_theme"
);
LookAndFeel defaultLaf = isDarkMode ? new FlatMacDarkLaf() : new FlatMacLightLaf();
UIManager.setLookAndFeel(defaultLaf);
main.registrationTopic.setLoading(
isDarkMode ? "system:flatMacDark_theme" : "system:flatMacLight_theme"
);
} catch (Exception e) {
logger.warn("Failed to load the system facade class", e);
}
@@ -778,7 +839,6 @@ public class AxisInnovatorsBox {
windowsJDialog.repaint();
}
/**
* 重新加载窗口
*/

View File

@@ -58,12 +58,22 @@ public class MainWindow extends JFrame {
// settings dialog
private WindowsJDialog dialog;
// 颜色常量
private static final Color SIDEBAR_COLOR = new Color(0x3C3F41); // 你指定的颜色
private static final Color CARD_LIGHT_BG = new Color(250, 250, 250);
private static final Color CARD_BG = new Color(0x4A4D50); // 与侧边栏协调的深灰色
private static final Color CARD_BORDER = new Color(0x5C5F61); // 稍亮的边框色
private static final Color TEXT_COLOR = new Color(0xE0E0E0); // 浅灰色文字
// 侧边栏颜色(比面板背景稍暗)
private static final Color SIDEBAR_COLOR = Optional.ofNullable(UIManager.getColor("Panel.background"))
.orElse(new Color(0x3C3F41));
// 卡片背景(深色模式适配,比侧边栏稍亮)
private static final Color CARD_BG = Optional.ofNullable(UIManager.getColor("control"))
.map(bg -> ThemeColors.brighten(bg, 0.1f))
.orElse(new Color(0x4A4D50));
// 卡片边框(使用系统边框色或稍亮颜色)
private static final Color CARD_BORDER = Optional.ofNullable(UIManager.getColor("controlHighlight"))
.orElse(new Color(0x5C5F61));
// 文本颜色(直接使用系统主题的文本颜色)
private static final Color TEXT_COLOR = Optional.ofNullable(UIManager.getColor("textText"))
.orElse(new Color(0xE0E0E0));
public MainWindow() {
// 增强字体设置逻辑:优先使用系统支持的中文字体
@@ -417,8 +427,8 @@ public class MainWindow extends JFrame {
button.setIcon(ic);
button.setIconTextGap(12);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button.setForeground(Color.WHITE);
button.setBackground(new Color(0,0,0,0));
button.setForeground(TEXT_COLOR);
button.setBackground(TEXT_COLOR);
button.setOpaque(false);
button.setBorder(BorderFactory.createEmptyBorder(8, 12, 8, 12));
button.setFocusPainted(false);
@@ -809,7 +819,25 @@ public class MainWindow extends JFrame {
// ---------- 字体选择工具(返回 Font ----------
private Font selectFont(Object... namesAndSize) {
int size = 13;
return new Font("微软雅黑", Font.PLAIN, size);
for (Object obj : namesAndSize) {
if (obj instanceof Integer) {
size = (Integer) obj;
}
}
Font systemFont = UIManager.getFont("Label.font");
if (systemFont != null && canDisplayChinese(systemFont)) {
return systemFont.deriveFont(Font.PLAIN, size);
}
try {
return new Font("Microsoft YaHei", Font.PLAIN, size);
} catch (Exception e) {
return new Font("微软雅黑", Font.PLAIN, size);
}
}
/** 检查字体是否能显示中文 */
private static boolean canDisplayChinese(Font font) {
return font.canDisplay('中') && font.canDisplay('文'); // 测试常见汉字
}
private boolean isFontAvailable(String fontName) {

View File

@@ -0,0 +1,35 @@
package com.axis.innovators.box.gui;
import javax.swing.*;
import java.awt.*;
public class ThemeColors {
// 工具方法:使颜色变暗 (factor: 0~10.2表示变暗20%)
public static Color darken(Color color, float factor) {
return new Color(
Math.max((int)(color.getRed() * (1 - factor)), 0),
Math.max((int)(color.getGreen() * (1 - factor)), 0),
Math.max((int)(color.getBlue() * (1 - factor)), 0),
color.getAlpha()
);
}
// 工具方法:使颜色变亮 (factor: 0~10.2表示变亮20%)
public static Color brighten(Color color, float factor) {
return new Color(
Math.min((int)(color.getRed() * (1 + factor)), 255),
Math.min((int)(color.getGreen() * (1 + factor)), 255),
Math.min((int)(color.getBlue() * (1 + factor)), 255),
color.getAlpha()
);
}
// 检测当前是否为深色模式
public static boolean isDarkMode() {
Color bg = UIManager.getColor("Panel.background");
if (bg == null) return false;
// 计算亮度0-1值越小越暗
double brightness = (bg.getRed() * 0.299 + bg.getGreen() * 0.587 + bg.getBlue() * 0.114) / 255;
return brightness < 0.5;
}
}

View File

@@ -258,6 +258,7 @@ public class RegistrationSettingsItem extends WindowsJDialog {
language.getText("settings.4.load_theme_success.3"), JOptionPane.INFORMATION_MESSAGE);
registrationTopic.setLoading(registeredName);
themeList.repaint();
AxisInnovatorsBox.getMain().reloadAllWindow();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, language.getText("settings.4.load_theme_error")
+ e.getMessage(),

View File

@@ -31,6 +31,45 @@ public class SystemInfoUtil {
return System.getProperty("os.name");
}
/**
* 判断当前系统是否处于深色模式
* @return true 表示处于深色模式false 表示处于浅色模式
*/
public static boolean isSystemDarkMode() {
try {
// macOS 检测
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
// 通过 Apple 脚本检测 macOS 深色模式
Process process = Runtime.getRuntime().exec("defaults read -g AppleInterfaceStyle");
return process.waitFor() == 0; // 命令成功返回表示深色模式
}
// Windows 检测 (Windows 10/11)
else if (System.getProperty("os.name").toLowerCase().contains("windows")) {
String cmd = "reg query HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize "
+ "/v AppsUseLightTheme";
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("REG_DWORD") && line.contains("0x0")) {
return true; // 0x0 表示深色模式
}
}
}
// Linux (GNOME) 检测
else if (System.getenv("XDG_CURRENT_DESKTOP") != null
&& System.getenv("XDG_CURRENT_DESKTOP").toLowerCase().contains("gnome")) {
Process process = Runtime.getRuntime().exec("gsettings get org.gnome.desktop.interface color-scheme");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
return line != null && line.contains("dark");
}
} catch (Exception e) {
logger.warn("Failed to detect system dark mode", e);
}
return false; // 默认浅色模式
}
/**
* 获取 CPU 信息
*/