List icon Conteúdo

BrowserView

O documento descreve como incorporar um componente visual que apresenta o conteúdo de páginas Web em aplicações Swing, JavaFX, SWT e Compose Desktop.

Visão Geral

O JxBrowser pode ser utilizado em aplicações Java construídas com as seguintes estruturas GUI Java:

  • Swing
  • JavaFX
  • Compose Desktop
  • SWT

O componente Browser em si não é um componente visual que permite a visualização de uma página web. Para apresentar o conteúdo de uma página Web carregada no Browser, utilize um dos seguintes controles, dependendo da estrutura GUI utilizada:

  • com.teamdev.jxbrowser.view.swing.BrowserView
  • com.teamdev.jxbrowser.view.javafx.BrowserView
  • com.teamdev.jxbrowser.view.compose.BrowserView
  • com.teamdev.jxbrowser.view.swt.BrowserView

Swing

Para exibir o conteúdo de uma página da Web em um aplicativo Java Swing, crie uma instância do com.teamdev.jxbrowser.view.swing.BrowserView:

Java
Kotlin

var view = BrowserView.newInstance(browser);

import com.teamdev.jxbrowser.view.swing.BrowserView
...
val view = BrowserView.newInstance(browser)

E incorpore-o a um JFrame:

Java
Kotlin

frame.add(view, BorderLayout.CENTER);

frame.add(view, BorderLayout.CENTER)

Eis o exemplo completo:

Java
Kotlin


import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
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.WindowConstants;

import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;
import static javax.swing.SwingUtilities.invokeLater;

/**
 * A aplicação mais simples com o componente de browser integrado.
 *
 * <p>Este exemplo demonstra:
 *
 * <ol>
 *     <li>Criando uma instância de {@link Engine}.
 *     <li>Criar uma instância de {@link Browser}.
 *     <li>Incorporar o browser no Swing através de {@link BrowserView}.
 *     <li>Carregando o site "https://html5test.teamdev.com".
 * </ol>
 */
public final class BrowserViewSwing {
    public static void main(String[] args) {
        // Criando e executando o Chromium engine.
        var engine = Engine.newInstance(HARDWARE_ACCELERATED);

        var browser = engine.newBrowser();
        // Carregando a página Web necessária.
        browser.navigation().loadUrl("https://html5test.teamdev.com");

        invokeLater(() -> {
            // Criando componente Swing para renderizar conteúdo Web
            // carregado na instância de Browser dada.
            var view = BrowserView.newInstance(browser);

            // Criando e apresentando o frame da aplicação Swing
            var frame = new JFrame("JxBrowser AWT/Swing");
            // Fechar o motor quando o frame da aplicação está prestes a fechar.
            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.dsl.Engine
import com.teamdev.jxbrowser.dsl.browser.navigation
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

/**
 * A aplicação mais simples com o componente de browser integrado.
 *
 * Este exemplo demonstra:
 *
 *  1. Criando uma instância de [Engine].
 *  2. Criando uma instância de [Browser].
 *  3. Incorporando o navegador no Swing via [BrowserView].
 *  4. Carregando o site "https://html5test.teamdev.com".
 */
fun main() {
    // Criando e executando o mecanismo Chromium.
    val engine = Engine(RenderingMode.HARDWARE_ACCELERATED)
    val browser = engine.newBrowser()
    // Carregando a página web necessária.
    browser.navigation.loadUrl("https://html5test.teamdev.com")
    SwingUtilities.invokeLater {
        // Criando componente Swing para renderizar conteúdo Web
        // carregado na instância de Browser fornecida.
        val view = BrowserView.newInstance(browser)

        // Criando e apresentar o frame da aplicação Swing.
        val frame = JFrame("JxBrowser AWT/Swing")
        // Fechar o motor quando o frame da aplicação está prestes a fechar.
        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
    }
}

O resultado deste exemplo tem o seguinte aspecto: AWT/Swing BrowserView

Veja também nosso tutorial em vídeo que mostra como adicionar BrowserView a uma aplicação Java Swing:

JavaFX

Para exibir o conteúdo de uma página da Web em um aplicativo JavaFX, crie uma instância do com.teamdev.jxbrowser.view.javafx.BrowserView:

Java
Kotlin

var view = BrowserView.newInstance(browser);

import com.teamdev.jxbrowser.view.javafx.BrowserView
...
val view = BrowserView.newInstance(browser)

E incorpore-o numa Scene:

Java
Kotlin

var scene = new Scene(new BorderPane(view), 800, 600);

val scene = Scene(BorderPane(view), 800.0, 600.0)

Eis o exemplo completo:

Java
Kotlin


import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
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;

/**
 * A aplicação mais simples com o componente de browser integrado.
 *
 * <p>Este exemplo demonstra:
 * <ol>
 *     <li>Criando uma instância de {@link Engine}.
 *     <li>Criando uma instância de {@link Browser}.
 *     <li>Incorporação do browser em JavaFX através de {@link BrowserView}.
 *     <li>Carregando o site "https://html5test.teamdev.com".
 * </ol>
 */
public final class BrowserViewJavaFx extends Application {

    @Override
    public void start(Stage primaryStage) {
        // Criando e executando o motor Chromium.
        var engine = Engine.newInstance(HARDWARE_ACCELERATED);

        var browser = engine.newBrowser();
        // Carregando a página Web necessária.
        browser.navigation().loadUrl("https://html5test.teamdev.com");

        // Criando o componente UI para renderizar conteúdo Web
        // carregado na instância de Browser dada.
        var view = BrowserView.newInstance(browser);

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

        // Fechando o motor quando o palco está prestes a fechar.
        primaryStage.setOnCloseRequest(event -> engine.close());
    }
}

import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.dsl.Engine
import com.teamdev.jxbrowser.dsl.browser.navigation
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

/**
 * A aplicação mais simples com o componente de browser integrado.
 *
 * <p>Este exemplo demonstra:
 *  1. Criando uma instância de [Engine].
 *  2. Criando uma instância de [Browser].
 *  3. Incorporando o navegador no JavaFX via [BrowserView].
 *  4. Carregando o site "https://html5test.teamdev.com".
 */
class HelloWorld : Application() {
    override fun start(primaryStage: Stage) {
        // Criando e executando o mecanismo Chromium.
        val engine = Engine(RenderingMode.HARDWARE_ACCELERATED)
        val browser = engine.newBrowser()
        // Carregando a página web necessária.
        browser.navigation.loadUrl("https://html5test.teamdev.com")

        // Criando o componente UI para renderizar o conteúdo da web
        // carregado na instância dada do Browser.
        val view = BrowserView.newInstance(browser)
        val scene = Scene(BorderPane(view), 800.0, 600.0)
        primaryStage.title = "JxBrowser JavaFX"
        primaryStage.scene = scene
        primaryStage.show()

        // Fechar o motor quando o palco está prestes a fechar.
        primaryStage.onCloseRequest = EventHandler { engine.close() }
    }
}

O resultado deste exemplo tem o seguinte aspecto: JavaFX BrowserView

Veja também nosso tutorial em vídeo que mostra como adicionar BrowserView a um aplicativo JavaFX:

JFXPanel

Recomendamos que utilize o Swing BrowserView em aplicações Swing, bem como o JavaFX BrowserView em aplicações JavaFX.

Às vezes, pode ser necessário incorporar o JavaFX BrowserView em uma aplicação Swing. Por exemplo, se desenvolver um controle de navegador Web complexo utilizando o JavaFX UI Toolkit e tiver de apresentar este controle JavaFX numa aplicação Swing/AWT.

Desde a versão 7.1, é possível incorporar o JavaFX BrowserView em uma janela Swing/AWT através do javafx.embed.swing.JFXPanel. É suportado em todas as plataformas suportadas com todos os modos de renderização.

Java
Kotlin


import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.view.javafx.BrowserView;
import java.awt.BorderLayout;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;
import static javafx.application.Platform.runLater;

/**
 * O exemplo demonstra como incorporar o JavaFX BrowserView no
 * JFXPanel que é apresentado no interior do frame Swing/AWT.
 */
public final class JFXPanelExample {

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

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

        // Incorporando o JFXPanel no Swing Frame.
        var fxPanel = new JFXPanel();
        frame.add(fxPanel, BorderLayout.CENTER);
        frame.setSize(600, 600);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Inicialização do JFXPanel na thread de interface JavaFX.
        runLater(() -> initFX(fxPanel));
    }

    private static void initFX(JFXPanel fxPanel) {
        var engine = Engine.newInstance(HARDWARE_ACCELERATED);

        var browser = engine.newBrowser();
        browser.navigation().loadUrl("https://html5test.teamdev.com");
        // Criar JavaFX BrowserView e inseri-lo no JFXPanel.
        var view = BrowserView.newInstance(browser);
        var pane = new BorderPane(view);
        fxPanel.setScene(new Scene(pane, 600, 600));
    }
}

import com.teamdev.jxbrowser.dsl.Engine
import com.teamdev.jxbrowser.dsl.browser.navigation
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

/**
 * O exemplo demonstra como incorporar o JavaFX BrowserView no
 * JFXPanel que é apresentado dentro do Swing/AWT Frame.
 */
fun main() = SwingUtilities.invokeLater {
    initAndShowGUI()
}

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

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

    // Inicializando o JFXPanel na thread de interface JavaFX.
    Platform.runLater {
        initFX(fxPanel)
    }
}

private fun initFX(fxPanel: JFXPanel) {
    val engine = Engine(RenderingMode.HARDWARE_ACCELERATED)
    val browser = engine.newBrowser()
    browser.navigation.loadUrl("https://html5test.teamdev.com")
    // Criando JavaFX BrowserView e inserindo-o no JFXPanel.
    val view = BrowserView.newInstance(browser)
    val pane = BorderPane(view)
    fxPanel.scene = Scene(pane, 600.0, 600.0)
}

FXML

Você pode incorporar o JavaFX BrowserView numa aplicação FXML utilizando a abordagem descrita na seção seguinte.

Em primeiro lugar, descreva a estrutura do arquivo browser-view.fxml para indicar ao JavaFX como o controle BrowserView deve ser incorporado na GUI da aplicação JavaFX.

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

Este FXML declara um componente que consiste em dois elementos: barra de endereço e visualização de navegador. A barra de endereço representa um campo de texto simples. Aqui podemos escrever um URL e pressionar Enter para o carregá-lo na visualização de navegador abaixo. A visualização de navegador contém FxmlBrowserView que apresenta o conteúdo da página Web carregada.

A implementação de FxmlBrowserViewController definida no arquivo browser-view.fxml tem o seguinte aspecto:

Java
Kotlin


import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;

/**
 * Representa o controlador FXML com a barra de endereço e a área de visualização de navegador que
 * apresenta o URL introduzido na barra de endereço.
 */
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());
    }
}

import com.teamdev.jxbrowser.dsl.browser.navigation
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

/**
 * Representa o controlador FXML com a barra de endereço e a área de visualização do browser que
 * apresenta o URL introduzido na barra de endereço.
 */
class FxmlBrowserViewController : Initializable {

    @FXML
    private val textField = TextField()

    @FXML
    private val browserView = FxmlBrowserView()

    override fun initialize(location: URL, resources: ResourceBundle) {
        browserView.browser().navigation.loadUrl(textField.text)
    }

    fun loadUrl(actionEvent: ActionEvent) {
        browserView.browser().navigation.loadUrl(textField.text)
    }
}

Você pode notar que a implementação do controlador utiliza FxmlBrowserView em vez do JavaFX BrowserView. Isto deve-se ao fato de o JavaFX BrowserView não fornecer o construtor público padrão, portanto, ele não pode ser utilizado diretamente no FXML. Para incorporar o JavaFX BrowserView utilize o FxmlBrowserView que representa um simples wrapper com o construtor público padrão que inicializa e incorpora o JavaFX BrowserView.

A implementação da classe FxmlBrowserView é a seguinte:

Java
Kotlin


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;

/**
 * Um componente envolvedor para JavaFX {@link BrowserView} que permite utilizar
 * a instância BrowserView nas aplicações FXML. O JavaFX BrowserView
 * não pode ser utilizado diretamente no FXML, porque não fornece o padrão
 * construtor público.
 */
public final class FxmlBrowserView extends StackPane {

    private final Browser browser;

    /**
     * Constrói uma instância de {@code FxmlBrowserView}.
     */
    public FxmlBrowserView() {
        var engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED);
        browser = engine.newBrowser();
        var view = BrowserView.newInstance(browser);
        getChildren().add(view);
    }

    /**
     * Retorna a instância {@link Browser} da visualização atual do navegador.
     */
    public Browser browser() {
        return browser;
    }
}

import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.dsl.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import com.teamdev.jxbrowser.view.javafx.BrowserView
import javafx.scene.layout.StackPane

/**
 * Um componente encapsulado para JavaFX [BrowserView] que permite utilizar
 * a instância BrowserView em aplicações FXML. O JavaFX BrowserView
 * não pode ser utilizado diretamente no FXML, porque não fornece o construtor público
 * padrão.
 */
class FxmlBrowserView : StackPane() {

    private val browser: Browser

    /**
     * Constrói uma instância de `FxmlBrowserView`.
     */
    init {
        val engine = Engine(RenderingMode.HARDWARE_ACCELERATED)
        browser = engine.newBrowser()
        val view = BrowserView.newInstance(browser)
        children.add(view)
    }

    /**
     * Devolve a instância [Browser] da vista do browser atual.
     */
    fun browser() = browser
}

Agora, temos tudo para implementar e executar o nosso exemplo FXML:

Java
Kotlin

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

/**
 * Este exemplo demonstra como utilizar o JavaFX BrowserView numa aplicação FXML
 * através do controlo {@link com.teamdev.jxbrowser.view.javafx.FxmlBrowserView}.
 */
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 {
        var resource = BrowserViewInFxml.class.getResource("browser-view.fxml");
        if (resource == null) {
            throw new IllegalStateException("The browser-view.fxml file not found.");
        }
        BorderPane pane = FXMLLoader.load(resource);

        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

/**
 * Este exemplo demonstra como utilizar o JavaFX BrowserView na aplicação FXML
 * através do controle [com.teamdev.jxbrowser.view.javafx.FxmlBrowserView] .
 */
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)
}

Depois de executar este exemplo, deverá obter o seguinte resultado:

FXML Saída Exemplo

O exemplo completo com todas as classes e recursos utilizados nesta seção podem ser encontrados em JxBrowser Examples.

SWT

Para exibir o conteúdo de uma página da Web em um aplicativo Java SWT, crie uma instância do com.teamdev.jxbrowser.view.swt.BrowserView:

Java
Kotlin

var display = new Display();
var shell = new Shell(display);
...
var 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)

Eis o exemplo completo:

Java
Kotlin


import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
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;

/**
 * A aplicação mais simples com o componente de browser integrado.
 *
 * <p>Este exemplo demonstra:
 * <ol>
 *     <li>Criar uma instância de {@link Engine}.
 *     <li>Criar uma instância de {@link Browser}.
 *     <li>Incorporação do browser no SWT através de {@link BrowserView}.
 *     <li>Carregamento do sítio Web "https://html5test.teamdev.com".
 * </ol>
 */
public final class BrowserViewSwt {

    public static void main(String[] args) {
        // Criar e executar o motor Chromium.
        var engine = Engine.newInstance(HARDWARE_ACCELERATED);
        var browser = engine.newBrowser();

        // Carregar a página Web necessária.
        browser.navigation().loadUrl("https://html5test.teamdev.com");

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

        // Criar componente SWT para renderizar
        // conteúdo Web carregado na instância Browser.
        var view = BrowserView.newInstance(shell, browser);
        view.setSize(800, 600);

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

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

        // Encerrar o motor e libertar todos os recursos atribuídos.
        engine.close();
        display.dispose();
    }
}

import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.dsl.browser.navigation
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

/**
 * A aplicação mais simples com o componente de browser integrado.
 *
 * <p>Este exemplo demonstra:
 *  1. Criando uma instância de [Engine].
 *  2. Criando uma instância de [Browser].
 *  3. Incorporando o navegador no SWT via [BrowserView].
 *  4. Carregando o site "https://html5test.teamdev.com".
 */
fun main() {
    // Criar e executar o motor Chromium.
    val engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED)
    val browser = engine.newBrowser()

    // Carregar a página Web necessária.
    browser.navigation.loadUrl("https://html5test.teamdev.com")

    val display = Display()
    val shell = Shell(display)
    shell.text = "JxBrowser SWT"
    shell.layout = FillLayout()

    // Criar componente SWT para renderizar
    // conteúdo Web carregado na instância Browser.
    val view = BrowserView.newInstance(shell, browser)
    view.setSize(800, 600)

    shell.pack()
    shell.open()

    while (!shell.isDisposed) {
        if (!display.readAndDispatch()) {
            display.sleep()
        }
    }

    // Encerrar o motor e libertar todos os recursos atribuídos.
    engine.close()
    display.dispose()
}

O resultado deste exemplo tem o seguinte aspecto: SWT BrowserView

Veja também o nosso tutorial em vídeo que mostra como adicionar BrowserView a uma aplicação Java SWT:

Compose Desktop

Para exibir o conteúdo de uma página da web em uma aplicação Compose Desktop, use o composable com.teamdev.jxbrowser.view.compose.BrowserView:

import com.teamdev.jxbrowser.view.compose.BrowserView
...
BrowserView(browser)

Atualmente, este composable suporta apenas o modo de renderização off-screen.

Aqui está o exemplo completo:

import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.singleWindowApplication
import com.teamdev.jxbrowser.browser.Browser
import com.teamdev.jxbrowser.dsl.Engine
import com.teamdev.jxbrowser.dsl.browser.navigation
import com.teamdev.jxbrowser.engine.Engine
import com.teamdev.jxbrowser.engine.RenderingMode
import com.teamdev.jxbrowser.view.compose.BrowserView

/**
 * 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 Compose Desktop via [BrowserView].
 *  4. Loading the "https://html5test.teamdev.com" website.
 */
fun main() {
    // Criando e executando o mecanismo Chromium.
    val engine = Engine(RenderingMode.OFF_SCREEN)
    val browser = engine.newBrowser()
    // Carregando a página web necessária.
    browser.navigation.loadUrl("https://html5test.teamdev.com")
    singleWindowApplication(
        title = "Compose Desktop BrowserView",
        state = WindowState(width = 800.dp, height = 600.dp),
    ) {
        // Criando um componente Compose para renderizar conteúdo da web
        // carregado na instância do navegador fornecida.
        BrowserView(browser)
        DisposableEffect(Unit) {
            onDispose {
                // Feche o mecanismo quando a janela do aplicativo sair da composição.
                engine.close()
            }
        }
    }
}

O resultado deste exemplo é o seguinte: Compose Desktop BrowserView

Renderização

O JxBrowser suporta vários modos de renderização. Nesta seção, descreveremos cada um dos modos com o seu desempenho e limitações, e forneceremos recomendações sobre a escolha do modo correto, dependendo do tipo de aplicação Java.

Acelerado por hardware

Neste modo de renderização, a biblioteca renderiza o conteúdo de uma página Web utilizando a GPU no processo GPU do Chromium e apresenta-a diretamente numa superfície. Neste modo, o BrowserView cria e incorpora uma janela nativa heavyweight (superfície) na qual o Chromium renderiza os pixels produzidos.

Desempenho

O desempenho de renderização é equivalente ao do Chromium ou Google Chrome, pois o Chromium renderiza os pixels diretamente em uma janela nativa embutida no componente BrowserView. A taxa média de renderização em Frames por Segundo (FPS) de um vídeo HTML5 é de aproximadamente 60FPS.

Limitações

Em uma aplicação Swing, evite embutir o BrowserView do Swing em um JInternalFrame ou JLayeredPane, ou exibir outros componentes Swing sobre o BrowserView. Neste modo de renderização, o JxBrowser embute e exibe uma janela nativa pesada. Exibir uma janela pesada dentro de uma interface gráfica Swing leve resulta em um problema conhecido de mistura de componentes pesados e leves.

De acordo com o artigo, o problema da mistura de componentes pesados e leves foi resolvido no JDK 6 Update 12 e no JDK 7 build 19. No entanto, isso é válido apenas para os componentes pesados do Java Swing, como o java.awt.Canvas. O JxBrowser embute seu próprio componente nativo pesado, portanto, a correção não se aplica nesse caso.

Em uma aplicação JavaFX, configurar o javafx.stage.Stage com o estilo StageStyle.TRANSPARENT adiciona a flag de estilo de janela WS_EX_LAYERED à janela JavaFX no Windows. Esta flag é usada para criar uma janela em camadas, que desenha seu conteúdo off-screen. Se você embutir o BrowserView do JavaFX em uma janela em camadas, o conteúdo não será renderizado devido ao conflito de tipos de janela.

Em uma aplicação Eclipse RCP no macOS, quando o modo de renderização acelerada por hardware está ativado, os widgets SWT podem não ser exibidos sobre o BrowserView SWT, pois ele renderiza o conteúdo utilizando NSView com suporte a camadas, enquanto os outros widgets SWT desenham seu conteúdo utilizando NSView regular. O conteúdo de um NSView regular não pode se sobrepor ao conteúdo de um NSView com suporte a camadas, pois a renderização ocorre em contextos de desenho diferentes, fazendo com que o NSView regular seja sempre exibido abaixo do NSView com suporte a camadas.

Fora da Tela

Neste modo de renderização, a biblioteca renderiza o conteúdo de uma página Web utilizando a GPU no processo GPU do Chromium e copia os pixéis para uma memória intermédia fora de tela atribuída na memória do processo Java. Neste modo, o BrowserView cria e incorpora um componente leve que lê os pixels do buffer fora da tela e os exibe usando a API gráfica Java padrão.

Desempenho

No modo de renderização fora de tela, o desempenho é diferente para cada conjunto de ferramentas de IU e sistema operacional. Os resultados do teste de desempenho de renderização de um vídeo HTML5 em FPS são os seguintes:

Windows

  • AMD Ryzen 9 3900X 12-Core 3.79GHz, 64GB RAM, GPU NVIDIA GeForce RTX 3080
  • Dimensão do vídeo: 1920x1080 (Full HD)
Compose |------------------------------------------------------------| 60FPS
 JavaFX |------------------------------------------------------------| 60FPS
  Swing |------------------------------------------------------------| 60FPS
    SWT |------------------------------------------------------------| 60FPS

macOS

  • MacBook Pro 16, M3 Max, 48GB RAM
  • Dimensão do vídeo: 3840x2160 (4K)
Compose |------------------------------------------------------------| 60FPS
 JavaFX |------------------------------------------------------------| 60FPS
  Swing |------------------------------------------------------------| 60FPS
    SWT |------------------------------------------------------------| 60FPS

Linux

  • AMD FX-8300 3.3 GHz with GPU Radeon RX 480
  • Dimensão do vídeo: 1920x1080 (Full HD)
Compose |----------------------------------------------| 46FPS
 JavaFX |--------------------------------------------| 44FPS
  Swing |----------------------------------------------------------| 58FPS
    SWT |----------------| 16FPS

Limitações

Neste modo de renderização no Windows, Linux e macOS (em ambos os modos de renderização), os eventos de mouse, teclado e toque são processados no lado Java e encaminhados para o Chromium. Os toolkits Java Swing, JavaFX, SWT e Compose UI não oferecem suporte completo a eventos de toque, portanto, o JxBrowser não oferece suporte para alguns gestos de toque.

A mesma limitação se aplica à funcionalidade de arrastar e soltar (Drag and Drop - DnD). O DnD é processado usando a API Java DnD, por isso não funciona exatamente como no Google Chrome. O DnD suporta apenas um conjunto predefinido de formatos.

Arrastar e Soltar

Por padrão, a função arrastar e soltar está ativada para Swing, JavaFX e SWT BrowserView. Para desativar a função arrastar e soltar, utilize o seguinte procedimento:

Java
Kotlin

browserView.dragAndDrop().disable();

browserView.dragAndDrop().disable()

HiDPI

Esta seção descreve as capacidades e limitações do JxBrowser em ambientes com telas HiDPI.

macOS

No macOS, o JxBrowser suporta telas HiDPI e Retina prontos a utilizar em Swing, JavaFX e SWT.

Windows

No Windows, o JxBrowser suporta telas HiDPI prontos a utilizar em Swing e JavaFX.

SWT

A biblioteca apenas reconhece o fator de escala de um monitor primário. O fator de escala deve ser um múltiplo de 25%. É obrigatório utilizar a propriedade de sistema swt.autoScale se necessitar de suporte HiDPI. Os valores suportados são quarter e exact:

java -Dswt.autoScale=quarter -jar application.jar

No Eclipse 4.6 e superior, a propriedade swt.autoScale é sempre quarter.

Você pode ler mais sobre swt.autoScale aqui.

Linux

O fator de escala deve ser explicitamente configurado ao iniciar a JVM. Ele é detectado automaticamente.

Swing

Para configurar o fator de escala em uma aplicação Swing, utilize a propriedade de sistema sun.java2d.uiScale. Ela aceita apenas valores inteiros.

java -Dsun.java2d.uiScale=2 -jar application.jar

JavaFX

Para configurar o fator de escala numa aplicação JavaFX, utilize a propriedade de sistema glass.gtk.uiScale. Ela aceita apenas valores inteiros.

java -Dglass.gtk.uiScale=2 -jar application.jar