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 #Current Loaded Language
#Fri Aug 15 19:03:09 CST 2025 #Sat Aug 16 18:11:03 CST 2025
loadedLanguage=system\:zh_CN 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 { public class BrowserWindow extends JFrame {
private final String windowId; private final String windowId;
private final String htmlUrl;
private CefApp cefApp; private CefApp cefApp;
private CefClient client; private CefClient client;
private CefBrowser browser; private CefBrowser browser;
@@ -51,6 +52,7 @@ public class BrowserWindow extends JFrame {
private boolean resizable = true; // 默认允许调整大小 private boolean resizable = true; // 默认允许调整大小
private boolean maximizable = true; // 默认允许最大化 private boolean maximizable = true; // 默认允许最大化
private boolean minimizable = true; // 默认允许最小化 private boolean minimizable = true; // 默认允许最小化
private String htmlUrl;
public Builder resizable(boolean resizable) { public Builder resizable(boolean resizable) {
@@ -113,12 +115,14 @@ public class BrowserWindow extends JFrame {
* 设置HTML路径 * 设置HTML路径
*/ */
public BrowserWindow build() { public BrowserWindow build() {
if (this.htmlPath == null || this.htmlPath.isEmpty()) { if (htmlUrl.isEmpty()) {
throw new IllegalArgumentException("HTML paths cannot be empty"); if (this.htmlPath == null || this.htmlPath.isEmpty()) {
} throw new IllegalArgumentException("HTML paths cannot be empty");
File htmlFile = new File(this.htmlPath); }
if (!htmlFile.exists()) { File htmlFile = new File(this.htmlPath);
throw new RuntimeException("The HTML file does not exist: " + htmlFile.getAbsolutePath()); if (!htmlFile.exists()) {
throw new RuntimeException("The HTML file does not exist: " + htmlFile.getAbsolutePath());
}
} }
return new BrowserWindow(this); return new BrowserWindow(this);
} }
@@ -131,12 +135,22 @@ public class BrowserWindow extends JFrame {
this.htmlPath = path; this.htmlPath = path;
return this; return this;
} }
/**
* 使用Url
* @param htmlUrl Url路径
*/
public Builder htmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
return this;
}
} }
private BrowserWindow(Builder builder) { private BrowserWindow(Builder builder) {
this.windowId = builder.windowId; this.windowId = builder.windowId;
this.htmlPath = builder.htmlPath; this.htmlPath = builder.htmlPath;
this.operationHandler = builder.operationHandler; this.operationHandler = builder.operationHandler;
this.htmlUrl = builder.htmlUrl;
// 设置图标(如果存在) // 设置图标(如果存在)
if (builder.icon != null) { if (builder.icon != null) {
@@ -345,11 +359,16 @@ public class BrowserWindow extends JFrame {
Thread.currentThread().setName("BrowserRenderThread"); Thread.currentThread().setName("BrowserRenderThread");
// 4. 加载HTML // 4. 加载HTML
String fileUrl = new File(htmlPath).toURI().toURL().toString(); if (htmlUrl.isEmpty()){
System.out.println("Loading HTML from: " + fileUrl); String fileUrl = new File(htmlPath).toURI().toURL().toString();
System.out.println("Loading HTML from: " + fileUrl);
// 5. 创建浏览器组件(直接添加到内容面板) // 5. 创建浏览器组件(直接添加到内容面板)
browser = client.createBrowser(fileUrl, false, false); browser = client.createBrowser(fileUrl, false, false);
} else {
System.out.println("Loading Url from: " + htmlUrl);
browser = client.createBrowser(htmlUrl, false, false);
}
Component browserComponent = browser.getUIComponent(); Component browserComponent = browser.getUIComponent();
browser.executeJavaScript("console.log('Java -> HTML 消息测试')",null,2); 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 { public class BrowserWindowJDialog extends JDialog {
private final String windowId; private final String windowId;
private final String htmlUrl;
private CefApp cefApp; private CefApp cefApp;
private CefClient client; private CefClient client;
private CefBrowser browser; private CefBrowser browser;
@@ -52,6 +53,7 @@ public class BrowserWindowJDialog extends JDialog {
private boolean resizable = true; // 默认允许调整大小 private boolean resizable = true; // 默认允许调整大小
private boolean maximizable = true; // 默认允许最大化 private boolean maximizable = true; // 默认允许最大化
private boolean minimizable = true; // 默认允许最小化 private boolean minimizable = true; // 默认允许最小化
private String htmlUrl;
public Builder resizable(boolean resizable) { public Builder resizable(boolean resizable) {
@@ -124,12 +126,14 @@ public class BrowserWindowJDialog extends JDialog {
* 设置HTML路径 * 设置HTML路径
*/ */
public BrowserWindowJDialog build() { public BrowserWindowJDialog build() {
if (this.htmlPath == null || this.htmlPath.isEmpty()) { if (htmlUrl.isEmpty()) {
throw new IllegalArgumentException("HTML paths cannot be empty"); if (this.htmlPath == null || this.htmlPath.isEmpty()) {
} throw new IllegalArgumentException("HTML paths cannot be empty");
File htmlFile = new File(this.htmlPath); }
if (!htmlFile.exists()) { File htmlFile = new File(this.htmlPath);
throw new RuntimeException("The HTML file does not exist: " + htmlFile.getAbsolutePath()); if (!htmlFile.exists()) {
throw new RuntimeException("The HTML file does not exist: " + htmlFile.getAbsolutePath());
}
} }
return new BrowserWindowJDialog(this); return new BrowserWindowJDialog(this);
} }
@@ -142,6 +146,15 @@ public class BrowserWindowJDialog extends JDialog {
this.htmlPath = path; this.htmlPath = path;
return this; return this;
} }
/**
* 使用Url
* @param htmlUrl Url路径
*/
public Builder htmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
return this;
}
} }
private BrowserWindowJDialog(Builder builder) { private BrowserWindowJDialog(Builder builder) {
@@ -149,6 +162,7 @@ public class BrowserWindowJDialog extends JDialog {
super(builder.parentFrame, builder.title, builder.parentFrame != null); super(builder.parentFrame, builder.title, builder.parentFrame != null);
this.windowId = builder.windowId; this.windowId = builder.windowId;
this.htmlPath = builder.htmlPath; this.htmlPath = builder.htmlPath;
this.htmlUrl = builder.htmlUrl;
this.operationHandler = builder.operationHandler; this.operationHandler = builder.operationHandler;
// 设置图标(如果存在) // 设置图标(如果存在)
@@ -357,11 +371,16 @@ public class BrowserWindowJDialog extends JDialog {
Thread.currentThread().setName("BrowserRenderThread"); Thread.currentThread().setName("BrowserRenderThread");
// 4. 加载HTML // 4. 加载HTML
String fileUrl = new File(htmlPath).toURI().toURL().toString(); if (htmlUrl.isEmpty()) {
System.out.println("Loading HTML from: " + fileUrl); String fileUrl = new File(htmlPath).toURI().toURL().toString();
System.out.println("Loading HTML from: " + fileUrl);
// 5. 创建浏览器组件(直接添加到内容面板) // 5. 创建浏览器组件(直接添加到内容面板)
browser = client.createBrowser(fileUrl, false, false); browser = client.createBrowser(fileUrl, false, false);
} else {
System.out.println("Loading HTML from: " + htmlUrl);
browser = client.createBrowser(htmlUrl, false, false);
}
Component browserComponent = browser.getUIComponent(); Component browserComponent = browser.getUIComponent();
browser.executeJavaScript("console.log('Java -> HTML 消息测试')",null,2); browser.executeJavaScript("console.log('Java -> HTML 消息测试')",null,2);

View File

@@ -1,10 +1,13 @@
package com.axis.innovators.box.browser; package com.axis.innovators.box.browser;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.tools.FolderCreator; import com.axis.innovators.box.tools.FolderCreator;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.cef.CefApp; import org.cef.CefApp;
import org.cef.CefSettings; import org.cef.CefSettings;
import org.cef.callback.CefCommandLine;
import org.cef.handler.CefAppHandlerAdapter;
import java.io.File; import java.io.File;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -69,12 +72,35 @@ public class CefAppManager {
//settings.background_color = new Color(255, 255, 255, 0); //settings.background_color = new Color(255, 255, 255, 0);
settings.command_line_args_disabled = false; 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"); logger.info("Optimized CEF settings initialized");
} finally { } finally {
initLock.unlock(); initLock.unlock();
} }
} }
private static boolean isDarkTheme() {
if (AxisInnovatorsBox.getMain() == null){
return false;
}
return AxisInnovatorsBox.getMain().getRegistrationTopic().isDarkMode();
}
public static CefApp getInstance() { public static CefApp getInstance() {
if (cefApp == null) { if (cefApp == null) {
if (initLock.tryLock()) { if (initLock.tryLock()) {

View File

@@ -37,7 +37,14 @@ public class MainApplication {
private static long ctxHandle; private static long ctxHandle;
private static boolean isSystem = true; private static boolean isSystem = true;
public static void main(String[] args) { 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 javax.swing.*;
import java.awt.*; import java.awt.*;
/**
* @author tzdwindows 7
*/
public class ThemeColors { public class ThemeColors {
// 工具方法:使颜色变暗 (factor: 0~10.2表示变暗20%) // 工具方法:使颜色变暗 (factor: 0~10.2表示变暗20%)
public static Color darken(Color color, float factor) { public static Color darken(Color color, float factor) {
@@ -23,13 +26,4 @@ public class ThemeColors {
color.getAlpha() 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;
}
} }