List icon Conteúdo

Publicado em 30 de julho de 2019

JxBrowser 7.1

Conheça o novo JxBrowser 7.1!

Nesta atualização, nos concentramos em restaurar as funcionalidades temporariamente abandonadas e em expandir a funcionalidade atual com novas possibilidades.

Interceptar eventos do mouse e do teclado

Agora você pode intercetar os eventos do mouse e do teclado antes de serem enviados para a página Web utilizando as seguintes callbacks:

  • EnterMouseCallback
  • ExitMouseCallback
  • MoveMouseCallback
  • MoveMouseWheelCallback
  • PressKeyCallback
  • PressMouseCallback
  • ReleaseKeyCallback
  • ReleaseMouseCallback
  • TypeKeyCallback

O exemplo seguinte demonstra como ocultar a roda do mouse:

browser.set(MoveMouseWheelCallback.class, params -> Response.suppress());

Você pode utilizar estas chamadas de retorno para obter notificações sobre os eventos do mouse e do teclado, de modo a implementar teclas de atalho em a sua aplicação.

Acessar o bitmap de uma página Web

Agora você pode obter um bitmap que contém os pixels da página web atualmente carregada com o tamanho atual do Browser. O exemplo seguinte demonstra como obter um bitmap, convertê-lo em imagens Java AWT e JavaFX e salvá-lo num arquivo PNG:

Swing

// Criar e executar o motor Chromium
Engine engine = Engine.newInstance(
        EngineOptions.newBuilder(HARDWARE_ACCELERATED).build());
Browser browser = engine.newBrowser();
// Redimensionar o browser para a dimensão pretendida
browser.resize(500, 500);
// Carrega a página Web pretendida e espera até estar completamente carregada
browser.navigation().loadUrlAndWait("https://www.google.com");
// Obtém um bitmap da página Web atualmente carregada. O seu tamanho será 
// igual ao tamanho do browser atual.
Bitmap bitmap = browser.bitmap();
// Converte o bitmap para java.awt.image.BufferedImage
BufferedImage bufferedImage = BitmapUtil.toBufferedImage(bitmap);
// Salva a imagem num arquivo PNG
ImageIO.write(bufferedImage, "PNG", new File("bitmap.png"));

JavaFX

// Criar e executar o motor Chromium
Engine engine = Engine.newInstance(
        EngineOptions.newBuilder(HARDWARE_ACCELERATED).build());
Browser browser = engine.newBrowser();
// Redimensionar o browser para a dimensão pretendida
browser.resize(500, 500);
// Carrega a página Web pretendida e espera até estar completamente carregada
browser.navigation().loadUrlAndWait("https://www.google.com");
// Obtém um bitmap da página Web atualmente carregada. O seu tamanho será
// igual ao tamanho do browser atual.
Bitmap bitmap = browser.bitmap();
// Converte o bitmap para javafx.scene.image.Image
Image image = BitmapUtil.toImage(bitmap);
// Converte javafx.scene.image.Image para java.awt.image.BufferedImage
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);
// Salva a imagem num arquivo PNG
ImageIO.write(bufferedImage, "PNG", new File("bitmap.png"));

JavaScript-Java bridge

@JsAccessible

Agora a anotação @JsAccessible pode ser usada na classe. Isso significa que todos os métodos públicos do objeto Java injetado anotado com @JsAccessible são acessíveis a partir do JavaScript.

Conversão automática de tipos

Melhoramos a funcionalidade da Bridge JavaScript-Java e introduzimos a conversão automática de tipos ao chamar um método público do objeto Java injetado a partir do JavaScript. Na V7.0 o JavaScript Number podia ser convertido apenas para Java Double.

Agora a biblioteca converte automaticamente o Número JavaScript fornecido para o tipo Java necessário se for possível. Se detectarmos que o número dado não pode ser convertido para, por exemplo, um byte Java sem perda de dados, então a biblioteca lança uma exceção e notifica o JavaScript que não existe um método Java apropriado. Se o valor fornecido puder ser convertido sem perda de dados, a biblioteca o converte e invoca o método Java adequado.

Por exemplo, se você injetar o seguinte objeto Java no JavaScript:


@JsAccessible
public final class JavaObject {

    public int method(int intValue) {
        return intValue;
    }
}

Em seguida, é possível chamá-lo a partir do JavaScript e passar o valor Number do JavaScript que pode ser convertido para um Integer sem perda de dados:

window.javaObject.method(123);

Mas, se você passar um valor Double que não possa ser convertido para Integer sem perda de dados, receberá um erro:

window.javaObject.method(3.14); // <- erro

JsFunctionCallback

A ponte JavaScript-Java te permite associar um objeto Java ou um valor primitivo a uma propriedade JavaScript. Agora, é possível associar JsFunctionCallback a uma propriedade JavaScript que será tratada como uma função que pode ser invocada no código JavaScript.

Por exemplo, você pode registrar uma função JavaScript associada à instância JsFunctionCallback utilizando o seguinte código:

JsObject window = frame.executeJavaScript("window");
if (window != null) {
    window.putProperty("sayHello", (JsFunctionCallback) args ->
            "Hello, " + args[0]);
}

Agora, em JavaScript, você pode invocar esta função da seguinte forma:

window.sayHello('John');

Saiba mais

API de armazenamento Web

Você pode acessar o armazenamento local e de sessão e trabalhar com ele diretamente a partir do código Java:

WebStorage localStorage = frame.localStorage();
localStorage.putItem("car", "BMW");
localStorage.clear();

Saiba mais

URL de depuração remota

Na versão 7.1 restauramos a funcionalidade que permite obter a URL de depuração remota para uma página web carregada numa instância particular do Browser. O seguinte exemplo demonstra como fazer:

browser.devTools().remoteDebuggingUrl().ifPresent(url -> {});

JFXPanel

O JxBrowser fornece dois componentes BrowserView para aplicações Swing e JavaFX. Recomendamos a utilização do Swing BrowserView em aplicações Swing e do JavaFX BrowserView em aplicações JavaFX.

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

Agora você pode incorporar JavaFX BrowserView numa janela Swing/AWT através do JFXPanel. É suportado em todas as plataformas suportadas com todos os modos de renderização.

Selecionar dispositivo multimídia

Se você tem várias webcams e microfones no seu ambiente, e uma página web quer usar um deles, você pode usar SelectMediaDeviceCallback para dizer à página web qual dispositivo deve ser usado.

O exemplo seguinte demonstra como selecionar o primeiro dispositivo na lista de dispositivos disponíveis:

engine.mediaDevices().set(SelectMediaDeviceCallback.class, params ->
        Response.select(params.mediaDevices().get(0)));

Se você deseja proibir a página Web de acessar o seu microfone ou a uma webcam, você pode utilizar RequestPermissionCallback, como mostrado abaixo:

engine.permissions().set(RequestPermissionCallback.class, (params, tell) -> {
    PermissionType type = params.permissionType();
    if (type == PermissionType.VIDEO_CAPTURE || type == PermissionType.AUDIO_CAPTURE) {
        tell.deny();
    } else {
        tell.grant();
    }
});

Response body acesso HTTP

No JxBrowser 7.0 foi introduzido o evento BytesReceived que permite obter a informação sobre a quantidade de bytes recebidos da rede. Nesta versão foi adicionado o ResponseBytesReceived que permite acessar aos bytes do response body HTTP:

network.on(ResponseBytesReceived.class, event -> {
    byte[] data = event.data();
});

Ocultar barras de rolagem

Agora você pode ocultar as barras de rolagem utilizando a seguinte abordagem:

browser.settings().hideScrollbars();

Uma vez chamado este método, as páginas web carregadas na instância Browser não exibirão mais barras de rolagem. Isto é útil para aplicações de quiosque e quando se está capturando um bitmap de uma página Web.

DOM API

Element

O Element foi expandido com os seguintes métodos:

  • focus() e blur() permitem definir programaticamente o foco do teclado para um elemento HTML focalizável e limpar o foco.
  • outerHtml() permite obter uma string que representa uma serialização HTML do Element e seus descendentes.

Node.document()

A partir da V7.1 é possível obter a instância Document de uma instância Node. Por exemplo:

Document document = node.document();

Internacionalização I18N

Agora a biblioteca suporta a internacionalização (I18N) ao navegar no sistema de arquivos local:

i18n

Baixar a API

Expandimos a API do JxBrowser com a funcionalidade que permite obter a instância do Browser que iniciou o download usando o seguinte código:

downloads.set(StartDownloadCallback.class, (params, tell) -> {
    params.browser().ifPresent(browser -> {
        ...
    });
    tell.cancel();
});

Note que a instância Browser pode já estar fechada ou não estar disponível no momento em que a transferência é iniciada. Esta é a razão pela qual utilizamos Optional<Browser> na API.

Desativar o menu tátil

Expandimos o EngineOptions com uma opção adicional que permite desativar o menu tátil em dispositivos táteis do Windows 10. O seguinte trecho de código demonstra como desativar o menu tátil:

Engine engine = Engine.newInstance(
        EngineOptions.newBuilder(renderingMode)
                .disableTouchMenu()
                .build());

Request de evento de foco

Para receber notificações quando o JavaScript solicita o foco via window.focus() você pode usar o evento FocusRequested:

browser.on(FocusRequested.class, event -> {});

Linguagem API

O enum Language foi expandido com o método estático Language.of(String language, String country) que obtém o item correspondente do enum Language para o idioma e país fornecidos.

Recomendamos a utilização deste método ao invés de Language.of(Locale) se houver a necessidade de passar os novos códigos de linguagem ao invés dos antigos, pois o Java Locale converte internamente o novo código de linguagem passado ao construtor para o antigo. Existe a possibilidade de não encontrar uma língua para um código antigo, por isso, se quiser ter a certeza de que a localidade passada não será convertida, utilize este método com os códigos de idioma e país necessários.

Certificate.toX509Certificate()

A classe Certificate foi expandida com o método Optional<X509Certificate> toX509Certificate() que permite obter um certificado X.509 inicializado com os dados armazenados no array de bytes codificados em DER do certificado.

Melhorias

  • Detecta quando o processo Java é encerrado inesperadamente com o sinal kill -9 no macOS ou Linux e encerra os processos browsercore criados pelo processo Java encerrado.
  • Atualiza os detalhes do processo browsercore.exe no Windows.
  • XPathResult.asSingleNode() devolve um Optional vazio em vez de lançar uma exceção quando o nó não é encontrado.
  • Implementações padrão do StartDownloadCallback para os componentes Swing e JavaFX BrowserView. Agora, quando você tentar transferir um arquivo, será apresentada uma caixa de diálogo padrão Salvar Arquivo, onde você poderá selecionar onde transferir e salvar o arquivo. A menos que você registre o seu próprio retorno de chamada e substitua o comportamento padrão.
  • Reduz o piscamento preto no Windows ao exibir o Swing BrowserView pela primeira vez.

Problemas corrigidos

  • Restaura o suporte do macOS 10.10.
  • A opção de idioma Engine ignorada e sempre ENGLISH_US no Linux ao trabalhar no macOS e no Windows.
  • O frame principal do pop-up vinculado a uma instância diferente do Browser.
  • java.awt.IllegalComponentStateException: o componente deve ser exibido na tela para determinar a sua localização quando move o JFrame com o componente invisível Swing BrowserView nele.
  • java.lang.IllegalArgumentException ao chamar BrowserView.setSize(0, 0).
  • java.lang.OutOfMemoryError na tentativa de registrar um request RPC que contém uma string de ~20MB.
  • O StartNavigationCallback.Params.url() retorna o endereço URL sem protocolo quando este deveria estar presente.
  • Falha nativa ao imprimir em console.log() ou alert() a propriedade registrada através do método JsObject.putProperty().
  • O arquivo PDF dentro de um IFRAME é aberto em tela cheia ao invés de abrir no frame de uma página Web.
  • java.lang.NullPointerException ao fechar o Browser logo após criá-lo.
  • O erro Failed to register a ServiceWorker numa página Web com JavaScript que funciona com Service Workers.
  • java.lang.NoSuchMethodError: com.teamdev.jxbrowser.ui.internal.rpc.Bitmap.getPixels()Lcom/google/protobuf/ByteString; ao mover o cursor sobre uma página web no JavaFX BrowserView.
  • Alguns sites, como https://evernote.com, não estão sendo carregados devido à impossibilidade de utilizar o IndexedDB devido a QuotaExceededError.

Gostaríamos de agradecer a todos os seus comentários sobre a utilização da versão 7.0 e a migração do JxBrowser 6.x para a versão 7! Muito obrigado!

Baixe o JxBrowser 7.1

Por favor, compartilhe seu e-mail conosco, e nós lhe enviaremos instruções para download.

Enviando...
Por favor, verifique sua caixa de entrada.

Não foi possível enviar o e-mail. Por favor, use o link direto para baixar o JxBrowser.

Se você é um cliente registrado, não precisa fazer nada para usar esta atualização.

Se você deseja avaliar o produto, precisa de uma licença de avaliação.

Obtenha Teste Gratuito de 30 dias