BrowserView
该文档描述了如何在 Swing、JavaFX 和 SWT 应用程序中嵌入显示网页内容的可视化组件。
嵌入
JxBrowser 可用于使用以下 Java GUI 框架构建的 Java 应用程序:
- Swing
- JavaFX
- SWT
该 Browser
组件本身不是一个允许显示网页的可视化组件。要显示在 Browser
中加载的网页内容,请根据您使用的 GUI 框架,使用以下控件之一:
com.teamdev.jxbrowser.view.swing.BrowserView
com.teamdev.jxbrowser.view.javafx.BrowserView
com.teamdev.jxbrowser.view.swt.BrowserView
Swing
要在 Java Swing 应用程序中显示网页内容,请创建一个 com.teamdev.jxbrowser.view.swing.BrowserView
的实例:
import com.teamdev.jxbrowser.view.swing.BrowserView;
...
BrowserView view = BrowserView.newInstance(browser);
import com.teamdev.jxbrowser.view.swing.BrowserView
...
val view = BrowserView.newInstance(browser)
并将其嵌入到 JFrame
中:
frame.add(view, BorderLayout.CENTER);
frame.add(view, BorderLayout.CENTER)
这是完整的示例:
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;
/**
* 带有集成 Browser 组件的最简单应用程序。
*
* <p>此示例演示了:
*
* <ol>
* <li>创建一个 {@link Engine} 实例。
* <li>创建一个 {@link Browser} 实例。
* <li>通过 {@link BrowserView} 将 Browser 嵌入到 Swing 中。
* <li>加载 "https://html5test.teamdev.com" 网站。
* </ol>
*/
public final class HelloWorld {
public static void main(String[] args) {
// 创建和运行 Chromium Engine
Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();
// 加载所需的网页
browser.navigation().loadUrl("https://html5test.teamdev.com");
SwingUtilities.invokeLater(() -> {
// 创建一个 Swing 组件
// 用于渲染在给定 Browser 实例中加载的网页内容
BrowserView view = BrowserView.newInstance(browser);
// 创建并显示 Swing 应用程序 Frame
JFrame frame = new JFrame("JxBrowser AWT/Swing");
// 在应用程序 Frame 即将关闭时关闭 Engine
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
engine.close();
}
});
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.add(view, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setVisible(true);
});
}
}
import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.engine.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import com.teamdev.jxbrowser.view.swing.BrowserView
import java.awt.BorderLayout
import java.awt.event.WindowAdapter
import java.awt.event.WindowEvent
import javax.swing.JFrame
import javax.swing.SwingUtilities
import javax.swing.WindowConstants
/**
* 带有集成 Browser 组件的最简单应用程序。
*
* 此示例演示了:
*
* 1. 创建一个 [Engine] 实例。
* 2. 创建一个 [Browser] 实例。
* 3. 通过 [BrowserView] 将 Browser 嵌入到 Swing 中。
* 4. 加载 "https://html5test.teamdev.com" 网站。
*/
fun main() {
// 创建和运行 Chromium Engine
val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
val browser = engine.newBrowser()
// 加载所需的网页
browser.navigation().loadUrl("https://html5test.teamdev.com")
SwingUtilities.invokeLater {
// 创建一个 Swing 组件
// 用于渲染在给定 Browser 实例中加载的网页内容
val view = BrowserView.newInstance(browser)
// 创建并显示 Swing 应用程序 Frame
val frame = JFrame("JxBrowser AWT/Swing")
// 在应用程序 Frame 即将关闭时关闭 Engine
frame.addWindowListener(object: WindowAdapter() {
override fun windowClosing(e: WindowEvent) {
engine.close()
}
})
frame.defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE
frame.add(view, BorderLayout.CENTER)
frame.setSize(800, 600)
frame.isVisible = true
}
}
此示例的输出如下所示:
另请参阅我们的视频教程,其中展示了如何将 BrowserView
添加到 Java Swing 应用程序:
JavaFX
要在 JavaFX 应用程序中显示网页内容,请创建一个 com.teamdev.jxbrowser.view.javafx.BrowserView
的实例:
import com.teamdev.jxbrowser.view.javafx.BrowserView;
...
BrowserView view = BrowserView.newInstance(browser);
import com.teamdev.jxbrowser.view.javafx.BrowserView
...
val view = BrowserView.newInstance(browser)
并将其嵌入到 Scene
中:
Scene scene = new Scene(new BorderPane(view), 800, 600);
frame.add(view, BorderLayout.CENTER)
这是完整的示例:
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.view.javafx.BrowserView;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;
/**
* 带有集成 Browser 组件的最简单应用程序。
*
* <p>此示例演示了:
*
* <ol>
* <li>创建一个 {@link Engine} 实例。
* <li>创建一个 {@link Browser} 实例。
* <li>通过 {@link BrowserView} 将 Browser 嵌入到 JavaFX 中。
* <li>加载 "https://html5test.teamdev.com" 网站。
* </ol>
*/
public final class HelloWorld extends Application {
@Override
public void start(Stage primaryStage) {
// 创建和运行 Chromium Engine
Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();
// 加载所需的网页
browser.navigation().loadUrl("https://html5test.teamdev.com");
// 创建一个 UI 组件
// 用于渲染给定 Browser 实例中加载的网页内容
BrowserView view = BrowserView.newInstance(browser);
Scene scene = new Scene(new BorderPane(view), 800, 600);
primaryStage.setTitle("JxBrowser JavaFX");
primaryStage.setScene(scene);
primaryStage.show();
// 当 stage 即将关闭时关闭 Engine
primaryStage.setOnCloseRequest(event -> engine.close());
}
}
import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.engine.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import com.teamdev.jxbrowser.view.javafx.BrowserView
import javafx.application.Application
import javafx.event.EventHandler
import javafx.scene.Scene
import javafx.scene.layout.BorderPane
import javafx.stage.Stage
import javafx.stage.WindowEvent
/**
* 带有集成 Browser 组件的最简单应用程序。
*
* 此示例演示了:
*
* 1. 创建一个 [Engine] 实例。
* 2. 创建一个 [Browser] 实例。
* 3. 通过 [BrowserView] 将 Browser 嵌入到 JavaFX 中。
* 4. 加载 "https://html5test.teamdev.com" 网站。
*/
class HelloWorld : Application() {
override fun start(primaryStage: Stage) {
// 创建和运行 Chromium Engine
val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
val browser = engine.newBrowser()
// 加载所需的网页
browser.navigation().loadUrl("https://html5test.teamdev.com")
// 创建一个 UI 组件
// 用于渲染给定 Browser 实例中加载的网页内容
val view = BrowserView.newInstance(browser)
val scene = Scene(BorderPane(view), 800.0, 600.0)
primaryStage.title = "JxBrowser JavaFX"
primaryStage.scene = scene
primaryStage.show()
// 当 stage 即将关闭时关闭 Engine
primaryStage.onCloseRequest = EventHandler { engine.close() }
}
}
此示例的输出如下所示:
另请参阅我们的视频教程,其中展示了如何将 BrowserView
添加到 JavaFX 应用程序:
JFXPanel
我们建议您在 Swing 应用程序中使用 Swing BrowserView
,在 JavaFX 应用程序中使用 JavaFX BrowserView
。
有时您可能需要将 JavaFX BrowserView
嵌入到 Swing 应用程序中。例如,如果您使用 JavaFX UI Toolkit 开发一个复杂的网页浏览器控件,并且您必须在 Swing/AWT 应用程序中显示此 JavaFX 控件。
从 7.1 版本开始,您可以通过 javafx.embed.swing.JFXPanel
将 JavaFX BrowserView
嵌入到 Swing/AWT 窗口中。它支持所有受支持的平台和所有渲染模式。
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.view.javafx.BrowserView;
import java.awt.BorderLayout;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/**
* 这个示例演示了如何将 JavaFX 的 BrowserView 嵌入到
* 显示在 Swing/AWT Frame 内的 JFXPanel 中。
*/
public final class JFXPanelExample {
public static void main(final String[] args) {
SwingUtilities.invokeLater(JFXPanelExample::initAndShowGUI);
}
private static void initAndShowGUI() {
JFrame frame = new JFrame("JFXPanel");
// 将 JFXPanel 嵌入到 Swing Frame 中
JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel, BorderLayout.CENTER);
frame.setSize(600, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 在 JavaFX UI 线程中初始化 JFXPanel
Platform.runLater(() -> initFX(fxPanel));
}
private static void initFX(JFXPanel fxPanel) {
Engine engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();
browser.navigation().loadUrl("https://www.google.com");
// 创建 JavaFX BrowserView 并将其插入到 JFXPanel 中
BrowserView view = BrowserView.newInstance(browser);
BorderPane pane = new BorderPane(view);
fxPanel.setScene(new Scene(pane, 600, 600));
}
}
import com.teamdev.jxbrowser.engine.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import com.teamdev.jxbrowser.view.javafx.BrowserView
import javafx.application.Platform
import javafx.embed.swing.JFXPanel
import javafx.scene.Scene
import javafx.scene.layout.BorderPane
import java.awt.BorderLayout
import javax.swing.JFrame
import javax.swing.SwingUtilities
/**
* 这个示例演示了如何将 JavaFX 的 BrowserView 嵌入到
* 显示在 Swing/AWT Frame 内的 JFXPanel 中。
*/
fun main() {
SwingUtilities.invokeLater { initAndShowGUI() }
}
private fun initAndShowGUI() {
val frame = JFrame("JFXPanel")
// 将 JFXPanel 嵌入到 Swing Frame 中
val fxPanel = JFXPanel()
frame.add(fxPanel, BorderLayout.CENTER)
frame.setSize(600, 600)
frame.isVisible = true
frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
// 在 JavaFX UI 线程中初始化 JFXPanel
Platform.runLater { initFX(fxPanel) }
}
private fun initFX(fxPanel: JFXPanel) {
val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
val browser = engine.newBrowser()
browser.navigation().loadUrl("https://www.google.com")
// 创建 JavaFX BrowserView 并将其插入到 JFXPanel 中
val view = BrowserView.newInstance(browser)
val pane = BorderPane(view)
fxPanel.scene = Scene(pane, 600.0, 600.0)
}
FXML
您可以使用下面这一节中描述的方法将 JavaFX BrowserView
嵌入到 FXML 应用程序中。
首先,请描述 browser-view.fxml
文件的结构,以告诉 JavaFX BrowserView
控件应该如何嵌入到 JavaFX 应用程序 GUI 中。
<?xml version="1.0" encoding="UTF-8"?>
<?import com.teamdev.jxbrowser.view.javafx.FxmlBrowserView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane
fx:controller="com.teamdev.jxbrowser.view.javafx.FxmlBrowserViewController"
xmlns:fx="http://javafx.com/fxml">
<top>
<TextField fx:id="textField" text="https://www.google.com"
onAction="#loadUrl"/>
</top>
<center>
<FxmlBrowserView fx:id="browserView"/>
</center>
</BorderPane>
此 FXML 声明了一个由两个元素组成的组件:地址栏和 Browser View。地址栏代表一个简单的文本字段。在这里,我们可以键入一个 URL,然后按 Enter
Browser 键在下面的 Browser View 中加载它。Browser View 包含显示加载网页内容的 FxmlBrowserView
。
在 browser-view.fxml
文件中定义的 FxmlBrowserViewController
的实现如下所示:
package com.teamdev.jxbrowser.view.javafx;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import java.net.URL;
import java.util.ResourceBundle;
/**
* 代表带有地址栏和 Browser View 区域的 FXML 控制器
* 用于显示在地址栏中输入的 URL。
*/
public final class FxmlBrowserViewController implements Initializable {
@FXML
private TextField textField;
@FXML
private FxmlBrowserView browserView;
@Override
public void initialize(URL location, ResourceBundle resources) {
browserView.browser().navigation().loadUrl(textField.getText());
}
public void loadUrl(ActionEvent actionEvent) {
browserView.browser().navigation().loadUrl(textField.getText());
}
}
package com.teamdev.jxbrowser.view.javafx
import javafx.event.ActionEvent
import javafx.fxml.FXML
import javafx.fxml.Initializable
import javafx.scene.control.TextField
import java.net.URL
import java.util.*
/**
* 代表带有地址栏和 Browser View 区域的 FXML 控制器
* 用于显示在地址栏中输入的 URL。
*/
class FxmlBrowserViewController : Initializable {
@FXML
private val textField: TextField? = null
@FXML
private val browserView: FxmlBrowserView? = null
override fun initialize(location: URL, resources: ResourceBundle) {
browserView.browser().navigation().loadUrl(textField!!.text)
}
fun loadUrl(actionEvent: ActionEvent?) {
browserView.browser().navigation().loadUrl(textField!!.text)
}
}
您可能会注意到,控制器实现中使用了 FxmlBrowserView
而不是 JavaFX BrowserView
。这是因为 JavaFX 的 BrowserView
没有提供默认的公共构造函数,因此无法直接在 FXML 中使用。要嵌入 JavaFX 的 BrowserView
,请使用 FxmlBrowserView
,它代表了一个简单的包装器,具有初始化和嵌入 JavaFX BrowserView
的默认公共构造函数。
FxmlBrowserView
类的实现如下所示:
package com.teamdev.jxbrowser.view.javafx;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.view.javafx.BrowserView;
import javafx.scene.layout.StackPane;
/**
* 一个用于 JavaFX {@link BrowserView} 的包装组件,
* 允许在 FXML 应用程序中使用 BrowserView 实例。
* 由于 JavaFX 的 BrowserView 没有提供默认的公共构造函数,
* 因此它不能直接用于 FXML 中。
*/
public final class FxmlBrowserView extends StackPane {
private final Browser browser;
/**
* 构造一个 {@code FxmlBrowserView} 的实例。
*/
public FxmlBrowserView() {
Engine engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED);
browser = engine.newBrowser();
BrowserView view = BrowserView.newInstance(browser);
getChildren().add(view);
}
/**
* 返回当前 Browser View 的 {@link Browser} 实例。
*/
public Browser browser() {
return browser;
}
}
package com.teamdev.jxbrowser.view.javafx
import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.engine.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import javafx.scene.layout.StackPane
/**
* 一个用于 JavaFX [BrowserView] 的包装组件,
* 允许在 FXML 应用程序中使用 BrowserView 实例。
* 由于 JavaFX 的 BrowserView 没有提供默认的公共构造函数,
* 因此它不能直接用于 FXML 中。
*/
class FxmlBrowserView : StackPane() {
private val browser: Browser
/**
* 构造一个 `FxmlBrowserView` 的实例。
*/
init {
val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
browser = engine.newBrowser()
val view = BrowserView.newInstance(browser)
children.add(view)
}
/**
* 返回当前 Browser View 的 [Browser] 实例。
*/
fun browser() = browser
}
现在,我们已经具备了实施和运行 FXML 示例的一切条件:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
/**
* 这个示例演示了如何通过 {@link com.teamdev.jxbrowser.view.javafx.FxmlBrowserView} 控件
* 在 FXML 应用程序中使用 JavaFX 的 BrowserView。
*/
public final class BrowserViewInFxml extends Application {
public static void main(String[] args) {
Application.launch(BrowserViewInFxml.class, args);
}
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane pane = FXMLLoader.load(
BrowserViewInFxml.class.getResource("browser-view.fxml"));
primaryStage.setTitle("JavaFX BrowserView in FXML");
primaryStage.setScene(new Scene(pane, 1024, 600));
primaryStage.show();
}
}
import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Scene
import javafx.scene.layout.BorderPane
import javafx.stage.Stage
/**
* 这个示例演示了如何通过 [com.teamdev.jxbrowser.view.javafx.FxmlBrowserView] 控件
* 在 FXML 应用程序中使用 JavaFX 的 BrowserView。
*/
class BrowserViewInFxml : Application() {
override fun start(primaryStage: Stage) {
val pane = FXMLLoader.load<BorderPane>(
BrowserViewInFxml::class.java.getResource("browser-view.fxml")
)
primaryStage.title = "JavaFX BrowserView in FXML"
primaryStage.scene = Scene(pane, 1024.0, 600.0)
primaryStage.show()
}
}
fun main(args: Array<String>) {
Application.launch(BrowserViewInFxml::class.java, *args)
}
运行此示例后,您应该获得以下输出:
您可以在 JxBrowser 示例中找到包含本节中使用的所有类和资源的完整示例。
SWT
要在 Java SWT 应用程序中显示网页内容,请创建一个com.teamdev.jxbrowser.view.swt.BrowserView
的实例:
import com.teamdev.jxbrowser.view.swt.BrowserView;
...
Display display = new Display();
Shell shell = new Shell(display);
BrowserView view = BrowserView.newInstance(shell, browser);
import com.teamdev.jxbrowser.view.swt.BrowserView
...
val display = Display()
val shell = Shell(display)
val view = BrowserView.newInstance(shell, browser)
这是完整的示例:
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.view.swt.BrowserView;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;
/**
* 带有集成 Browser 组件的最简单应用程序。
*
* <p>此示例演示了:
*
* <ol>
* <li>创建一个 {@link Engine} 实例。
* <li>创建一个 {@link Browser} 实例。
* <li>通过 {@link BrowserView} 将 Browser 嵌入到 SWT 中。
* <li>加载 "https://html5test.teamdev.com" 网站。
* </ol>
*/
public final class HelloWorld {
public static void main(String[] args) {
// 创建和运行 Chromium Engine
Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();
// 加载所需的网页
browser.navigation().loadUrl("https://html5test.teamdev.com");
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("JxBrowser SWT");
shell.setLayout(new FillLayout());
// 创建一个 SWT 组件
// 用于渲染加载在 Browser 实例中的网页内容
BrowserView view = BrowserView.newInstance(shell, browser);
view.setSize(800, 600);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
// 关闭 Engine 并释放所有已分配的资源
engine.close();
display.dispose();
}
}
import com.teamdev.jxbrowser.engine.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import com.teamdev.jxbrowser.view.swt.BrowserView
import org.eclipse.swt.layout.FillLayout
import org.eclipse.swt.widgets.Display
import org.eclipse.swt.widgets.Shell
/**
* 带有集成 Browser 组件的最简单应用程序。
*
* 此示例演示了:
*
* 1. 创建一个 [Engine] 实例。
* 2. 创建一个 [Browser] 实例。
* 3. 通过 [BrowserView] 将 Browser 嵌入到 SWT 中。
* 4. 加载 "https://html5test.teamdev.com" 网站。
*/
fun main() {
// 创建和运行 Chromium Engine
val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
val browser = engine.newBrowser()
// 加载所需的网页
browser.navigation().loadUrl("https://html5test.teamdev.com")
val display = Display()
val shell = Shell(display)
shell.setText("JxBrowser SWT")
shell.setLayout(FillLayout())
// 创建一个 SWT 组件
// 用于渲染加载在 Browser 实例中的网页内容
val view = BrowserView.newInstance(shell, browser)
view.setSize(800, 600)
shell.pack()
shell.open()
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep()
}
}
// 关闭 Engine 并释放所有已分配的资源
engine.close()
display.dispose()
}
此示例的输出如下所示:
另请参阅我们的视频教程,其中展示了如何将 BrowserView
添加到 Java SWT 应用程序:
渲染
JxBrowser 支持多种渲染模式。在本节中,我们将描述每种模式及其性能及其限制,并根据 Java 应用程序的类型,为您提供选择正确模式的建议。
硬件加速
在这种渲染模式下,库使用 GPU 在 Chromium GPU 进程中渲染网页内容,并将其直接显示在表面上。在这种模式下,BrowserView
创建并嵌入了一个原生重量级窗口(表面),Chromium 在其上呈现生成的像素。
离屏
在这种渲染模式下,库使用 GPU 在 Chromium GPU 进程中渲染网页内容,并将像素复制到 Java 进程内存中分配的离屏缓冲区。在这种模式下,BrowserView
创建并嵌入一个轻量级组件,该组件从离屏缓冲区读取像素并使用标准 Java 图形 API 显示它们。
性能
在硬件加速渲染模式下,性能与 Chromium 应用程序相同,因为 Chromium 直接在嵌入 BrowserView
组件中的原生窗口上渲染像素。在此渲染模式下,HTML5 视频的平均渲染性能 (以每秒帧数 (FPS) 表示) 约为 60FPS。
在离屏渲染模式下,每种 UI 工具包和操作系统的性能都不同。HTML5 视频在 FPS 渲染性能测试结果如下:
Windows
- Intel Core i7 7700k 4.2 GHz 与 GPU GTX 1070
- 视频尺寸:1920x1080
macOS
- MacBook Pro 15”, Intel Core i7 2.9GHz 与 GPU Radeon Pro 650 4GB
- 视频尺寸:2880x1800
Linux
- AMD FX-8300 3.3 GHz 与 GPU Radeon RX 480
- 视频尺寸:1920x1080
限制
嵌入和渲染
请不要在启用 HARDWARE_ACCELERATED
渲染模式时将 Swing 的 BrowserView
嵌入到 JInternalFrame
或 JLayeredPane
中,也不要在 BrowserView
上显示其他 Swing 组件。在这种模式下,BrowserView
会显示一个原生的重量级窗口。在轻量级 GUI 中显示重量级窗口会导致一个众所周知的问题,即混合使用重量级和轻量级组件。
根据文章所述,混合重量级和轻量级组件的问题已在 JDK 6 Update 12 和 JDK 7 build 19 中修复。但这仅适用于 Java Swing 重量级组件,如 java.awt.Canvas
。JxBrowser 嵌入了它自己的重量级原生小部件。因此,在这种情况下,该修复不会生效。
在 JavaFX 应用程序中,使用 StageStyle.TRANSPARENT
样式配置 javafx.stage.Stage
会在 Windows 上为 JavaFX 窗口添加 WS_EX_LAYERED
窗口样式标志。此标志用于创建分层窗口。分层窗口是一种在离屏缓冲区中绘制其内容的窗口。如果在启用 HARDWARE_ACCELERATED
渲染模式时,将 JavaFX 的 BrowserView
嵌入到分层窗口中,由于窗口类型的冲突,其内容将不会被绘制。
在 macOS 上的 Eclipse RCP 应用程序中,当启用了 HARDWARE_ACCELERATED
渲染模式时,SWT 小部件可能无法显示在 SWT 的 BrowserView
小部件之上,因为 SWT 的 BrowserView
小部件使用 Layer-Backed NSView
来渲染内容,而其他 SWT 小部件则使用常规的 NSView
来绘制其内容。问题在于,常规 NSView
的内容无法覆盖 Layer-Backed NSView
的内容。这是因为渲染发生在不同的绘图上下文中,常规的 NSView
的内容总是会显示在 Layer-Backed NSView
之下。
鼠标、键盘和触摸输入
在 Windows 和 Linux 上的 OFF_SCREEN
渲染模式下,以及 macOS 上的 HARDWARE_ACCELERATED
和 OFF_SCREEN
渲染模式下,鼠标、键盘和触摸事件在 Java 端处理并转发给 Chromium。Java Swing、JavaFX 和 SWT UI 工具包不提供完全功能的触摸事件支持,因此在这些渲染模式下,JxBrowser 不支持某些触摸手势。
相同的限制适用于拖放 (DnD) 功能。DnD 是使用 Java DnD API 处理的,因此它的工作方式与 Google Chrome 不完全相同。DnD 仅支持预定义的一组格式。
拖放
默认情况下,Swing、JavaFX 和 SWT 的 BrowserView
启用拖放功能。要禁用拖放功能,请使用以下方式:
browserView.dragAndDrop().disable();
browserView.dragAndDrop().disable()
HiDPI
本节介绍 JxBrowser 在具有 HiDPI 显示器的环境中的功能和限制。
macOS
在 macOS 上,JxBrowser 在 Swing、JavaFX 和 SWT 中默认支持 HiDPI 和 Retina 显示。
Windows
在 Windows 上,JxBrowser 在 Swing 和 JavaFX 中默认支持 HiDPI 显示。
SWT
该库仅识别主显示器的缩放因子。缩放因子必须是 25% 的倍数。如果您需要 HiDPI 支持,则必须使用 swt.autoScale
系统属性。支持的值有 quarter
和 exact
:
java -Dswt.autoScale=quarter -jar application.jar
在 Eclipse 4.6 及更高版本中,swt.autoScale
属性始终设置为 quarter
。
您可以在此处阅读有关 swt.autoScale
的更多信息。
Linux
在 Linux 上,启动 JVM 时需要明确配置缩放因子。它会自动检测。
Swing
要在 Swing 应用程序中配置缩放因子,请使用 sun.java2d.uiScale
系统属性。它只接受整数值。
java -Dsun.java2d.uiScale=2 -jar application.jar
JavaFX
要在 JavaFX 应用程序中配置缩放因子,请使用 glass.gtk.uiScale
系统属性。它只接受整数值。
java -Dglass.gtk.uiScale=2 -jar application.jar