feat(gui): 添加深色模式支持并优化主题
- 增加了对 macOS、Windows 和 Linux 深色模式的检测- 添加了多个 FlatLaf 主题支持 - 优化了窗口主题设置逻辑,根据系统模式自动选择深浅主题 -调整了侧边栏、卡片背景和文本颜色等样式,以适应不同主题 - 更新了语言文件,增加了新主题的翻译
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 重新加载窗口
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
35
src/main/java/com/axis/innovators/box/gui/ThemeColors.java
Normal file
35
src/main/java/com/axis/innovators/box/gui/ThemeColors.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.axis.innovators.box.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class ThemeColors {
|
||||
// 工具方法:使颜色变暗 (factor: 0~1,0.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~1,0.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;
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
@@ -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 信息
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user