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;

/**
 * The simplest application with the integrated browser component.
 *
 * <p>This example demonstrates:
 *
 * <ol>
 *     <li>Creating an instance of {@link Engine}.
 *     <li>Creating an instance of {@link Browser}.
 *     <li>Embedding the browser into Swing via {@link BrowserView}.
 *     <li>Loading the "https://html5test.teamdev.com" web site.
 * </ol>
 */
public final class HelloWorld {
    public static void main(String[] args) {
        // Creating and running Chromium engine
        Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);

        Browser browser = engine.newBrowser();
        // Loading the required web page
        browser.navigation().loadUrl("https://html5test.teamdev.com");

        SwingUtilities.invokeLater(() -> {
            // Creating Swing component for rendering web content
            // loaded in the given Browser instance
            BrowserView view = BrowserView.newInstance(browser);

            // Creating and displaying Swing app frame
            JFrame frame = new JFrame("JxBrowser AWT/Swing");
            // Closing the engine when app frame is about to close
            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

/**
 * The simplest application with the integrated browser component.
 *
 * This example demonstrates:
 *
 *  1. Creating an instance of [Engine].
 *  2. Creating an instance of [Browser].
 *  3. Embedding the browser into Swing via [BrowserView].
 *  4. Loading the "https://html5test.teamdev.com" web site.
 */
fun main() {
    // Creating and running Chromium engine
    val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
    val browser = engine.newBrowser()
    // Loading the required web page
    browser.navigation().loadUrl("https://html5test.teamdev.com")
    SwingUtilities.invokeLater {
        // Creating Swing component for rendering web content
        // loaded in the given Browser instance
        val view = BrowserView.newInstance(browser)

        // Creating and displaying Swing app frame
        val frame = JFrame("JxBrowser AWT/Swing")
        // Closing the engine when app frame is about to close
        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;

/**
 * The simplest application with the integrated browser component.
 *
 * <p>This example demonstrates:
 *
 * <ol>
 *     <li>Creating an instance of {@link Engine}.
 *     <li>Creating an instance of {@link Browser}.
 *     <li>Embedding the browser into JavaFX via {@link BrowserView}.
 *     <li>Loading the "https://html5test.teamdev.com" web site.
 * </ol>
 */
public final class HelloWorld extends Application {

    @Override
    public void start(Stage primaryStage) {
        // Creating and running Chromium engine
        Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);

        Browser browser = engine.newBrowser();
        // Loading the required web page
        browser.navigation().loadUrl("https://html5test.teamdev.com");

        // Creating UI component for rendering web content
        // loaded in the given Browser instance
        BrowserView view = BrowserView.newInstance(browser);

        Scene scene = new Scene(new BorderPane(view), 800, 600);
        primaryStage.setTitle("JxBrowser JavaFX");
        primaryStage.setScene(scene);
        primaryStage.show();

        // Closing the engine when stage is about to close
        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

/**
 * The simplest application with the integrated browser component.
 *
 * This example demonstrates:
 *
 *  1. Creating an instance of [Engine].
 *  2. Creating an instance of [Browser].
 *  3. Embedding the browser into JavaFX via [BrowserView].
 *  4. Loading the "https://html5test.teamdev.com" web site.
 */
class HelloWorld : Application() {
    override fun start(primaryStage: Stage) {
        // Creating and running Chromium engine
        val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
        val browser = engine.newBrowser()
        // Loading the required web page
        browser.navigation().loadUrl("https://html5test.teamdev.com")

        // Creating UI component for rendering web content
        // loaded in the given Browser instance
        val view = BrowserView.newInstance(browser)
        val scene = Scene(BorderPane(view), 800.0, 600.0)
        primaryStage.title = "JxBrowser JavaFX"
        primaryStage.scene = scene
        primaryStage.show()

        // Closing the engine when stage is about to close
        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;

/**
 * The example demonstrates how to embed JavaFX BrowserView into 
 * JFXPanel that is displayed inside Swing/AWT Frame.
 */
public final class JFXPanelExample {

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(JFXPanelExample::initAndShowGUI);
    }

    private static void initAndShowGUI() {
        JFrame frame = new JFrame("JFXPanel");

        // Embedding JFXPanel into Swing Frame
        JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel, BorderLayout.CENTER);
        frame.setSize(600, 600);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Initializing JFXPanel in JavaFX UI Thread
        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");
        // Creating JavaFX BrowserView and inserting it into 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

/**
 * The example demonstrates how to embed JavaFX BrowserView into
 * JFXPanel that is displayed inside Swing/AWT Frame.
 */
fun main() {
    SwingUtilities.invokeLater { initAndShowGUI() }
}

private fun initAndShowGUI() {
    val frame = JFrame("JFXPanel")

    // Embedding JFXPanel into Swing Frame
    val fxPanel = JFXPanel()
    frame.add(fxPanel, BorderLayout.CENTER)
    frame.setSize(600, 600)
    frame.isVisible = true
    frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE

    // Initializing JFXPanel in JavaFX UI Thread
    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")
    // Creating JavaFX BrowserView and inserting it into 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 声明了一个由两个元素组成的组件:地址栏和浏览器视图。 地址栏代表一个简单的文本字段。 在这里,我们可以键入一个 URL,然后按 Enter 键将其加载到下面的浏览器视图中。 浏览器视图包含显示加载网页内容的 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;

/**
 * Represents FXML controller with the address bar and browser view area that
 * displays the URL entered in the address bar.
 */
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.*

/**
 * Represents FXML controller with the address bar and browser view area that
 * displays the URL entered in the address bar.
 */
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;

/**
 * A wrapper component for JavaFX {@link BrowserView} that allows using
 * the BrowserView instance in FXML applications. The JavaFX BrowserView
 * cannot be used in FXML directly, because it does not provide the default
 * public constructor.
 */
public final class FxmlBrowserView extends StackPane {

    private final Browser browser;

    /**
     * Constructs an instance of {@code FxmlBrowserView}.
     */
    public FxmlBrowserView() {
        Engine engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED);
        browser = engine.newBrowser();
        BrowserView view = BrowserView.newInstance(browser);
        getChildren().add(view);
    }

    /**
     * Returns the {@link Browser} instance of the current browser view.
     */
    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

/**
 * A wrapper component for JavaFX [BrowserView] that allows using
 * the BrowserView instance in FXML applications. The JavaFX BrowserView
 * cannot be used in FXML directly, because it does not provide the default
 * public constructor.
 */
class FxmlBrowserView : StackPane() {
    
    private val browser: Browser

    /**
     * Constructs an instance of `FxmlBrowserView`.
     */
    init {
        val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
        browser = engine.newBrowser()
        val view = BrowserView.newInstance(browser)
        children.add(view)
    }

    /**
     * Returns the [Browser] instance of the current browser view.
     */
    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;

/**
 * This example demonstrates how to use JavaFX BrowserView in FXML app
 * through the {@link com.teamdev.jxbrowser.view.javafx.FxmlBrowserView} control.
 */
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

/**
 * This example demonstrates how to use JavaFX BrowserView in FXML app
 * through the [com.teamdev.jxbrowser.view.javafx.FxmlBrowserView] control.
 */
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;

/**
 * The simplest application with the integrated browser component.
 *
 * <p>This example demonstrates:
 *
 * <ol>
 *     <li>Creating an instance of {@link Engine}.
 *     <li>Creating an instance of {@link Browser}.
 *     <li>Embedding the browser into SWT via {@link BrowserView}.
 *     <li>Loading the "https://html5test.teamdev.com" web site.
 * </ol>
 */
public final class HelloWorld {

    public static void main(String[] args) {
        // Creating and running Chromium engine
        Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);

        Browser browser = engine.newBrowser();
        // Loading the required web page
        browser.navigation().loadUrl("https://html5test.teamdev.com");

        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setText("JxBrowser SWT");
        shell.setLayout(new FillLayout());

        // Creating SWT component for rendering web content loaded
        // in the Browser instance
        BrowserView view = BrowserView.newInstance(shell, browser);
        view.setSize(800, 600);

        shell.pack();
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        // Closing the engine and releasing all allocated resources
        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

/**
 * The simplest application with the integrated browser component.
 *
 * This example demonstrates:
 *
 *  1. Creating an instance of [Engine].
 *  2. Creating an instance of [Browser].
 *  3. Embedding the browser into SWT via [BrowserView].
 *  4. Loading the "https://html5test.teamdev.com" web site.
 */
fun main() {
    // Creating and running Chromium engine
    val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
    val browser = engine.newBrowser()
    // Loading the required web page
    browser.navigation().loadUrl("https://html5test.teamdev.com")
    val display = Display()
    val shell = Shell(display)
    shell.setText("JxBrowser SWT")
    shell.setLayout(FillLayout())

    // Creating SWT component for rendering web content loaded
    // in the Browser instance
    val view = BrowserView.newInstance(shell, browser)
    view.setSize(800, 600)
    shell.pack()
    shell.open()
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep()
        }
    }
    // Closing the engine and releasing all allocated resources
    engine.close()
    display.dispose()
}

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

另请参阅我们的视频教程,其中展示了如何将 BrowserView 添加到 Java SWT 应用程序:

渲染

JxBrowser 支持多种渲染模式。 在本节中,我们将描述每种模式及其性能和局限性,并根据Java应用程序的类型,为你提供选择正确模式的建议。

硬件加速

在这种渲染模式下,库使用 Chromium GPU 进程中的 GPU 渲染网页内容,并将其直接显示在表面上。 在这种模式下,BrowserView 创建并嵌入了一个原生重量级窗口(表面),Chromium 在其上呈现生成的像素。

离屏

在这种渲染模式下,库使用 Chromium GPU 进程中的 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

局限性

嵌入和渲染

请不要将 Swing BrowserView 嵌入到 JInternalFrame 或 JLayeredPane中,或在启用 HARDWARE_ACCELERATED 渲染模式时在 BrowserView 上显示其他 Swing 组件。 在这种模式下, BrowserView 显示一个原生的重量级窗口。 在轻量级 GUI 中显示重量级窗口会导致混合使用重量级和轻量级组件的众所周知的问题。

根据文章,混合重量级和轻量级组件的问题已在 JDK 6 Update 12 和 JDK 7 build 19 中修复。仅适用于 Java Swing 重量级组件,例如 java.awt.Canvas。 JxBrowser 嵌入了它自己的重量级原生小部件。 因此,在这种情况下不会应用修复程序。

在 JavaFX 应用程序中,使用 StageStyle.TRANSPARENT 样式配置 javafx.stage.Stage 会将 WS_EX_LAYERED 窗口样式标志添加到 Windows 上的 JavaFX 窗口。 此标志用于创建分层窗口。 分层窗口是将其内容绘制到离屏窗口。如果在启用 HARDWARE_ACCELERATED 渲染模式时,将JavaFX BrowserView 嵌入到分层窗口中,由于窗口类型的冲突,其内容将不会被绘制。

在 macOS 上的 Eclipse RCP 应用程序中,当启用了 HARDWARE_ACCELERATED 渲染模式时,SWT小部件可能不会显示在 SWT BrowserView 小部件之上,因为当其他 SWT 小部件使用常规 NSView 绘制内容时,SWT BrowserView 小部件使用图层 NSView渲染内容。问题是常规 NSView 的内容不能与层支持 NSView 的内容重叠。这是因为渲染发生在不同的绘图上下文中,常规的 NSView 将始终显示在图层支持的 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

比例因子应该在启动 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