Browser

Este guia descreve como criar, utilizar e fechar o Browser.

Considere a leitura do guia Architecture para compreender melhor como foi concebida a arquitetura do JxBrowser, quais os principais componentes que fornece e como funciona.

Criando Browser

Para criar uma nova instância do Browser utilize o método Profile.newBrowser(). Por exemplo:

Browser browser = profile.newBrowser();
val browser = profile.newBrowser()

Se você utilizar o Engine.newBrowser() então o browser é criado com o perfil padrão.

Browser browser = engine.newBrowser();
val browser = engine.newBrowser()

Este método executa as seguintes ações:

  1. Cria uma nova instância do Browser.
  2. Carrega a página web about:blank e espera até que a página web esteja completamente carregada.

Fechando Browser

A instância Browser é executada num processo nativo separado que aloca memória e recursos do sistema a serem liberados. Assim, quando uma instância do Browser não é mais necessária, ela deve ser fechada através do método Browser.close() para liberar toda a memória alocada e os recursos do sistema. Por exemplo:

Browser browser = engine.newBrowser();
...
browser.close();
val browser = engine.newBrowser()
...
browser.close()

Uma tentativa de utilizar uma instância de Browser já fechada levará à IllegalStateException.

A instância Browser é fechada automaticamente nos seguintes casos:

  1. Quando o seu Engine é encerrado ou sofre uma falha inesperada.
  2. Quando Browser é um pop-up que é fechado a partir do JavaScript usando window.close().

Para receber notificações quando a instância Browser for fechada, utilize o evento BrowserClosed. Por exemplo:

browser.on(BrowserClosed.class, event -> {});
browser.on(BrowserClosed::class.java) { event -> }

Para verificar se o Browser está fechado, utilize o método isClosed():

boolean closed = browser.isClosed();
val closed = browser.isClosed

Tamanho do Browser

Por padrão, o tamanho do Browser é vazio. Se você deseja trabalhar com DOM ou Localizar texto numa página Web, configure o tamanho.

Para atualizar o tamanho do Browser por favor utilize resize(int width, int height). Por exemplo:

browser.resize(800, 600);
browser.resize(800, 600)

Este método notifica o Chromium que o tamanho do Browser foi alterado. O Chromium atualizará a disposição DOM da página Web carregada e repintará o seu conteúdo de forma assíncrona. Assim, pode demorar algum tempo até que a página Web seja repintada após o regresso do método.

Agente do usuário

Você pode substituir a string padrão Agente do usuário e configurar o Browser para usar uma string personalizada. Por exemplo:

browser.userAgent("<user-agent>");
browser.userAgent("<user-agent>")

Para obter a cadeia de caracteres do agente do usuário atual, utilize:

String userAgent = browser.userAgent();
val userAgent = browser.userAgent()

URL de depuração remota

Para obter o URL de depuração remota para uma página da Web carregada em uma determinada instância do Browser, use a seguinte abordagem:

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

Esta abordagem devolve um URL válido apenas se o Engine tiver sido configurado com a Remote Debugging Port.

Eventos do mouse e do teclado

O JxBrowser fornece uma funcionalidade que lhe permite interceptar os eventos do mouse e do teclado antes de serem enviados para a página Web, utilizando as seguintes chamadas de retorno:

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

O exemplo seguinte demonstra como suprimir a roda do mouse:

browser.set(MoveMouseWheelCallback.class, params -> Response.suppress());
browser.set(MoveMouseWheelCallback::class.java, MoveMouseWheelCallback { Response.suppress() })

Você pode utilizar estas chamadas de retorno para obter notificações sobre os eventos do mouse e do teclado, a fim de implementar as teclas de atalho na sua aplicação. Ou pode suprimir os atalhos predefinidos, como Ctrl+C no Windows e no Linux. Por exemplo:

browser.set(PressKeyCallback.class, params -> {
    KeyPressed event = params.event();
    boolean keyCodeC = event.keyCode() == KeyCode.KEY_CODE_C;
    boolean controlDown = event.keyModifiers().isControlDown();
    if (controlDown && keyCodeC) {
        return PressKeyCallback.Response.suppress();
    }
    return PressKeyCallback.Response.proceed();
});
browser.set(PressKeyCallback::class.java, PressKeyCallback { params ->
    val event = params.event()
    val keyCodeC = event.keyCode() == KeyCode.KEY_CODE_C
    val controlDown = event.keyModifiers().isControlDown
    if (controlDown && keyCodeC) {
        PressKeyCallback.Response.suppress()
    } else {
        PressKeyCallback.Response.proceed()
    }
})

Despachar eventos de teclado

É possível simular a digitação no elemento DOM focado do Browser.

char character = 'h';
KeyCode keyCode = KeyCode.KEY_CODE_H;
KeyPressed keyPressed = KeyPressed.newBuilder(keyCode)
        .keyChar(character)
        .build();
KeyTyped keyTyped = KeyTyped.newBuilder(keyCode)
        .keyChar(character)
        .build();
KeyReleased keyReleased = KeyReleased.newBuilder(keyCode)
        .build();

browser.dispatch(keyPressed);
browser.dispatch(keyTyped);
browser.dispatch(keyReleased);
val character = 'h'
val keyCode = KeyCode.KEY_CODE_H
val keyPressed = KeyPressed.newBuilder(keyCode)
    .keyChar(character)
    .build()
val keyTyped = KeyTyped.newBuilder(keyCode)
    .keyChar(character)
    .build()
val keyReleased = KeyReleased.newBuilder(keyCode)
    .build()
browser.dispatch(keyPressed)
browser.dispatch(keyTyped)
browser.dispatch(keyReleased)

Compartilhamento de Tela

Algumas páginas Web podem querer iniciar uma sessão de compartilhamento de tela. O Chromium tem a funcionalidade incorporada que permite compartilhar uma tela, uma janela de aplicação ou uma página Web. Na versão 7.20, a API da biblioteca foi estendida com uma funcionalidade que permite tratar programaticamente esses requests ou apenas apresentar a caixa de diálogo padrão do Chromium, onde o usuário pode selecionar a fonte de captura.

Para visualizar o diálogo padrão, utilize a seguinte abordagem:

browser.set(StartCaptureSessionCallback.class, (params, tell) ->
        tell.showSelectSourceDialog());
browser.set(StartCaptureSessionCallback::class.java,
    StartCaptureSessionCallback { params, tell -> tell.showSelectSourceDialog() }
)

WebRTC Diálogo Compartilhamento de Tela

Se não desejar apresentar a caixa de diálogo e quiser tratar os requests de forma programática, você sempre pode selecionar programaticamente a origem da captura e iniciar a sessão:

browser.set(StartCaptureSessionCallback.class, (params, tell) -> {
    CaptureSources sources = params.sources();
    CaptureSource screen = sources.screens().get(0);
    // Tell the browser instance to start a new capture session
    // with the given capture source (the first entire screen).
    tell.selectSource(screen, AudioCaptureMode.CAPTURE);
});
browser.set(StartCaptureSessionCallback::class.java,
    StartCaptureSessionCallback { params, tell ->
        val sources = params.sources()
        val screen = sources.screens().first()
        // Tell the browser instance to start a new capture session
        // with the given capture source (the first entire screen).
        tell.selectSource(screen, AudioCaptureMode.CAPTURE)
    }
)

Para interromper programaticamente a sessão, utilize o evento CaptureSessionStarted. Este evento é acionado quando é iniciada uma nova sessão de captura é iniciada. Pode obter uma referência à sessão de captura e interrompê-la em qualquer altura. O seguinte exemplo demonstra como parar a sessão de captura iniciada em 5 segundos:

browser.on(CaptureSessionStarted.class, event -> {
    CaptureSession captureSession = event.capture();
    new java.util.Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            // Stop the capture session in 5 seconds.
            captureSession.stop();
        }
    }, 5000);
});
browser.on(CaptureSessionStarted::class.java) { event ->
    val captureSession = event.capture()
    Timer().schedule(5000) {
        // Stop the capture session in 5 seconds.
        captureSession.stop()
    }
}

Notificações no ambiente de trabalho

As páginas Web seguras (HTTPS) podem apresentar notificações de ambiente de trabalho ao usuário final através da API de Notificações. A API foi concebida para ser compatível com os sistemas de notificação existentes, em diferentes plataformas.

As notificações não funcionarão se a página Web não for segura (HTTPS).

Para apresentar a notificação no ambiente de trabalho, é necessário conceder as permissões correspondentes:

engine.permissions().set(RequestPermissionCallback.class, (params, tell) -> {
    if (params.permissionType() == PermissionType.NOTIFICATIONS) {
        tell.grant();
    } else {
        tell.deny();
    }
});
engine.permissions().set(RequestPermissionCallback::class.java,
    RequestPermissionCallback { params, tell ->
        if (params.permissionType() == PermissionType.NOTIFICATIONS) {
            tell.grant()
        } else {
            tell.deny()
        }
    }
)

Algumas plataformas requerem uma configuração adicional para ativar as notificações no ambiente de trabalho. No macOS, quando o JxBrowser é iniciado pela primeira vez, é pedido ao usuário final que autorize o Chromium a mostrar notificações.

Notificações Chromium Prompt macOS

Em alternativa, o usuário final pode ativar/desativar as notificações para o Chromium no macOS Preferências do Sistema -> Centro de Notificações:

Centro de Notificações Chromium

DevTools

É possível mostrar/ocultar a janela DevTools programaticamente sem configurar a Porta de depuração remota:

browser.devTools().show();
browser.devTools().show()

O DevTools será apresentado numa janela separada:

Janela DevTools

Go Top