feat(theme): 实现Windows主题变更监听与动态更新
- 添加WindowsTheme工具类用于监听系统主题变更 - 实现runMonitorTopics方法监控主题变化并自动更新- 新增TopicsUpdateEvents事件类用于主题更新通知 - 重构setTopic方法使用updateTheme统一处理主题设置 -优化MainWindow背景透明度更新逻辑- 添加isSettingsVisible方法判断设置界面可见状态 - 移除RegisterTray类中的静态库加载代码 - 调整设置面板显示逻辑,支持重新显示已打开的设置窗口 -修复库加载错误日志信息 - 添加异常堆栈打印到崩溃报告组织方法中
This commit is contained in:
Binary file not shown.
@@ -4,6 +4,8 @@ import com.axis.innovators.box.browser.WindowRegistry;
|
||||
import com.axis.innovators.box.events.GlobalEventBus;
|
||||
import com.axis.innovators.box.events.OpenFileEvents;
|
||||
import com.axis.innovators.box.events.StartupEvent;
|
||||
import com.axis.innovators.box.events.TopicsUpdateEvents;
|
||||
import com.axis.innovators.box.util.WindowsTheme;
|
||||
import com.axis.innovators.box.window.*;
|
||||
import com.axis.innovators.box.plugins.PluginDescriptor;
|
||||
import com.axis.innovators.box.plugins.PluginLoader;
|
||||
@@ -46,6 +48,8 @@ import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.*;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.lang.management.*;
|
||||
@@ -69,6 +73,7 @@ public class AxisInnovatorsBox {
|
||||
"tzdwindows 7",
|
||||
"lyxyz5223",
|
||||
"\uD83D\uDC3EMr. Liu\uD83D\uDC3E",
|
||||
"泽钰"
|
||||
};
|
||||
|
||||
/** 我是总任务数 **/
|
||||
@@ -188,8 +193,9 @@ public class AxisInnovatorsBox {
|
||||
LibraryLoad.loadLibrary("FridaNative");
|
||||
LibraryLoad.loadLibrary("ThrowSafely");
|
||||
LibraryLoad.loadLibrary("DogAgent");
|
||||
LibraryLoad.loadLibrary("RegisterTray");
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load the 'FridaNative' library", e);
|
||||
logger.error("Failed to load library", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +228,7 @@ public class AxisInnovatorsBox {
|
||||
* 组织崩溃报告
|
||||
*/
|
||||
public void organizingCrashReports(Exception e) {
|
||||
e.printStackTrace();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
String systemOut = Log4j2OutputStream.systemOutContent.toString();
|
||||
String systemErr = Log4j2OutputStream.systemErrContent.toString();
|
||||
@@ -713,6 +720,28 @@ public class AxisInnovatorsBox {
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行监控主题
|
||||
*/
|
||||
public void runMonitorTopics(){
|
||||
WindowsTheme.setThemeChangeListener((themeName, darkTheme) -> {
|
||||
logger.info("主题变更: {}, 暗主题: {}", themeName, darkTheme);
|
||||
if (registrationTopic.isDarkMode() == darkTheme){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
updateTheme(themeName,darkTheme);
|
||||
} catch (UnsupportedLookAndFeelException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
reloadAllWindow();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(this::reloadAllWindow);
|
||||
}
|
||||
});
|
||||
}
|
||||
private void addFileToZip(ZipOutputStream zos, File file, String entryPath) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
@@ -804,7 +833,7 @@ public class AxisInnovatorsBox {
|
||||
private void setTopic() {
|
||||
try {
|
||||
|
||||
boolean isDarkMode = SystemInfoUtil.isSystemDarkMode();
|
||||
boolean isDarkMode = WindowsTheme.isDarkTheme();
|
||||
|
||||
// 1. 默认系统主题
|
||||
main.registrationTopic.addTopic(
|
||||
@@ -932,16 +961,26 @@ public class AxisInnovatorsBox {
|
||||
// "system:blur",true
|
||||
//);
|
||||
|
||||
LookAndFeel defaultLaf = isDarkMode ? new FlatMacDarkLaf() : new FlatMacLightLaf();
|
||||
UIManager.setLookAndFeel(defaultLaf);
|
||||
main.registrationTopic.setLoading(
|
||||
isDarkMode ? "system:flatMacDark_theme" : "system:flatMacLight_theme"
|
||||
);
|
||||
updateTheme("",isDarkMode);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to load the system facade class", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新主题
|
||||
* @param themeName 主题名称
|
||||
* @param isDarkMode 是否是暗主题
|
||||
*/
|
||||
public void updateTheme(String themeName,boolean isDarkMode) throws UnsupportedLookAndFeelException {
|
||||
LookAndFeel defaultLaf = isDarkMode ? new FlatMacDarkLaf() : new FlatMacLightLaf();
|
||||
UIManager.setLookAndFeel(defaultLaf);
|
||||
main.registrationTopic.setLoading(
|
||||
isDarkMode ? "system:flatMacDark_theme" : "system:flatMacLight_theme"
|
||||
);
|
||||
GlobalEventBus.EVENT_BUS.post(new TopicsUpdateEvents(themeName,isDarkMode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出窗口
|
||||
* @param windowsJDialog 窗口
|
||||
@@ -1051,7 +1090,7 @@ public class AxisInnovatorsBox {
|
||||
try {
|
||||
main.initLog4j2();
|
||||
main.setTopic();
|
||||
|
||||
main.runMonitorTopics();
|
||||
//main.popupLogin();
|
||||
main.thread = new Thread(() -> {
|
||||
try {
|
||||
@@ -1155,6 +1194,12 @@ public class AxisInnovatorsBox {
|
||||
isWindow = true;
|
||||
ex.setVisible(true);
|
||||
|
||||
Toolkit.getDefaultToolkit().addPropertyChangeListener("win.xpstyle.themeName",
|
||||
evt -> {
|
||||
logger.info("系统主题发生变化: {}", evt.getNewValue());
|
||||
ex.updateTheme();
|
||||
});
|
||||
|
||||
if (isDebug) {
|
||||
SwingUtilities.invokeLater(this::createDebugWindow);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.axis.innovators.box.events;
|
||||
|
||||
/**
|
||||
* 当主题变更时被调用
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class TopicsUpdateEvents {
|
||||
private final String themeName;
|
||||
private final boolean darkTheme;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param themeName 主题名称
|
||||
* @param darkTheme 是否是暗主题
|
||||
*/
|
||||
public TopicsUpdateEvents(String themeName, boolean darkTheme) {
|
||||
this.themeName = themeName;
|
||||
this.darkTheme = darkTheme;
|
||||
}
|
||||
|
||||
public String getThemeName() {
|
||||
return themeName;
|
||||
}
|
||||
|
||||
public boolean isDarkTheme() {
|
||||
return darkTheme;
|
||||
}
|
||||
}
|
||||
@@ -80,28 +80,31 @@ public class RegistrationSettingsItem extends WindowsJDialog {
|
||||
JPanel aboutPanel = createAboutPanel();
|
||||
JPanel themePanel = createThemePanel();
|
||||
|
||||
registrationSettingsItem.addSettings(
|
||||
pluginPanel, language.getText("settings.1.title"),
|
||||
null, language.getText("settings.1.tip"), "system:settings_plugins_item"
|
||||
);
|
||||
registrationSettingsItem.addSettings(
|
||||
generalPanel, language.getText("settings.2.title"),
|
||||
null, language.getText("settings.2.tip"), "system:settings_appearance_item"
|
||||
);
|
||||
registrationSettingsItem.addSettings(
|
||||
aboutPanel, language.getText("settings.3.title"),
|
||||
null, language.getText("settings.3.tip"), "system:settings_information_item"
|
||||
pluginPanel, language.getText("settings.1.title"),
|
||||
null, language.getText("settings.1.tip"), "system:settings_plugins_item"
|
||||
);
|
||||
registrationSettingsItem.addSettings(
|
||||
themePanel, language.getText("settings.4.title"),
|
||||
null, language.getText("settings.4.tip"), "system:settings_theme_item"
|
||||
);
|
||||
registrationSettingsItem.addSettings(
|
||||
aboutPanel, language.getText("settings.3.title"),
|
||||
null, language.getText("settings.3.tip"), "system:settings_information_item"
|
||||
);
|
||||
|
||||
registrationSettingsItemList.add(
|
||||
registrationSettingsItem
|
||||
);
|
||||
|
||||
AxisInnovatorsBox.getMain().getMainWindow().showSettings();
|
||||
// 重新显示
|
||||
if (AxisInnovatorsBox.getMain().getMainWindow().isSettingsVisible()) {
|
||||
AxisInnovatorsBox.getMain().getMainWindow().showSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private static JPanel createThemePanel() {
|
||||
|
||||
@@ -12,11 +12,6 @@ import java.util.List;
|
||||
*/
|
||||
public class RegisterTray {
|
||||
|
||||
static {
|
||||
LibraryLoad.loadLibrary("RegisterTray");
|
||||
//System.load("C:\\Users\\Administrator\\source\\repos\\RegisterTray\\x64\\Release\\RegisterTray.dll");
|
||||
}
|
||||
|
||||
/**
|
||||
* 托盘菜单项构建器(流畅接口)
|
||||
*/
|
||||
|
||||
64
src/main/java/com/axis/innovators/box/util/WindowsTheme.java
Normal file
64
src/main/java/com/axis/innovators/box/util/WindowsTheme.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package com.axis.innovators.box.util;
|
||||
|
||||
/**
|
||||
* Windows主题变更监听器
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class WindowsTheme {
|
||||
|
||||
/**
|
||||
* 设置主题改变监听器
|
||||
* @param listener 监听器
|
||||
*/
|
||||
public static native void setThemeChangeListener(ThemeChangeListener listener);
|
||||
|
||||
/**
|
||||
* 主题改变监听器
|
||||
*/
|
||||
public interface ThemeChangeListener {
|
||||
/**
|
||||
* 当主题改变时调用
|
||||
* @param themeName 主题名称
|
||||
* @param darkTheme 是否是暗主题
|
||||
*/
|
||||
void themeChanged(String themeName,boolean darkTheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前是否为暗色主题
|
||||
* @return true-暗色主题, false-亮色主题
|
||||
*/
|
||||
public static native boolean isDarkTheme();
|
||||
|
||||
/**
|
||||
* 获取当前主题名称
|
||||
* @return 主题名称
|
||||
*/
|
||||
public static native String getThemeName();
|
||||
|
||||
//public static void main(String[] args) {
|
||||
// try {
|
||||
// System.load("C:\\Users\\Administrator\\source\\repos\\RegisterTray\\x64\\Release\\RegisterTray.dll");
|
||||
//
|
||||
// // 先测试直接获取主题信息的方法
|
||||
// System.out.println("Current topic Name: " + WindowsTheme.getThemeName());
|
||||
// System.out.println("Is it a dark theme: " + WindowsTheme.isDarkTheme());
|
||||
//
|
||||
// WindowsTheme.setThemeChangeListener(new WindowsTheme.ThemeChangeListener() {
|
||||
// @Override
|
||||
// public void themeChanged(String themeName, boolean darkTheme) {
|
||||
// System.out.println("The theme has changed: " + themeName + " is dark theme: " + darkTheme);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// System.out.println("Start listening for theme changes... Press Enter to exit");
|
||||
//
|
||||
// System.in.read();
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// } finally {
|
||||
// WindowsTheme.setThemeChangeListener(null);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -155,19 +155,7 @@ public class MainWindow extends JFrame {
|
||||
this.backgroundOpacity = Math.max(0.0f, Math.min(1.0f, opacity));
|
||||
this.cachedBlurredBackground = null;
|
||||
this.cachedBackgroundSize = null;
|
||||
|
||||
// 重新绘制窗口
|
||||
if (AxisInnovatorsBox.getMain().isWindow()) {
|
||||
AxisInnovatorsBox.getMain().reloadAllWindow();
|
||||
}
|
||||
else {
|
||||
getContentPane().removeAll();
|
||||
revalidate();
|
||||
repaint();
|
||||
initUI();
|
||||
updateTheme();
|
||||
revalidate();
|
||||
}
|
||||
AxisInnovatorsBox.getMain().reloadAllWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -965,6 +953,36 @@ public class MainWindow extends JFrame {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断设置界面是否打开
|
||||
* @return 设置界面是否可见
|
||||
*/
|
||||
public boolean isSettingsVisible(){
|
||||
if (dialog == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dialog.isDisplayable()) {
|
||||
dialog = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dialog.isVisible()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (dialog.getParent() != this && dialog.getOwner() != this) {
|
||||
dialog = null;
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
dialog = null;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private JPanel createToolCard(ToolItem tool) {
|
||||
JPanel card = new JPanel() {
|
||||
@Override
|
||||
@@ -1368,7 +1386,6 @@ public class MainWindow extends JFrame {
|
||||
dialog.setSize(750, 550);
|
||||
dialog.setLocationRelativeTo(this);
|
||||
|
||||
|
||||
// 使用 JLayer + LayerUI 来对整个内容做统一的淡入 + 下滑(仿 Apple 风格)动画,
|
||||
// 这样子组件也会跟随一起动画,而不是只有背景绘制发生变化。
|
||||
JPanel inner = new JPanel(new BorderLayout());
|
||||
|
||||
Reference in New Issue
Block a user