feat(browser): 实现主题和字体动态更新功能
- 移除重复的字体信息注入逻辑 - 添加 updateTheme 方法统一处理主题和字体更新 - 在 setVisible 方法中调用 updateTheme 确保显示时更新 -优化 JavaScript 中的主题应用逻辑,增强兼容性 - 增强 HTML 页面中的主题监听和字体应用功能 - 添加事件计数器和调试信息用于追踪主题变化
This commit is contained in:
@@ -208,7 +208,7 @@
|
||||
.quick-create-table:hover{opacity:0.9}
|
||||
</style>
|
||||
</head>
|
||||
<body data-theme="light">
|
||||
<body>
|
||||
<header>
|
||||
<div class="logo">
|
||||
<div class="mark">AI</div>
|
||||
@@ -515,6 +515,21 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
window.eventCounter = {
|
||||
javaFontsLoaded: 0,
|
||||
javaThemeChanged: 0
|
||||
};
|
||||
|
||||
document.addEventListener('javaThemeChanged', function(event) {
|
||||
window.eventCounter.javaThemeChanged++;
|
||||
console.log('事件详情:', event.detail);
|
||||
|
||||
if (typeof applyJavaTheme === 'function') {
|
||||
applyJavaTheme(event.detail);
|
||||
}
|
||||
}, true);
|
||||
|
||||
// Java 通信对象(与你的 Java 交互)
|
||||
const JavaBridge = {
|
||||
sendRequest: function(request, callback) {
|
||||
@@ -611,20 +626,28 @@
|
||||
}
|
||||
|
||||
// 主题支持(auto / light / dark)
|
||||
(function themeInit(){
|
||||
const body = document.body;
|
||||
let mode = localStorage.getItem('dbToolTheme') || 'light';
|
||||
applyTheme(mode);
|
||||
document.getElementById('themeToggle').addEventListener('click', () => {
|
||||
mode = (mode === 'light') ? 'dark' : 'light';
|
||||
localStorage.setItem('dbToolTheme', mode);
|
||||
applyTheme(mode);
|
||||
});
|
||||
function applyTheme(m){
|
||||
body.setAttribute('data-theme', m);
|
||||
document.getElementById('themeToggle').textContent = m === 'light' ? '🌙' : '☀️';
|
||||
}
|
||||
})();
|
||||
// 修复后的主题支持
|
||||
//(function themeInit(){
|
||||
// const body = document.body;
|
||||
// const themeToggle = document.getElementById('themeToggle');
|
||||
//
|
||||
// let currentTheme = localStorage.getItem('dbToolTheme') || 'light';
|
||||
//
|
||||
// applyTheme(currentTheme);
|
||||
//
|
||||
// themeToggle.addEventListener('click', () => {
|
||||
// const currentTheme = body.getAttribute('data-theme');
|
||||
// const newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
||||
//
|
||||
// localStorage.setItem('dbToolTheme', newTheme);
|
||||
// applyTheme(newTheme);
|
||||
// });
|
||||
//
|
||||
// function applyTheme(theme){
|
||||
// body.setAttribute('data-theme', theme);
|
||||
// themeToggle.textContent = theme === 'light' ? '🌙' : '☀️';
|
||||
// }
|
||||
//})();
|
||||
|
||||
// 绑定工具面板切换
|
||||
document.getElementById('toolsToggle').addEventListener('click', () => {
|
||||
@@ -1769,6 +1792,189 @@
|
||||
searchTerm ? `找到 ${matchCount} 个匹配项` : '';
|
||||
});
|
||||
|
||||
// 监听Java字体加载完成事件
|
||||
document.addEventListener('javaFontsLoaded', function(event) {
|
||||
const fontInfo = event.detail;
|
||||
console.log('接收到Java字体信息:', fontInfo);
|
||||
|
||||
// 应用Java字体到编辑器
|
||||
applyJavaFonts(fontInfo);
|
||||
});
|
||||
|
||||
// 应用Java字体的函数 - 修复版本
|
||||
function applyJavaFonts(fontInfo) {
|
||||
const uiFonts = fontInfo.uiFonts || {};
|
||||
const defaultFont = fontInfo.defaultFont || uiFonts['Label.font'] || {};
|
||||
|
||||
if (defaultFont && defaultFont.family) {
|
||||
const fontFamily = defaultFont.family;
|
||||
const fontSize = defaultFont.size || 14;
|
||||
const fontWeight = defaultFont.bold ? 'bold' : 'normal';
|
||||
const fontStyle = defaultFont.italic ? 'italic' : 'normal';
|
||||
|
||||
// 移除之前可能存在的字体样式
|
||||
const existingStyle = document.getElementById('java-fonts-style');
|
||||
if (existingStyle) {
|
||||
existingStyle.remove();
|
||||
}
|
||||
|
||||
// 创建字体样式 - 增加优先级和更全面的覆盖
|
||||
const style = document.createElement('style');
|
||||
style.id = 'java-fonts-style';
|
||||
style.textContent = `
|
||||
/* 强制应用Java字体到所有元素 */
|
||||
* {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
}
|
||||
|
||||
/* 特定元素覆盖 */
|
||||
body, html {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
font-size: ${fontSize}px !important;
|
||||
}
|
||||
|
||||
.toolbar, button, select, input {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
font-size: ${fontSize}px !important;
|
||||
}
|
||||
|
||||
.log-item {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
font-size: ${fontSize}px !important;
|
||||
}
|
||||
|
||||
/* CodeMirror 编辑器字体 */
|
||||
.CodeMirror, .CodeMirror * {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
font-size: ${fontSize}px !important;
|
||||
}
|
||||
|
||||
.CodeMirror pre, .CodeMirror-code, .CodeMirror-line {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
font-size: ${fontSize}px !important;
|
||||
}
|
||||
|
||||
.query-editor, .editor-content, textarea {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
font-size: ${fontSize}px !important;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
}
|
||||
|
||||
.sidebar-item, .sidebar-title {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
}
|
||||
|
||||
.modal, .form-control {
|
||||
font-family: '${fontFamily}', 'Fira Code', 'JetBrains Mono', monospace !important;
|
||||
}
|
||||
`;
|
||||
|
||||
// 添加到文档头
|
||||
document.head.appendChild(style);
|
||||
|
||||
console.log('Java字体已应用到HTML界面:', fontFamily, fontSize + 'px');
|
||||
|
||||
// 强制刷新CodeMirror编辑器
|
||||
if (window.editor) {
|
||||
setTimeout(() => {
|
||||
editor.refresh();
|
||||
// 重新设置内容以触发完全重绘
|
||||
const content = editor.getValue();
|
||||
editor.setValue('');
|
||||
editor.setValue(content);
|
||||
|
||||
// 额外的刷新确保字体应用
|
||||
setTimeout(() => {
|
||||
editor.refresh();
|
||||
}, 100);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// 记录字体应用事件
|
||||
addEventLog('字体应用', `已应用字体: ${fontFamily} ${fontSize}px`);
|
||||
}
|
||||
}
|
||||
|
||||
// 应用Java主题的函数
|
||||
function applyJavaTheme(themeInfo) {
|
||||
console.log('🎨 开始应用Java主题,原始数据:', themeInfo);
|
||||
|
||||
// 复用现有的主题处理逻辑
|
||||
let isDarkTheme;
|
||||
|
||||
if (typeof themeInfo.isDarkTheme === 'boolean') {
|
||||
isDarkTheme = themeInfo.isDarkTheme;
|
||||
} else if (typeof themeInfo.isDarkTheme === 'string') {
|
||||
// 处理字符串类型的布尔值
|
||||
isDarkTheme = themeInfo.isDarkTheme === 'true' || themeInfo.isDarkTheme === '1';
|
||||
console.log('🔄 转换字符串布尔值:', themeInfo.isDarkTheme, '->', isDarkTheme);
|
||||
} else {
|
||||
// 默认值
|
||||
isDarkTheme = false;
|
||||
console.warn('⚠️ 无法识别isDarkTheme值,使用默认值false');
|
||||
}
|
||||
|
||||
console.log('🎯 最终isDarkTheme值:', isDarkTheme);
|
||||
|
||||
// 直接调用页面现有的主题切换函数
|
||||
const theme = isDarkTheme ? 'dark' : 'light';
|
||||
|
||||
const body = document.body;
|
||||
// 添加强制刷新CSS的函数
|
||||
function forceThemeRefresh() {
|
||||
// 强制重新计算CSS
|
||||
const body = document.body;
|
||||
const currentTheme = body.getAttribute('data-theme');
|
||||
|
||||
// 临时移除再重新添加data-theme属性
|
||||
body.removeAttribute('data-theme');
|
||||
setTimeout(() => {
|
||||
body.setAttribute('data-theme', currentTheme);
|
||||
console.log('强制刷新主题:', currentTheme);
|
||||
}, 10);
|
||||
}
|
||||
function applyTheme(m){
|
||||
body.setAttribute('data-theme', m);
|
||||
document.getElementById('themeToggle').textContent = m === 'light' ? '🌙' : '☀️';
|
||||
}
|
||||
|
||||
// 方法1: 调用现有的 applyTheme 函数
|
||||
if (typeof applyTheme === 'function') {
|
||||
applyTheme(theme);
|
||||
forceThemeRefresh();
|
||||
console.log('✅ 调用现有applyTheme函数:', theme);
|
||||
}
|
||||
const codeMirrorTheme = isDarkTheme ? 'material-darker' : 'nord';
|
||||
if (window.editor) {
|
||||
editor.setOption('theme', codeMirrorTheme);
|
||||
}
|
||||
const themeSelector = document.getElementById('theme-selector');
|
||||
if (themeSelector) {
|
||||
themeSelector.value = theme;
|
||||
}
|
||||
console.log('✅ Java主题已应用到HTML界面:', isDarkTheme ? '深色主题' : '浅色主题');
|
||||
addEventLog('主题应用', `已应用${isDarkTheme ? '深色' : '浅色'}主题`);
|
||||
}
|
||||
|
||||
// 辅助函数:添加事件日志
|
||||
function addEventLog(type, message) {
|
||||
const output = document.getElementById('output');
|
||||
if (output) {
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const logItem = document.createElement('div');
|
||||
logItem.className = `log-item ${type === 'error' ? 'error' : ''}`;
|
||||
logItem.innerHTML = `
|
||||
<i class="fas fa-info-circle"></i>
|
||||
${timestamp}: ${message}
|
||||
`;
|
||||
output.appendChild(logItem);
|
||||
output.scrollTop = output.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化(模拟触发字体加载回调)
|
||||
document.addEventListener('DOMContentLoaded', ()=>{
|
||||
// 初始化 localDbPath
|
||||
@@ -1784,6 +1990,26 @@
|
||||
});
|
||||
}, 600);
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 监听所有对data-theme的修改
|
||||
const observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
|
||||
console.log('主题被修改:', mutation.oldValue, '->', document.body.getAttribute('data-theme'));
|
||||
console.trace('调用堆栈');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
attributes: true,
|
||||
attributeFilter: ['data-theme'],
|
||||
attributeOldValue: true
|
||||
});
|
||||
|
||||
console.log('主题调试已启动');
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -223,7 +223,6 @@ public class BrowserWindow extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Component initializeCef(Builder builder) throws MalformedURLException {
|
||||
if (!isInitialized) {
|
||||
isInitialized = true;
|
||||
@@ -471,9 +470,6 @@ public class BrowserWindow extends JFrame {
|
||||
browser = client.createBrowser(htmlUrl, false, false);
|
||||
}
|
||||
|
||||
String fontInfo = getSystemFontsInfo();
|
||||
injectFontInfoToPage(browser, fontInfo);
|
||||
|
||||
Component browserComponent = browser.getUIComponent();
|
||||
if (builder.browserCreationCallback != null) {
|
||||
boolean handled = builder.browserCreationCallback.onLayoutCustomization(
|
||||
@@ -508,6 +504,7 @@ public class BrowserWindow extends JFrame {
|
||||
config.jsQueryFunction = "javaQuery";// 定义方法
|
||||
config.jsCancelFunction = "javaQueryCancel";// 定义取消方法
|
||||
|
||||
updateTheme();
|
||||
|
||||
// 6. 配置窗口布局(确保只添加一次)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
@@ -585,11 +582,11 @@ public class BrowserWindow extends JFrame {
|
||||
public void updateTheme() {
|
||||
// 1. 获取Java字体信息
|
||||
String fontInfo = getSystemFontsInfo();
|
||||
injectFontInfoToPage(browser, fontInfo);
|
||||
boolean isDarkTheme = AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
|
||||
injectFontInfoToPage(browser, fontInfo, isDarkTheme);
|
||||
|
||||
// 2. 注入主题信息
|
||||
boolean isDarkTheme = AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
|
||||
injectThemeInfoToPage(browser, isDarkTheme);
|
||||
//injectThemeInfoToPage(browser, isDarkTheme);
|
||||
|
||||
//// 3. 刷新浏览器
|
||||
//SwingUtilities.invokeLater(() -> {
|
||||
@@ -650,44 +647,31 @@ public class BrowserWindow extends JFrame {
|
||||
return;
|
||||
}
|
||||
|
||||
client.addLoadHandler(new CefLoadHandlerAdapter() {
|
||||
@Override
|
||||
public void onLoadEnd(CefBrowser browser, CefFrame frame, int httpStatusCode) {
|
||||
String themeInfo = String.format(
|
||||
"{\"isDarkTheme\": %s, \"timestamp\": %d}",
|
||||
isDarkTheme,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
String themeInfo = String.format(
|
||||
"{\"isDarkTheme\": %s, \"timestamp\": %d}",
|
||||
isDarkTheme,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
|
||||
String script =
|
||||
"window.javaThemeInfo = " + themeInfo + ";\n" +
|
||||
"console.log('Java theme information has been loaded:', window.javaThemeInfo);\n" +
|
||||
"\n" +
|
||||
"if (typeof applyJavaTheme === 'function') {\n" +
|
||||
" applyJavaTheme(window.javaThemeInfo);\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"var event = new CustomEvent('javaThemeChanged', {\n" +
|
||||
" detail: window.javaThemeInfo\n" +
|
||||
"});\n" +
|
||||
"document.dispatchEvent(event);\n" +
|
||||
"console.log('The javaThemeChanged event is dispatched');";
|
||||
// 最简单的脚本 - 直接设置和分发事件
|
||||
String script = String.format(
|
||||
"window.javaThemeInfo = %s;" +
|
||||
"console.log('主题信息已设置:', window.javaThemeInfo);" +
|
||||
"" +
|
||||
"var event = new CustomEvent('javaThemeChanged', {" +
|
||||
" detail: window.javaThemeInfo" +
|
||||
"});" +
|
||||
"document.dispatchEvent(event);" +
|
||||
"console.log('javaThemeChanged事件已分发');",
|
||||
themeInfo);
|
||||
|
||||
browser.executeJavaScript(script, browser.getURL(), 0);
|
||||
|
||||
browser.executeJavaScript(
|
||||
"console.log('Theme information injection is complete,window.javaThemeInfo:', typeof window.javaThemeInfo);" +
|
||||
"console.log('Number of theme event listeners:', document.eventListeners ? document.eventListeners('javaThemeChanged') : '无法获取');",
|
||||
browser.getURL(), 0
|
||||
);
|
||||
}
|
||||
});
|
||||
browser.executeJavaScript(script, browser.getURL(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入字体信息到页面并设置字体
|
||||
*/
|
||||
private void injectFontInfoToPage(CefBrowser browser, String fontInfo) {
|
||||
private void injectFontInfoToPage(CefBrowser browser, String fontInfo,boolean isDarkTheme) {
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
@@ -715,6 +699,25 @@ public class BrowserWindow extends JFrame {
|
||||
"console.log('Number of event listeners:', document.eventListeners ? document.eventListeners('javaFontsLoaded') : '无法获取');",
|
||||
browser.getURL(), 0
|
||||
);
|
||||
|
||||
String themeInfo = String.format(
|
||||
"{\"isDarkTheme\": %s, \"timestamp\": %d}",
|
||||
isDarkTheme,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
|
||||
script = String.format(
|
||||
"window.javaThemeInfo = %s;" +
|
||||
"console.log('主题信息已设置:', window.javaThemeInfo);" +
|
||||
"" +
|
||||
"var event = new CustomEvent('javaThemeChanged', {" +
|
||||
" detail: window.javaThemeInfo" +
|
||||
"});" +
|
||||
"document.dispatchEvent(event);" +
|
||||
"console.log('javaThemeChanged事件已分发');",
|
||||
themeInfo);
|
||||
|
||||
browser.executeJavaScript(script, browser.getURL(), 0);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -732,6 +735,11 @@ public class BrowserWindow extends JFrame {
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
if (b) {
|
||||
if (browser != null) {
|
||||
updateTheme();
|
||||
}
|
||||
}
|
||||
super.setVisible(b);
|
||||
}
|
||||
|
||||
|
||||
@@ -513,8 +513,7 @@ public class BrowserWindowJDialog extends JDialog {
|
||||
}
|
||||
}
|
||||
|
||||
String fontInfo = getSystemFontsInfo();
|
||||
injectFontInfoToPage(browser, fontInfo);
|
||||
updateTheme();
|
||||
|
||||
CefMessageRouter.CefMessageRouterConfig config = new CefMessageRouter.CefMessageRouterConfig();
|
||||
config.jsQueryFunction = "javaQuery";// 定义方法
|
||||
@@ -593,6 +592,8 @@ public class BrowserWindowJDialog extends JDialog {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 更新主题
|
||||
*/
|
||||
@@ -609,6 +610,7 @@ public class BrowserWindowJDialog extends JDialog {
|
||||
//SwingUtilities.invokeLater(() -> {
|
||||
// browser.reload();
|
||||
//});
|
||||
|
||||
}
|
||||
private void injectThemeInfoToPage(CefBrowser browser, boolean isDarkTheme) {
|
||||
if (client == null) {
|
||||
@@ -744,6 +746,11 @@ public class BrowserWindowJDialog extends JDialog {
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
if (b) {
|
||||
if (browser != null) {
|
||||
updateTheme();
|
||||
}
|
||||
}
|
||||
super.setVisible(b);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user