Introdução
Instalação
Guias
- Engine
- Profile
- Browser
- BrowserView
- Navegação
- Conteúdo
- DOM
- JavaScript
- Pop-ups
- Diálogos
- Downloads
- Extensões
- Rede
- Cache
- Cookies
- Proxy
- Autenticação
- Plugins
- Impressão
- Senhas
- Perfis de dados do Usuário
- Cartões de Crédito
- Mídia
- Área de transferência
- Zoom
- Corretor Ortográfico
- Implantação
- Chromium
Resolução de Problemas
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
:
var view = BrowserView.newInstance(browser);
import com.teamdev.jxbrowser.view.swing.BrowserView
...
val view = BrowserView.newInstance(browser)
E incorpore-o a um JFrame
:
frame.add(view, BorderLayout.CENTER);
frame.add(view, BorderLayout.CENTER)
Eis o exemplo completo:
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:
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
:
var view = BrowserView.newInstance(browser);
import com.teamdev.jxbrowser.view.javafx.BrowserView
...
val view = BrowserView.newInstance(browser)
E incorpore-o numa Scene
:
var scene = new Scene(new BorderPane(view), 800, 600);
val scene = Scene(BorderPane(view), 800.0, 600.0)
Eis o exemplo completo:
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:
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.
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:
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 = guides.pt.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:
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:
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:
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
:
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:
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:
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:
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:
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