feat(browser): 支持 URL 加载并添加黑暗模式支持

- 在 BrowserWindow 和 BrowserWindowJDialog 中添加 htmlUrl 属性,用于支持 URL 加载
- 在 CefAppManager 中添加黑暗模式支持,根据系统主题动态调整浏览器设置
- 在 MainApplication 中使用 htmlUrl 属性创建主窗口
- 移除 ThemeColors 中的 isDarkMode 方法,改用 AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode() 判断黑暗模式
This commit is contained in:
tzdwindows 7
2025-08-17 14:00:43 +08:00
parent c276e35204
commit 2598e25168
6 changed files with 96 additions and 31 deletions

View File

@@ -1,3 +1,3 @@
#Current Loaded Language
#Fri Aug 15 19:03:09 CST 2025
#Sat Aug 16 18:11:03 CST 2025
loadedLanguage=system\:zh_CN

View File

@@ -31,6 +31,7 @@ import static org.cef.callback.CefMenuModel.MenuId.MENU_ID_USER_FIRST;
*/
public class BrowserWindow extends JFrame {
private final String windowId;
private final String htmlUrl;
private CefApp cefApp;
private CefClient client;
private CefBrowser browser;
@@ -51,6 +52,7 @@ public class BrowserWindow extends JFrame {
private boolean resizable = true; // 默认允许调整大小
private boolean maximizable = true; // 默认允许最大化
private boolean minimizable = true; // 默认允许最小化
private String htmlUrl;
public Builder resizable(boolean resizable) {
@@ -113,6 +115,7 @@ public class BrowserWindow extends JFrame {
* 设置HTML路径
*/
public BrowserWindow build() {
if (htmlUrl.isEmpty()) {
if (this.htmlPath == null || this.htmlPath.isEmpty()) {
throw new IllegalArgumentException("HTML paths cannot be empty");
}
@@ -120,6 +123,7 @@ public class BrowserWindow extends JFrame {
if (!htmlFile.exists()) {
throw new RuntimeException("The HTML file does not exist: " + htmlFile.getAbsolutePath());
}
}
return new BrowserWindow(this);
}
@@ -131,12 +135,22 @@ public class BrowserWindow extends JFrame {
this.htmlPath = path;
return this;
}
/**
* 使用Url
* @param htmlUrl Url路径
*/
public Builder htmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
return this;
}
}
private BrowserWindow(Builder builder) {
this.windowId = builder.windowId;
this.htmlPath = builder.htmlPath;
this.operationHandler = builder.operationHandler;
this.htmlUrl = builder.htmlUrl;
// 设置图标(如果存在)
if (builder.icon != null) {
@@ -345,11 +359,16 @@ public class BrowserWindow extends JFrame {
Thread.currentThread().setName("BrowserRenderThread");
// 4. 加载HTML
if (htmlUrl.isEmpty()){
String fileUrl = new File(htmlPath).toURI().toURL().toString();
System.out.println("Loading HTML from: " + fileUrl);
// 5. 创建浏览器组件(直接添加到内容面板)
browser = client.createBrowser(fileUrl, false, false);
} else {
System.out.println("Loading Url from: " + htmlUrl);
browser = client.createBrowser(htmlUrl, false, false);
}
Component browserComponent = browser.getUIComponent();
browser.executeJavaScript("console.log('Java -> HTML 消息测试')",null,2);

View File

@@ -31,6 +31,7 @@ import static org.cef.callback.CefMenuModel.MenuId.MENU_ID_USER_FIRST;
*/
public class BrowserWindowJDialog extends JDialog {
private final String windowId;
private final String htmlUrl;
private CefApp cefApp;
private CefClient client;
private CefBrowser browser;
@@ -52,6 +53,7 @@ public class BrowserWindowJDialog extends JDialog {
private boolean resizable = true; // 默认允许调整大小
private boolean maximizable = true; // 默认允许最大化
private boolean minimizable = true; // 默认允许最小化
private String htmlUrl;
public Builder resizable(boolean resizable) {
@@ -124,6 +126,7 @@ public class BrowserWindowJDialog extends JDialog {
* 设置HTML路径
*/
public BrowserWindowJDialog build() {
if (htmlUrl.isEmpty()) {
if (this.htmlPath == null || this.htmlPath.isEmpty()) {
throw new IllegalArgumentException("HTML paths cannot be empty");
}
@@ -131,6 +134,7 @@ public class BrowserWindowJDialog extends JDialog {
if (!htmlFile.exists()) {
throw new RuntimeException("The HTML file does not exist: " + htmlFile.getAbsolutePath());
}
}
return new BrowserWindowJDialog(this);
}
@@ -142,6 +146,15 @@ public class BrowserWindowJDialog extends JDialog {
this.htmlPath = path;
return this;
}
/**
* 使用Url
* @param htmlUrl Url路径
*/
public Builder htmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
return this;
}
}
private BrowserWindowJDialog(Builder builder) {
@@ -149,6 +162,7 @@ public class BrowserWindowJDialog extends JDialog {
super(builder.parentFrame, builder.title, builder.parentFrame != null);
this.windowId = builder.windowId;
this.htmlPath = builder.htmlPath;
this.htmlUrl = builder.htmlUrl;
this.operationHandler = builder.operationHandler;
// 设置图标(如果存在)
@@ -357,11 +371,16 @@ public class BrowserWindowJDialog extends JDialog {
Thread.currentThread().setName("BrowserRenderThread");
// 4. 加载HTML
if (htmlUrl.isEmpty()) {
String fileUrl = new File(htmlPath).toURI().toURL().toString();
System.out.println("Loading HTML from: " + fileUrl);
// 5. 创建浏览器组件(直接添加到内容面板)
browser = client.createBrowser(fileUrl, false, false);
} else {
System.out.println("Loading HTML from: " + htmlUrl);
browser = client.createBrowser(htmlUrl, false, false);
}
Component browserComponent = browser.getUIComponent();
browser.executeJavaScript("console.log('Java -> HTML 消息测试')",null,2);

View File

@@ -1,10 +1,13 @@
package com.axis.innovators.box.browser;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.tools.FolderCreator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.cef.CefApp;
import org.cef.CefSettings;
import org.cef.callback.CefCommandLine;
import org.cef.handler.CefAppHandlerAdapter;
import java.io.File;
import java.util.concurrent.TimeUnit;
@@ -69,12 +72,35 @@ public class CefAppManager {
//settings.background_color = new Color(255, 255, 255, 0);
settings.command_line_args_disabled = false;
boolean isDarkTheme = isDarkTheme();
if (isDarkTheme) {
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
@Override
public void onBeforeCommandLineProcessing(
String processType,
CefCommandLine commandLine
) {
commandLine.appendSwitch("force-dark-mode");
commandLine.appendSwitchWithValue("enable-features", "WebContentsForceDark");
}
});
logger.info("Dark theme settings applied");
}
logger.info("Optimized CEF settings initialized");
} finally {
initLock.unlock();
}
}
private static boolean isDarkTheme() {
if (AxisInnovatorsBox.getMain() == null){
return false;
}
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
}
public static CefApp getInstance() {
if (cefApp == null) {
if (initLock.tryLock()) {

View File

@@ -37,7 +37,14 @@ public class MainApplication {
private static long ctxHandle;
private static boolean isSystem = true;
public static void main(String[] args) {
AtomicReference<BrowserWindow> window = new AtomicReference<>();
WindowRegistry.getInstance().createNewWindow("main", builder ->
window.set(builder.title("Axis Innovators Box AI 工具箱")
.size(1280, 720)
.htmlUrl("https://chat.deepseek.com/")
.operationHandler(createOperationHandler())
.build())
);
}

View File

@@ -3,6 +3,9 @@ package com.axis.innovators.box.window;
import javax.swing.*;
import java.awt.*;
/**
* @author tzdwindows 7
*/
public class ThemeColors {
// 工具方法:使颜色变暗 (factor: 0~10.2表示变暗20%)
public static Color darken(Color color, float factor) {
@@ -23,13 +26,4 @@ public class ThemeColors {
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;
}
}