Visão Geral do JavaFX WebView
Neste blog, será analisada a forma como o JavaFX pode renderizar páginas da web e o componente responsável por isso – conhecido como WebView.
O JavaFX é uma:
- Plataforma de software para criar e entregar aplicações desktop, bem como aplicações ricas para a internet (RIAs) que podem ser executadas em uma ampla variedade de dispositivos.
- Conjunto de pacotes de gráficos e mídia que permite aos desenvolvedores projetar, criar, testar, depurar e implementar aplicações clientes ricas que operam de forma consistente em diversas plataformas.
Principais Características do JavaFX:
WebView: Um componente web que usa a tecnologia HTML WebKit para possibilitar a incorporação de páginas da web dentro de uma aplicação JavaFX. O JavaScript em execução no WebView pode chamar APIs Java, e as APIs Java podem chamar JavaScript em execução no WebView. Suporte para recursos adicionais do HTML5, incluindo Web Sockets, Web Workers e Web Fonts, e capacidades de impressão foram adicionados no JavaFX.
JavaFX WebView:
- O JavaFX WebView é um mini navegador (também chamado de navegador embutido) que fornece um visualizador web e funcionalidade completa de navegação por meio de sua API em aplicações JavaFX.
- Este navegador é baseado no WebKit, um mecanismo de navegador web de código aberto que suporta HTML5, JavaScript, CSS, renderização DOM e gráficos SVG.
- A classe
WebViewé uma extensão da classeNode. - O navegador embutido herda todos os campos e métodos da classe
Nodee, portanto, possui todas as suas características. - Ele encapsula um objeto
WebEngine, incorpora conteúdo HTML na cena de uma aplicação e fornece propriedades e métodos para aplicar efeitos e transformações. - O método
getEngine()chamado em um objetoWebViewretorna umWebEngineassociado a ele. - As classes que constituem o navegador embutido residem no pacote
javafx.scene.web. - O WebView permite que os desenvolvedores implementem os seguintes recursos em suas aplicações Java:
- Renderizar conteúdo HTML de URLs locais ou remotas
- Suportar histórico e fornecer navegação para Trás e Avançar
- Recarregar o conteúdo
- Aplicar efeitos ao componente web
- Editar o conteúdo HTML
- Executar comandos JavaScript
- Realizar "upcalls" do JavaScript para o JavaFX
- Manipular eventos
🔧 Funcionalidades Suportadas
O componente WebView suporta os seguintes recursos do HTML5, além de suportar CSS3 e ecmascript6 (ES6):
- DOM3
- Canvas
- Reprodução de Mídia
- Controles de Formulário (exceto para
<input type="color">) - Conteúdo editável
- Manutenção de histórico
- Suporte para as tags
<meter>,<progress>,<details>e<summary> - SVG
- Web Sockets
- Web Workers
- Suporte para nomes de domínio escritos em idiomas nacionais
O diagrama abaixo descreve a arquitetura do navegador embutido e sua relação com outras classes JavaFX:
Web Engine:
- É um objeto não visual capaz de gerenciar uma página Web por vez.
- Fornece funcionalidade básica de página web por meio de sua API.
- Suporta interação do usuário, como navegar por links e enviar formulários HTML, embora não interaja diretamente com os usuários.
- Carrega páginas Web, cria seus modelos de documento, aplica estilos conforme necessário e executa JavaScript nas páginas.
- Fornece acesso ao modelo de documento da página atual e permite comunicação bidirecional entre uma aplicação Java e o código JavaScript da página.
- Envolve um objeto
WebPage, que fornece interação com o núcleo WebKit nativo.
🔄 Relação entre as Classes WebView e WebEngine
Snippets de Código para Carregar Conteúdo no JavaFX WebView:
1️⃣ Criar objetos WebView, WebEngine e carregar via URL Remota
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load("https://www.example.com");
2️⃣ Carregar Conteúdo HTML Estático
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<html><body><h1>Olá, Mundo!</h1></body></html>");
3️⃣ Carregar conteúdo HTML a partir de um arquivo local
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
File file = new File("caminho/para/seu/arquivo.html");
webEngine.load(file.toURI().toString());
4️⃣ Rastrear o Progresso de Carregamento com a ajuda do LoadWorker
Worker<Void> loadWorker = webEngine.getLoadWorker();
loadWorker.stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
System.out.println("Página carregada com sucesso!");
}
});
O carregamento sempre acontece em uma thread em segundo plano. Métodos que iniciam o carregamento retornam imediatamente após agendar um trabalho em segundo plano.
Para rastrear o progresso e/ou cancelar um trabalho, pode-se usar a instância Worker disponível do método getLoadWorker().
O exemplo a seguir altera o título do palco quando o carregamento é concluído com sucesso:
loadWorker.stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == Worker.State.SUCCEEDED) {
stage.setTitle(webEngine.getTitle());
}
});
5️⃣ Acesso ao Modelo de Documento
Os objetos WebEngine criam e gerenciam um Modelo de Objeto de Documento (DOM) para suas páginas Web. O modelo pode ser acessado e modificado usando as classes Java DOM Core.
O método getDocument() fornece acesso à raiz do modelo. Além disso, a especificação DOM Event é suportada para definir manipuladores de eventos em código Java.
O exemplo a seguir anexa um listener de evento Java a um elemento de uma página Web. Clicar no elemento faz com que a aplicação seja encerrada:
EventListener listener = (Event ev) -> {
Platform.exit();
};
Document doc = webEngine.getDocument();
Element el = doc.getElementById("sair");
((EventTarget) el).addEventListener("click", listener, false);
6️⃣ Chamar JavaScript a partir do JavaFX
Após o WebView carregar um site, é possível executar código JavaScript arbitrário no contexto da página atual usando o método executeScript(java.lang.String).
webEngine.executeScript("alert('Olá do JavaFX!');");
Mapeamento entre Java e JavaScript
7️⃣ Mapear Valores JavaScript para Objetos Java
- Valores JavaScript são representados usando as classes Java óbvias:
nullse tornanullem Java; um booleano se torna umjava.lang.Boolean; e uma string se torna umjava.lang.String. - Se o resultado for um objeto JavaScript, ele é empacotado como uma instância da classe
JSObject. - A classe
JSObjecté um proxy que fornece acesso a métodos e propriedades de seu objeto JavaScript subjacente. - Os métodos
JSObjectmais comumente usados sãogetMember(para ler uma propriedade nomeada),setMember(para definir uma propriedade) ecall(para chamar uma propriedade de valor de função). - Um DOM Node é mapeado para um objeto que estende
JSObjecte implementa as interfaces DOM apropriadas. Para obter um objetoJSObjectpara um Node, basta fazer um cast:
JSObject jdoc = (JSObject) webEngine.getDocument();
8️⃣ Mapear Objetos Java para Valores JavaScript
- Os argumentos dos métodos
JSObjectsetMemberecallpassam objetos Java para o ambiente JavaScript. - Este é aproximadamente o inverso do mapeamento JavaScript para Java descrito acima: Objetos Java
String,NumberouBooleansão convertidos para os valores JavaScript óbvios. - Um objeto
JSObjecté convertido para o objeto JavaScript empacotado original. Caso contrário, umJavaRuntimeObjecté criado. - Este é um objeto JavaScript que atua como um proxy para o objeto Java, no sentido de que acessar propriedades do
JavaRuntimeObjectfaz com que o campo ou método Java com o mesmo nome seja acessado.
Atualização do WebKit no JDK
O mecanismo WebKit do WebView é baseado na porta Apple Safari. Esta porta também é usada por iOS, GTK, WinCairo, EFL etc.
O ciclo de lançamento do WebKit GTK é seguido e o WebKit será atualizado a cada 6 meses.
O objetivo de atualizar o WebKit é ter correções de vulnerabilidades de segurança, além de novos recursos e adesão aos padrões mais recentes.