List icon 目录

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
    }
}

此示例的输出如下所示: AWT/Swing BrowserView

另请参阅我们的视频教程,其中展示了如何将 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() }
    }
}

此示例的输出如下所示: JavaFX BrowserView

另请参阅我们的视频教程,其中展示了如何将 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 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)
}

运行此示例后,您应该获得以下输出:

FXML Example Output

您可以在 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()
}

此示例的输出如下所示: SWT BrowserView

另请参阅我们的视频教程,其中展示了如何将 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

Windows Off-Screen

macOS

  • MacBook Pro 15”, Intel Core i7 2.9GHz 与 GPU Radeon Pro 650 4GB
  • 视频尺寸:2880x1800

macOS Off-Screen

Linux

  • AMD FX-8300 3.3 GHz 与 GPU Radeon RX 480
  • 视频尺寸:1920x1080

Linux Off-Screen

限制

嵌入和渲染

请不要在启用 HARDWARE_ACCELERATED 渲染模式时将 Swing 的 BrowserView 嵌入到 JInternalFrameJLayeredPane 中,也不要在 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_ACCELERATEDOFF_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 系统属性。支持的值有 quarterexact

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
Go Top