映射
在本节中,我们将展示 6.x 版本的主要功能如何映射到 7.0 版本。
Engine
创建 Engine
6.x
Engine
不是公共 API 的一部分。它是在应用程序中创建第一个 Browser
实例时在内部创建的。在应用程序中只能创建和使用一个 Engine
。
7.0
Engine
现在是公共 API 的一部分。您可以在应用程序中创建和使用多个 Engine
实例。要创建带有所需选项的 Engine
实例,请使用以下代码:
Engine engine = Engine.newInstance(
EngineOptions.newBuilder(RenderingMode.OFF_SCREEN)
// 默认错误页面和 GUI 中使用的语言。
.language(Language.ENGLISH_US)
// 存储数据的绝对路径目录,例如缓存、Cookies、历史记录、
// GPU 缓存、本地存储、已访问链接、Web 数据、拼写检查词典文件等。
.userDataDir(Paths.get("/Users/Me/JxBrowser/UserData"))
.build());
val engine = Engine.newInstance(
EngineOptions.newBuilder(RenderingMode.OFF_SCREEN)
// 默认错误页面和 GUI 使用的语言。
.language(Language.ENGLISH_US)
// 存储数据的绝对路径目录,例如缓存、Cookies、历史记录、
// GPU 缓存、本地存储、已访问链接、Web 数据、拼写检查词典文件等。
.userDataDir(Path("/Users/Me/JxBrowser/UserData"))
.build()
)
Engine
运行一个单独的本地进程,在其中创建并初始化带有指定选项的 Chromium。该本地进程通过进程间通信 (IPC) 桥与 Java 进程进行通信。如果本地进程因崩溃而意外终止,Java 进程将继续运行。
您可以使用以下通知来了解 Engine
何时意外终止,以便您可以重新创建 Engine
并恢复 Browser
实例:
engine.on(EngineCrashed.class, event -> {
// 清除所有已分配的资源并重新创建 Engine。
});
engine.on(EngineCrashed::class.java) { event ->
// 清除所有已分配的资源并重新创建 Engine。
}
关闭 Engine
6.x
当应用程序中的最后一个 Browser
实例关闭时,Engine
会自动关闭。
7.0
当不再需要 Engine 时,应通过调用 close()
方法来手动关闭它:
engine.close();
engine.close()
当您关闭 Engine
时,其所有 Browser
实例都将自动关闭。任何尝试使用已关闭的 Engine
的操作都会导致异常。
要了解 Engine
何时关闭,请使用以下通知:
engine.on(EngineClosed.class, event -> {});
engine.on(EngineClosed::class.java) { event -> }
Browser
创建 Browser
6.x
Browser browser = new Browser();
val browser = Browser()
7.0
Browser browser = engine.newBrowser();
val browser = engine.newBrowser()
使用选项创建 Browser
6.x
BrowserContextParams browserContextParams =
new BrowserContextParams("Users/Me/JxBrowser/Data");
browserContextParams.setStorageType(StorageType.MEMORY);
BrowserContext browserContext = new BrowserContext(browserContextParams);
Browser browser = new Browser(BrowserType.HEAVYWEIGHT, browserContext);
val browserContextParams = BrowserContextParams("Users/Me/JxBrowser/Data")
browserContextParams.setStorageType(StorageType.MEMORY)
val browserContext = BrowserContext(browserContextParams)
val browser = Browser(BrowserType.HEAVYWEIGHT, browserContext)
7.0
BrowserContext
功能已经移至 Engine
。因此,因此,相同的代码应替换为:
Engine engine = Engine.newInstance(EngineOptions.newBuilder(HARDWARE_ACCELERATED)
.userDataDir(Paths.get("/Users/Me/JxBrowser/UserData"))
.enableIncognito()
.build());
Browser browser = engine.newBrowser();
val engine = Engine.newInstance(EngineOptions.newBuilder(HARDWARE_ACCELERATED)
.userDataDir(Path("/Users/Me/JxBrowser/UserData"))
.enableIncognito()
.build()
)
val browser = engine.newBrowser()
关闭 Browser
6.x
browser.dispose();
browser.dispose()
7.0
browser.close();
browser.close()
响应/无响应
6.x
browser.addRenderListener(new RenderAdapter() {
@Override
public void onRenderUnresponsive(RenderEvent event) {}
@Override
public void onRenderResponsive(RenderEvent event) {}
});
browser.addRenderListener(object: RenderAdapter {
override fun onRenderUnresponsive(event: RenderEvent) {}
override fun onRenderResponsive(event: RenderEvent) {}
})
7.0
browser.on(BrowserBecameResponsive.class, event -> {});
browser.on(BrowserBecameUnresponsive.class, event -> {});
browser.on(BrowserBecameResponsive::class.java) { event -> }
browser.on(BrowserBecameUnresponsive::class.java) { event -> }
BrowserView
创建 Swing BrowserView
6.x
import com.teamdev.jxbrowser.chromium.swing.BrowserView;
...
BrowserView view = new BrowserView(browser);
import com.teamdev.jxbrowser.chromium.swing.BrowserView
...
val view = BrowserView(browser)
7.0
import com.teamdev.jxbrowser.view.swing.BrowserView;
...
BrowserView view = BrowserView.newInstance(browser);
import com.teamdev.jxbrowser.view.swing.BrowserView
...
val view = BrowserView.newInstance(browser)
创建 JavaFX BrowserView
6.x
import com.teamdev.jxbrowser.chromium.javafx.BrowserView;
...
BrowserView view = new BrowserView(browser);
import com.teamdev.jxbrowser.chromium.javafx.BrowserView
...
val view = BrowserView(browser)
7.0
import com.teamdev.jxbrowser.view.javafx.BrowserView;
...
BrowserView view = BrowserView.newInstance(browser);
import com.teamdev.jxbrowser.view.javafx.BrowserView
...
val view = BrowserView.newInstance(browser)
Frame
与 Frame 交互
6.x
一个网页可能包含一个主 Frame,该 Frame 可能包含多个子 Frame。要对某个 Frame 执行操作,您需要将 Frame 的标识符传递给对应的方法。例如:
// 获取主 Frame 的 HTML。
browser.getHTML();
// 获取所有 Frame 的 HTML。
for (Long frameId : browser.getFramesIds()) {
String html = browser.getHTML(frameId);
}
// 获取主 Frame 的 HTML。
browser.html
// 获取所有 Frame 的 HTML。
for (frameId in browser.framesIds) {
val html = browser.getHTML(frameId)
}
7.0
Frame
现在是公共 API 的一部分。您可以通过 Frame
实例与框架进行交互。例如:
// 如果主 Frame 存在,则获取其 HTML。
browser.mainFrame().ifPresent(Frame::getHtml);
// 获取所有 Frame 的 HTML。
browser.frames().forEach(frame -> {
String html = frame.html();
});
// 如果主 Frame 存在,则获取其 HTML。
browser.mainFrame().ifPresent(Frame::getHtml)
// 获取所有 Frame 的 HTML。
browser.frames().forEach { frame ->
val html = frame.html()
}
导航
加载 URL
6.x
browser.loadURL("https://www.google.com");
browser.loadURL("https://www.google.com")
7.0
browser.navigation().loadUrl("https://www.google.com");
browser.navigation().loadUrl("https://www.google.com")
加载 HTML
6.x
browser.loadHTML("<html><body></body></html>");
browser.loadHTML("<html><body></body></html>")
7.0
browser.mainFrame().ifPresent(frame ->
frame.loadHtml("<html><body></body></html>"));
browser.mainFrame().ifPresent { frame ->
frame.loadHtml("<html><body></body></html>") }
过滤 URLs
6.x
browser.setLoadHandler(new DefaultLoadHandler() {
@Override
public boolean onLoad(LoadParams params) {
if (params.getURL().startsWith("mailto:")) {
return true; // 取消加载
}
return false; // 继续加载
}
});
browser.setLoadHandler(object: DefaultLoadHandler {
override fun onLoad(params: LoadParams): Boolean {
return if (params.getURL().startsWith("mailto:")) {
true // 取消加载
} else false // 继续加载
}
})
7.0
navigation.set(StartNavigationCallback.class, params -> {
if (params.url().startsWith("mailto:")) {
return Response.ignore();
}
return Response.start();
});
navigation.set(StartNavigationCallback::class.java,
StartNavigationCallback { params ->
if (params.url().startsWith("mailto:")) Response.ignore() else Response.start()
}
)
导航事件
开始加载
6.x
browser.addLoadListener(new LoadAdapter() {
@Override
public void onStartLoadingFrame(StartLoadingEvent event) {
String url = event.getValidatedURL();
}
});
browser.addLoadListener(object: LoadAdapter {
override fun onStartLoadingFrame(event: StartLoadingEvent) {
val url = event.validatedURL
}
})
7.0
browser.navigation().on(NavigationStarted.class, event -> {
String url = event.url();
});
browser.navigation().on(NavigationStarted::class.java) { event ->
val url = event.url()
}
加载完成
6.x
browser.addLoadListener(new LoadAdapter() {
@Override
public void onFinishLoadingFrame(FinishLoadingEvent event) {
String html = browser.getHTML(event.getFrameId());
}
});
browser.addLoadListener(object: LoadAdapter {
override fun onFinishLoadingFrame(event: FinishLoadingEvent) {
val html = browser.getHTML(event.frameId)
}
})
7.0
browser.navigation().on(FrameLoadFinished.class, event -> {
String html = event.frame().html();
});
browser.navigation().on(FrameLoadFinished::class.java) { event ->
val html = event.frame().html()
}
加载失败
6.x
browser.addLoadListener(new LoadAdapter() {
@Override
public void onFailLoadingFrame(FailLoadingEvent event) {
NetError errorCode = event.getErrorCode();
}
});
browser.addLoadListener(object: LoadAdapter {
override fun onFailLoadingFrame(event: FailLoadingEvent) {
val errorCode = event.errorCode
}
})
7.0
browser.navigation().on(FrameLoadFailed.class, event -> {
NetError error = event.error();
});
browser.navigation().on(FrameLoadFailed::class.java) { event ->
val error = event.error()
}
browser.navigation().on(NavigationFinished.class, event -> {
NetError errorCode = event.error();
});
browser.navigation().on(NavigationFinished::class.java) { event ->
val errorCode = event.error()
}
网络
配置 User-Agent
6.x
BrowserPreferences.setUserAgent("My User-Agent");
BrowserPreferences.setUserAgent("My User-Agent")
7.0
Engine engine = Engine.newInstance(EngineOptions.newBuilder(...)
.userAgent("My User-Agent")
.build());
val engine = Engine.newInstance(EngineOptions.newBuilder(...)
.userAgent("My User-Agent")
.build())
配置 Accept-Language
6.x
browserContext.setAcceptLanguage("fr, en-gb;q=0.8, en;q=0.7");
browserContext.setAcceptLanguage("fr, en-gb;q=0.8, en;q=0.7")
7.0
engine.network().acceptLanguage("fr, en-gb;q=0.8, en;q=0.7");
engine.network().acceptLanguage("fr, en-gb;q=0.8, en;q=0.7")
配置代理
6.x
ProxyService proxyService = browserContext.getProxyService();
proxyService.setProxyConfig(new CustomProxyConfig("http-proxy-server:80"));
val proxyService = browserContext.proxyService
proxyService.setProxyConfig(CustomProxyConfig("http-proxy-server:80"))
7.0
engine.proxy().config(CustomProxyConfig.newInstance("http-proxy-server:80"));
engine.proxy().config(CustomProxyConfig.newInstance("http-proxy-server:80"))
重定向 URL 请求
6.x
browserContext.getNetworkService().setNetworkDelegate(new NetworkDelegate() {
@Override
public void onBeforeURLRequest(BeforeURLRequestParams params) {
params.setURL("https://www.google.com");
}
});
browserContext.networkService.setNetworkDelegate(object: NetworkDelegate {
override fun onBeforeURLRequest(params: BeforeURLRequestParams) {
params.setURL("https://www.google.com")
}
})
7.0
engine.network().set(BeforeUrlRequestCallback.class, (params) ->
Response.redirect("https://www.google.com"));
engine.network().set(BeforeUrlRequestCallback::class.java,
BeforeUrlRequestCallback { params ->
Response.redirect("https://www.google.com")
}
)
覆盖 HTTP 标头
6.x
browserContext.getNetworkService().setNetworkDelegate(new NetworkDelegate() {
...
@Override
public void onBeforeSendHeaders(BeforeSendHeadersParams params) {
HttpHeadersEx headers = params.getHeadersEx();
headers.setHeader("User-Agent", "MyUserAgent");
headers.setHeader("Content-Type", "text/html");
}
});
browserContext.networkService.setNetworkDelegate(object: NetworkDelegate {
override fun onBeforeSendHeaders(params: BeforeSendHeadersParams) {
val headers = params.headersEx
headers.setHeader("User-Agent", "MyUserAgent")
headers.setHeader("Content-Type", "text/html")
}
})
7.0
engine.network().set(BeforeSendHeadersCallback.class, (params) ->
Response.override(Arrays.asList(
HttpHeader.of("User-Agent", "MyUserAgent"),
HttpHeader.of("Content-Type", "text/html"))));
engine.network().set(BeforeSendHeadersCallback::class.java,
BeforeSendHeadersCallback { params ->
Response.override(listOf(
HttpHeader.of("User-Agent", "MyUserAgent"),
HttpHeader.of("Content-Type", "text/html")))
}
)
拦截 URL 请求
6.x
BrowserContext browserContext = browser.getContext();
ProtocolService protocolService = browserContext.getProtocolService();
protocolService.setProtocolHandler("https", new ProtocolHandler() {
@Override
public URLResponse onRequest(URLRequest request) {
URLResponse response = new URLResponse();
String html = "<html><body><p>你好呀!</p></body></html>";
response.setData(html.getBytes());
response.getHeaders().setHeader("Content-Type", "text/html");
return response;
}
});
val browserContext = browser.context
val protocolService = browserContext.protocolService
protocolService.setProtocolHandler("https", object: ProtocolHandler {
override fun onRequest(request: URLRequest): URLResponse {
val response = URLResponse()
val html = "<html><body><p>你好呀!</p></body></html>"
response.setData(html.toByteArray())
response.headers.setHeader("Content-Type", "text/html")
return response
}
});
7.0
Network network = engine.network();
network.set(InterceptRequestCallback.class, params -> {
UrlRequest urlRequest = params.urlRequest();
if (urlRequest.url().startsWith("https")) {
Options options = UrlRequestJob.Options
.newBuilder(urlRequest.id(), HttpStatus.OK)
.addHttpHeader(HttpHeader.of("Content-Type", "text/html"))
.build();
UrlRequestJob urlRequestJob = network.newUrlRequestJob(options);
String html = "<html><body><p>你好呀!</p></body></html>";
urlRequestJob.write(html.getBytes(UTF_8));
urlRequestJob.complete();
return Response.intercept(urlRequestJob);
}
return Response.proceed();
});
val network = engine.network()
network.set(InterceptRequestCallback::class.java, InterceptRequestCallback { params ->
val urlRequest = params.urlRequest()
if (urlRequest.url().startsWith("https")) {
val options = UrlRequestJob.Options
.newBuilder(urlRequest.id(), HttpStatus.OK)
.addHttpHeader(HttpHeader.of("Content-Type", "text/html"))
.build()
val urlRequestJob = network.newUrlRequestJob(options)
val html = "<html><body><p>你好呀!</p></body></html>"
urlRequestJob.write(html.toByteArray(UTF_8))
urlRequestJob.complete()
Response.intercept(urlRequestJob)
} else {
Response.proceed()
}
})
身份验证
Proxy、Basic、Digest、NTLM
6.x
NetworkService networkService = browserContext.getNetworkService();
networkService.setNetworkDelegate(new NetworkDelegate() {
...
@Override
public boolean onAuthRequired(AuthRequiredParams params) {
if (params.isProxy()) {
params.setUsername("用户");
params.setPassword("密码");
return false;
}
return true; // 取消身份验证请求
}
});
val networkService = browser.networkService
networkService.setNetworkDelegate(object: NetworkDelegate {
...
override fun onAuthRequired(params: AuthRequiredParams): Boolean {
return if (params.isProxy()) {
params.setUsername("用户")
params.setPassword("密码")
false
} else true // 取消身份验证请求
}
});
7.0
engine.network().set(AuthenticateCallback.class, (params, tell) -> {
if (params.isProxy()) {
tell.authenticate("用户", "密码");
} else {
tell.cancel();
}
});
engine.network().set(AuthenticateCallback::class.java,
AuthenticateCallback { params, tell ->
if (params.isProxy) {
tell.authenticate("用户", "密码")
} else {
tell.cancel()
}
}
)
HTTPS 客户端证书
6.x
browser.setDialogHandler(new DialogHandler() {
...
@Override
public CloseStatus onSelectCertificate(CertificatesDialogParams params) {
List<Certificate> certificates = params.getCertificates();
if (certificates.isEmpty()) {
return CloseStatus.CANCEL;
} else {
params.setSelectedCertificate(certificates.get(certificates.size() - 1));
return CloseStatus.OK;
}
}
});
browser.setDialogHandler(object: DialogHandler {
...
override fun onSelectCertificate(params: CertificatesDialogParams): CloseStatus {
val certificates = params.certificates
return if (certificates.isEmpty()) {
CloseStatus.CANCEL
} else {
params.setSelectedCertificate(certificates[certificates.size - 1])
CloseStatus.OK
}
}
});
7.0
browser.set(SelectClientCertificateCallback.class, (params, tell) -> {
List<Certificate> certificates = params.certificates();
if (certificates.isEmpty()) {
tell.cancel();
} else {
tell.select(certificates.size() - 1);
}
});
browser.set(SelectClientCertificateCallback::class.java,
SelectClientCertificateCallback { params, tell ->
val certificates = params.certificates()
if (certificates.isEmpty()) {
tell.cancel()
} else {
tell.select(certificates.size - 1)
}
}
)
插件
过滤插件
6.x
browser.getPluginManager().setPluginFilter(new PluginFilter() {
@Override
public boolean isPluginAllowed(PluginInfo pluginInfo) {
return true;
}
});
browser.pluginManager.setPluginFilter(object: PluginFilter {
override fun isPluginAllowed(pluginInfo: PluginInfo): Boolean {
return true
}
})
7.0
engine.plugins().set(AllowPluginCallback.class, params -> Response.allow());
engine.plugins().set(AllowPluginCallback::class.java,
AllowPluginCallback { Response.allow() })
DOM
访问文档
6.x
DOMDocument document = browser.getDocument();
if (document != null) {
String baseURI = document.getBaseURI();
}
val document = browser.document
val baseURI = document?.baseURI
7.0
browser.mainFrame().ifPresent(frame ->
frame.document().ifPresent(document -> {
String baseUri = document.baseUri();
}));
browser.mainFrame().ifPresent { frame ->
frame.document().ifPresent { document ->
val baseUri = document.baseUri()
}
}
DOM 事件
处理事件
6.x
element.addEventListener(DOMEventType.OnClick, new DOMEventListener() {
@Override
public void handleEvent(DOMEvent event) {
DOMEventTarget eventTarget = event.getTarget();
if (eventTarget != null) {
...
}
}
}, false);
element.addEventListener(DOMEventType.OnClick, object: DOMEventListener {
override fun handleEvent(event: DOMEvent) {
val eventTarget = event.target
if (eventTarget != null) {
...
}
}
})
7.0
element.addEventListener(EventType.CLICK, event ->
event.target().ifPresent(eventTarget -> {
...
}), false);
element.addEventListener(EventType.CLICK, { event ->
event.target().ifPresent { eventTarget ->
...
}
}, false)
CSS
注入 CSS
6.x
browser.setCustomStyleSheet("body { background-color: orange; }");
browser.setCustomStyleSheet("body { background-color: orange; }")
7.0
browser.set(InjectCssCallback.class, params ->
Response.inject("body { background-color: orange; }"));
browser.set(InjectCssCallback::class.java,
InjectCssCallback { Response.inject("body { background-color: orange; }") })
JavaScript
从 Java 调用 JavaScript
6.x
String string = browser.executeJavaScriptAndReturnValue("'你好'")
.asString().getValue();
double number = browser.executeJavaScriptAndReturnValue("123")
.asNumber().getValue();
boolean bool = browser.executeJavaScriptAndReturnValue("true")
.asBoolean().getValue();
JSObject window = browser.executeJavaScriptAndReturnValue("window")
.asObject();
val string = browser.executeJavaScriptAndReturnValue("'你好'")
.asString().value
val number = browser.executeJavaScriptAndReturnValue("123")
.asNumber().value
val bool = browser.executeJavaScriptAndReturnValue("true")
.asBoolean().value
val window = browser.executeJavaScriptAndReturnValue("window")
.asObject()
7.0
JSValue
类已被移除。现在类型转换是自动完成的。您可以选择同步执行 JavaScript 来阻塞当前线程,或者选择异步执行:
browser.mainFrame().ifPresent(frame -> {
String string = frame.executeJavaScript("'你好'");
Double number = frame.executeJavaScript("123");
Boolean bool = frame.executeJavaScript("true");
JsObject window = frame.executeJavaScript("window");
frame.executeJavaScript("document", (Consumer<Document>) document -> {
String baseUri = document.baseUri();
});
});
browser.mainFrame().ifPresent { frame: Frame ->
val string = frame.executeJavaScript<String>("'你好'")
val number = frame.executeJavaScript<Double>("123")
val bool = frame.executeJavaScript<Boolean>("true")
val window = frame.executeJavaScript<JsObject>("window")
frame.executeJavaScript("document", Consumer<Document> { document ->
val baseUri = document.baseUri()
})
}
从 JavaScript 调用 Java
6.x
在 Java 代码中:
public class JavaObject {
public void foo(String text) {}
}
…
JSValue window = browser.executeJavaScriptAndReturnValue("window");
if (window.isObject()) {
window.asObject().setProperty("java", new JavaObject());
}
class JavaObject {
fun foo(text String) {}
}
…
val window = browser.executeJavaScriptAndReturnValue("window")
if (window.isObject()) {
window.asObject().setProperty("java", JavaObject())
}
在 JavaScript 代码中:
window.java.foo("你好");
7.0
出于安全考虑,只有使用 @JsAccessible
注解标记的公共方法可以从 JavaScript 中访问。
在 Java 代码中:
public class JavaObject {
@JsAccessible
public void foo(String text) {}
}
…
JsObject window = frame.executeJavaScript("window");
window.putProperty("java", new JavaObject());
class JavaObject {
@JsAccessible
fun foo(text: String) {}
}
…
val window = frame.executeJavaScript<JsObject>("window")
window?.putProperty("java", JavaObject())
在 JavaScript 代码中:
window.java.foo("你好");
注入 JavaScript
6.x
browser.addScriptContextListener(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = browser.executeJavaScriptAndReturnValue(
event.getJSContext().getFrameId(), "window");
}
});
browser.addScriptContextListener(object: ScriptContextAdapter {
override fun onScriptContextCreated(event: ScriptContextEvent) {
val window = browser.executeJavaScriptAndReturnValue(
event.jsContext.frameId, "window")
}
})
7.0
browser.set(InjectJsCallback.class, params -> {
JsObject window = params.frame().executeJavaScript("window");
return Response.proceed();
});
browser.set(InjectJsCallback::class.java, InjectJsCallback { params ->
val window = params.frame().executeJavaScript<JsObject>("window")
Response.proceed()
})
控制台事件
6.x
browser.addConsoleListener(new ConsoleListener() {
@Override
public void onMessage(ConsoleEvent event) {
String message = event.getMessage();
}
});
browser.addConsoleListener(object: ConsoleListener {
override fun onMessage(event: ConsoleEvent) {
val message = event.message
}
})
7.0
browser.on(ConsoleMessageReceived.class, event -> {
String message = event.consoleMessage().message();
});
browser.on(ConsoleMessageReceived::class.java) { event ->
val message = event.consoleMessage().message()
}
弹出窗口
抑制弹出窗口
6.x
browser.setPopupHandler(new PopupHandler() {
@Override
public PopupContainer handlePopup(PopupParams params) {
return null;
}
});
browser.setPopupHandler(object: PopupHandler {
override fun handlePopup(params: PopupParams): PopupContainer? {
return null
}
})
7.0
browser.set(CreatePopupCallback.class, (params) -> Response.suppress());
browser.set(CreatePopupCallback::class.java, CreatePopupCallback { Response.suppress() })
打开弹出窗口
6.x
browser.setPopupHandler(new PopupHandler() {
@Override
public PopupContainer handlePopup(PopupParams params) {
return new PopupContainer() {
@Override
public void insertBrowser(Browser popupBrowser, Rectangle initialBounds) {}
};
}
});
browser.setPopupHandler(object: PopupHandler {
override fun handlePopup(params: PopupParams): PopupContainer {
return object: PopupContainer {
override fun insertBrowser(popupBrowser: Browser, initialBounds: Rectangle) {}
}
}
})
7.0
browser.set(CreatePopupCallback.class, (params) -> Response.create());
browser.set(OpenPopupCallback.class, (params) -> {
Browser popup = params.popupBrowser();
return OpenPopupCallback.Response.proceed();
});
browser.set(CreatePopupCallback::class.java, CreatePopupCallback { Response.create() })
browser.set(OpenPopupCallback::class.java, OpenPopupCallback { params ->
val popup = params.popupBrowser()
OpenPopupCallback.Response.proceed()
})
对话框
JavaScript 对话框
6.x
browser.setDialogHandler(new DialogHandler() {
@Override
public void onAlert(DialogParams params) {
}
@Override
public CloseStatus onConfirmation(DialogParams params) {
return CloseStatus.CANCEL;
}
@Override
public CloseStatus onPrompt(PromptDialogParams params) {
params.setPromptText("Text");
return CloseStatus.OK;
}
...
});
browser.setDialogHandler(object: DialogHandler {
override fun onAlert(params: DialogParams) {}
override fun onConfirmation(params: DialogParams): CloseStatus =
CloseStatus.CANCEL
override fun onPrompt(params: PromptDialogParams): CloseStatus {
params.setPromptText("Text")
return CloseStatus.OK
}
})
7.0
browser.set(AlertCallback.class, (params, tell) -> tell.ok());
browser.set(ConfirmCallback.class, (params, tell) -> tell.cancel());
browser.set(PromptCallback.class, (params, tell) -> tell.ok("Text"));
browser.set(AlertCallback::class.java, AlertCallback { params, tell -> tell.ok() })
browser.set(ConfirmCallback::class.java, ConfirmCallback { params, tell -> tell.cancel() })
browser.set(PromptCallback::class.java, PromptCallback { params, tell -> tell.ok("Text") })
文件对话框
6.x
browser.setDialogHandler(new DialogHandler() {
@Override
public CloseStatus onFileChooser(FileChooserParams params) {
FileChooserMode mode = params.getMode();
if (mode == FileChooserMode.Open) {
params.setSelectedFiles(new File(params.getDefaultFileName()));
}
if (mode == FileChooserMode.OpenMultiple) {
params.setSelectedFiles(new File("file1.txt"), new File("file2.txt"));
}
return CloseStatus.OK;
}
...
});
browser.setDialogHandler(object: DialogHandler {
override fun onFileChooser(params: FileChooserParams): CloseStatus {
val mode = params.mode
if (mode == FileChooserMode.Open) {
params.setSelectedFiles(File(params.defaultFileName))
}
if (mode == FileChooserMode.OpenMultiple) {
params.setSelectedFiles(File("file1.txt"), File("file2.txt"))
}
return CloseStatus.OK
}
})
7.0
browser.set(OpenFileCallback.class, (params, tell) ->
tell.open(Paths.get(params.defaultFileName())));
browser.set(OpenFilesCallback.class, (params, callback) ->
callback.open(Paths.get("file1.txt"), Paths.get("file2.txt")));
browser.set(OpenFileCallback::class.java,
OpenFileCallback { params, tell ->
tell.open(Path(params.defaultFileName()))
}
)
browser.set(OpenFilesCallback::class.java,
OpenFilesCallback { _, callback ->
callback.open(Path("file1.txt"), Path("file2.txt"))
}
)
颜色对话框
6.x
browser.setDialogHandler(new DialogHandler() {
@Override
public CloseStatus onColorChooser(ColorChooserParams params) {
params.setColor(params.getColor());
return CloseStatus.OK;
}
...
});
browser.setDialogHandler(object: DialogHandler {
override fun onColorChooser(params: ColorChooserParams): CloseStatus {
params.setColor(params.сolor)
return CloseStatus.OK
}
})
7.0
browser.set(SelectColorCallback.class, (params, tell) ->
tell.select(params.defaultColor()));
browser.set(SelectColorCallback::class.java,
SelectColorCallback { params, tell ->
tell.select(params.defaultColor())
}
)
SSL 证书对话框
6.x
browser.setDialogHandler(new DialogHandler() {
@Override
public CloseStatus onSelectCertificate(CertificatesDialogParams params) {
X509Certificate x509Certificate = ...;
PrivateKey privateKey = ...;
params.setSelectedCertificate(new Certificate(x509Certificate, privateKey));
return CloseStatus.OK;
}
...
});
browser.setDialogHandler(object: DialogHandler {
override fun onSelectCertificate(params: CertificatesDialogParams): CloseStatus {
val x509Certificate: X509Certificate = ...
val privateKey: PrivateKey = ...
params.setSelectedCertificate(Certificate(x509Certificate, privateKey))
return CloseStatus.OK
}
...
})
7.0
private static final Path CLIENT_CERT_FILE = Paths.get("<cert-file>.p12");
private static final String CLIENT_CERT_PASSWORD = "<cert-password>";
...
browser.set(SelectClientCertificateCallback.class, (params, tell) ->
tell.select(ClientCertificate.of(CLIENT_CERT_FILE,
CLIENT_CERT_PASSWORD, KeyStoreType.PKCS12)));
private val certFile = Path("<cert-file>.p12")
private val certPassword = "<cert-password>"
...
browser.set(SelectClientCertificateCallback::class.java,
SelectClientCertificateCallback { params, tell ->
tell.select(ClientCertificate.of(certFile,
certPassword, KeyStoreType.PKCS12))
}
)
上下文菜单
处理上下文菜单
6.x
browser.setContextMenuHandler(new ContextMenuHandler() {
@Override
public void showContextMenu(ContextMenuParams params) {
}
});
browser.setContextMenuHandler(object: ContextMenuHandler {
override fun showContextMenu(params: ContextMenuParams) {
}
})
7.0
browser.set(ShowContextMenuCallback.class, (params, tell) -> {
tell.close();
});
browser.set(ShowContextMenuCallback::class.java,
ShowContextMenuCallback { params, tell -> tell.close() }
)
了解更多关于上下文菜单的处理方法。
打印
配置打印
6.x
browser.setPrintHandler(new PrintHandler() {
@Override
public PrintStatus onPrint(PrintJob printJob) {
PrintSettings printSettings = printJob.getPrintSettings();
printSettings.setPrinterName("Microsoft XPS Document Writer");
printSettings.setLandscape(true);
printSettings.setPrintBackgrounds(true);
...
return PrintStatus.CONTINUE;
}
});
browser.setPrintHandler(object: PrintHandler {
override fun onPrint(printJob: PrintJob): PrintStatus {
val printSettings = printJob.printSettings
printSettings.setPrinterName("Microsoft XPS Document Writer")
printSettings.setLandscape(true)
printSettings.setPrintBackgrounds(true)
...
return PrintStatus.CONTINUE
}
})
7.0
配置打印的功能已被移除。取而代之的是,现在可以使用标准的 Print Preview(打印预览)对话框,您可以在其中提供所需的设置:
browser.set(PrintCallback.class, (params, tell) -> tell.showPrintPreview());
browser.set(PrintCallback::class.java,
PrintCallback { params, tell -> tell.showPrintPreview() }
)
抑制打印
6.x
browser.setPrintHandler(new PrintHandler() {
@Override
public PrintStatus onPrint(PrintJob printJob) {
return PrintStatus.CANCEL;
}
});
browser.setPrintHandler(object: PrintHandler {
override fun onPrint(printJob: PrintJob): PrintStatus =
PrintStatus.CANCEL
})
7.0
browser.set(PrintCallback.class, (params, tell) -> tell.cancel());
browser.set(PrintCallback::class.java,
PrintCallback { params, tell -> tell.cancel() }
)
缓存
清除 HTTP 缓存
6.x
browser.getCacheStorage().clearCache(new Callback() {
@Override
public void invoke() {
// HTTP 磁盘缓存已清除。
}
});
browser.cacheStorage.clearCache(object: Callback {
override fun invoke() {
// HTTP 磁盘缓存已清除。
}
})
7.0
engine.httpCache().clearDiskCache(() -> {
// HTTP 磁盘缓存已清除。
});
engine.httpCache().clearDiskCache {
// HTTP 磁盘缓存已清除。
}
Cookies
访问 cookies
6.x
List<Cookie> cookies = browser.getCookieStorage().getAllCookies();
val cookies = browser.cookieStorage.allCookies
7.0
List<Cookie> cookies = engine.cookieStore().cookies();
val cookies = engine.cookieStore().cookies()
渲染进程
启动/终止
6.x
browser.addRenderListener(new RenderAdapter() {
@Override
public void onRenderCreated(RenderEvent event) {}
@Override
public void onRenderGone(RenderEvent event) {
TerminationStatus status = event.getTerminationStatus();
}
});
browser.addRenderListener(object: RenderAdapter {
override fun onRenderCreated(event: RenderEvent) {}
override fun onRenderGone(event: RenderEvent) {
val status: TerminationStatus = event.terminationStatus
}
})
7.0
browser.on(RenderProcessStarted.class, event -> {});
browser.on(RenderProcessTerminated.class, event -> {
TerminationStatus status = event.status();
});
browser.on(RenderProcessStarted::class.java) { event -> }
browser.on(RenderProcessTerminated::class.java) { event ->
val status = event.status()
}
Chromium
Switches(开关)
该库并不支持所有可能的 Chromium 开关。它允许使用开关来配置 Chromium,但我们不能保证传递的开关能够正确工作或者能够工作。因此,我们建议在使用前检查此功能。
6.x
BrowserPreferences.setChromiumSwitches(
"--<switch_name>",
"--<switch_name>=<switch_value>"
);
BrowserPreferences.setChromiumSwitches(
"--<switch_name>",
"--<switch_name>=<switch_value>"
)
7.0
Engine engine = Engine.newInstance(EngineOptions.newBuilder(...)
.addSwitch("--<switch_name>")
.addSwitch("--<switch_name>=<switch_value>")
.build());
val engine = Engine.newInstance(EngineOptions.newBuilder(...)
.addSwitch("--<switch_name>")
.addSwitch("--<switch_name>=<switch_value>")
.build())
API 密钥
6.x
BrowserPreferences.setChromiumVariable(
"GOOGLE_API_KEY", "我的 API 密钥");
BrowserPreferences.setChromiumVariable(
"GOOGLE_DEFAULT_CLIENT_ID", "我的客户端 ID");
BrowserPreferences.setChromiumVariable(
"GOOGLE_DEFAULT_CLIENT_SECRET", "我的客户端密钥");
BrowserPreferences.setChromiumVariable(
"GOOGLE_API_KEY", "我的 API 密钥")
BrowserPreferences.setChromiumVariable(
"GOOGLE_DEFAULT_CLIENT_ID", "我的客户端 ID")
BrowserPreferences.setChromiumVariable(
"GOOGLE_DEFAULT_CLIENT_SECRET", "我的客户端密钥")
7.0
Engine engine = Engine.newInstance(EngineOptions.newBuilder(...)
.googleApiKey("我的 API 密钥")
.googleDefaultClientId("我的客户端 ID")
.googleDefaultClientSecret("我的客户端密钥")
.build());
val engine = Engine.newInstance(EngineOptions.newBuilder(...)
.googleApiKey("我的 API 密钥")
.googleDefaultClientId("我的客户端 ID")
.googleDefaultClientSecret("我的客户端密钥")
.build())
日志记录
在新版本中,日志记录 API 已经简化。请查阅故障排除指南,了解更多关于如何配置日志记录的信息。