Ao utilizar extensões num navegador incorporado, você poderá querer empacotá-las e distribuí-las na sua aplicação e instalá-las de maneira silenciosa.
Neste tutorial, vou demonstrar como instalar programaticamente extensões a partir de arquivos CRX, mantê-las atualizadas e utilizá-las.
Além disso, mostrarei como obter um arquivos CRX de uma extensão publicada na Chrome Web Store.
Ao invés disso, você pretende dar aos usuários finais acesso à Chrome Web Store? Abordamos essa questão em Extensões do Chrome no JxBrowser.
Extensão
Para este tutorial, escolhi a extensão React DevTools. Não é útil para os usuários finais, mas serve o objetivo deste tutorial e é útil durante o desenvolvimento. Muitas bibliotecas JavaScript fornecem ferramentas de desenvolvimento como extensões, que, em última análise, fazem o mesmo: estendem o Chrome DevTools com funcionalidades específicas da biblioteca.
Com o JxBrowser, é possível construir uma interface de usuário com React, e ter o React DevTools dentro do JxBrowser é muito bom. Isto é especialmente verdadeiro se uma aplicação Web incorporada precisar do JxBrowser para comunicar-se com a aplicação anfitriã Java, portanto ela não pode ser executada num navegador autônomo.
Você pode criar esta extensão a partir do código-fonte ou obtê-la a partir da Chrome Web Store, como descrevemos em mais adiante no tutorial.
Criar uma aplicação
Vamos começar por criar uma aplicação simples. Será apresentado um navegador e um botão que abre o Chrome DevTools padrão.
import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.NORTH;
import static javax.swing.BoxLayout.X_AXIS;
import static javax.swing.SwingUtilities.invokeLater;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.file.Paths;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class CrxExtensions {
private static final Dimension BUTTON_SIZE = new Dimension(32, 32);
public static void main(String[] args) {
var options = EngineOptions
.newBuilder(RenderingMode.HARDWARE_ACCELERATED)
.userDataDir(Paths.get("<path to the directory>"))
.build();
var engine = Engine.newInstance(options);
var profile = engine.profiles().defaultProfile();
var browser = profile.newBrowser();
invokeLater(() -> {
var frame = new JFrame("Extensão CRX do Chrome no JxBrowser);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
engine.close();
}
});
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.add(BrowserView.newInstance(browser), CENTER);
frame.add(createExtensionBar(browser), NORTH);
frame.setSize(1280, 900);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
browser.navigation().loadUrl("https://react.dev/");
});
}
private static JPanel createExtensionBar(Browser browser) {
var extensionBar = new JPanel();
extensionBar.setLayout(new BoxLayout(extensionBar, X_AXIS));
var openDevTools = new JButton("Abra o DevTools");
openDevTools.addActionListener(e -> browser.devTools().show());
extensionBar.add(openDevTools);
return extensionBar;
}
}
Note que destaquei a linha que configura o diretório de dados do usuário. Este é o local onde o Chromium irá armazenar as extensões instaladas. Queremos que este diretório seja persistente para que o estado das extensões seja preservado entre inicializações.
Instalação de extensões
Para instalar a extensão, precisamos de um caminho para um arquivo CRX. Localizaremos as extensões disponíveis nos recursos e as passaremos ao JxBrowser para instalação:
private static final List<String> EXTENSION_FILES = List.of(
"react_dev_tools.crx"
);
public static void main(String[] args) {
...
var profile = engine.profiles().defaultProfile();
var browser = profile.newBrowser();
var extensions = profile.extensions();
for (var crx : EXTENSION_FILES) {
extensions.install(getResourcePath(crx));
}
invokeLater(() -> {
...
});
}
private static Path getResourcePath(String name) {
try {
var resource = CrxExtensions.class.getClassLoader()
.getResource(name);
if (resource != null) {
return Paths.get(resource.toURI());
} else {
throw new IllegalStateException(
"Couldn't find the bundled extension.");
}
} catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
}
No código acima, instalamos extensões em cada inicialização de uma aplicação. Isso garante que as extensões se mantenham atualizadas: o JxBrowser reinstalará uma extensão se um arquivo CRX tiver uma versão diferente.
Permissão para abrir novas abas
As extensões podem abrir novas abas com conteúdo Web arbitrário. Por exemplo, elas podem abrir a página de definições ou um formulário de autorização. No JxBrowser, as chamamos de pop-ups de extensão e as desativamos por padrão. Agora é uma boa hora para ativá-las:
var extensions = profile.extensions();
for (var crx : EXTENSION_FILES) {
extensions.install(getResourcePath(crx));
extension.set(OpenExtensionPopupCallback.class,
new DefaultOpenExtensionPopupCallback());
}
Interagir com extensões
A maioria das extensões adiciona um ícone à barra de ferramentas do Google Chrome. Este ícone é chamado por ação de extensão e, quando clicado, executa a lógica ou abre uma janela pop-up.
Vamos obter uma barra de extensão semelhante e adicionar ações de extensão à IU da aplicação:
import com.teamdev.jxbrowser.extensions.callback.OpenExtensionPopupCallback;
import com.teamdev.jxbrowser.view.swing.callback.DefaultOpenExtensionPopupCallback;
...
private static JPanel createExtensionBar(Browser browser) {
...
var extensions = browser.profile().extensions();
for (var extension : extensions.list()) {
extension.action(browser).ifPresent(action -> {
var button = new JButton();
extensionBar.add(button);
configureActionButton(button, action);
});
}
return extensionBar;
}
As ações de extensão podem ser alteradas a qualquer momento. Por exemplo, a ação do React DevTools fica desativada para páginas sem React. Outras extensões podem alterar o ícone ou um emblema em reação ao que está ocorrendo no navegador. Vamos acompanhar estas alterações e atualizar a IU:
import com.teamdev.jxbrowser.extensions.callback.OpenExtensionPopupCallback;
import com.teamdev.jxbrowser.extensions.event.ExtensionActionUpdated;
import com.teamdev.jxbrowser.view.swing.callback.DefaultOpenExtensionPopupCallback;
...
private static JPanel createExtensionBar(Browser browser) {
...
var extensions = browser.profile().extensions();
for (var extension : extensions.list()) {
extension.action(browser).ifPresent(action -> {
var button = new JButton();
extensionBar.add(button);
configureActionButton(button, action);
action.on(ExtensionActionUpdated.class, params -> {
invokeLater(() -> configureActionButton(button, action));
});
});
}
return extensionBar;
}
Agora, vamos implementar o método que apresenta o ícone e o nome da ação e configura o handler de cliques:
import com.teamdev.jxbrowser.extensions.ExtensionAction;
import com.teamdev.jxbrowser.view.swing.graphics.BitmapImage;
...
private static void configureActionButton(JButton button,
ExtensionAction action) {
var icon = BitmapImage.toToolkit(action.icon());
button.setPreferredSize(new Dimension(32, 32));
button.setText(action.tooltip());
button.setIcon(new ImageIcon(icon));
button.setEnabled(action.isEnabled());
if (button.getActionListeners().length == 0) {
button.addActionListener(e -> action.click());
}
}
Resultado
Neste vídeo, você verá a extensão React DevTools instalada e usada dentro do JxBrowser.
Obter arquivos CRX da Chrome Web Store
Muitas vezes, as extensões de código aberto publicam arquivos CRX no GitHub ou fornecem instruções sobre como você mesmo pode criá-los. Mas se nem o arquivo CRX nem as instruções estiverem disponíveis, você pode obter o arquivo na Chrome Web Store.
Para obter o arquivo de extensão da Chrome Web Store no JxBrowser,
registre InstallExtensionCallback
como mostrado abaixo, navegue para a Chrome
Web Store e instale a extensão manualmente.
Depois de instalar a extensão, a chamada de retorno copiará o arquivo CRX baixado para o diretório atual e o abrirá no explorador de arquivos.
import static java.awt.Desktop.getDesktop;
import static javax.swing.SwingUtilities.invokeLater;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.extensions.callback.InstallExtensionCallback;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.swing.JFrame;
public final class CrxFileFromChromeWebStore {
private static final String EXTENSION_URL =
"https://chromewebstore.google.com/detail/...";
public static void main(String[] args) {
var engine = Engine.newInstance(RenderingMode.HARDWARE_ACCELERATED);
var browser = engine.newBrowser();
var extensions = browser.profile().extensions();
extensions.set(InstallExtensionCallback.class, (params, tell) -> {
var name = params.extensionName();
var source = Paths.get(params.extensionCrxFile());
var target = Paths.get(name + ".crx").toAbsolutePath();
try {
Files.copy(source, target);
getDesktop().open(target.getParent().toFile());
} catch (IOException e) {
throw new RuntimeException(e);
}
tell.cancel();
});
browser.navigation().loadUrl(EXTENSION_URL);
invokeLater(() -> {
var view = BrowserView.newInstance(browser);
var frame = new JFrame("Chrome Web Store");
frame.add(view);
frame.setSize(1280, 900);
frame.setLocationRelativeTo(null);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
engine.close();
}
});
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setVisible(true);
});
}
}
Enviando…
Desculpe, o envio foi interrompido
Tente novamente. Se o problema persistir, contate-nos através do endereço info@teamdev.com.
A sua chave de avaliação pessoal de JxBrowser e o guia de início rápido chegarão à sua caixa de entrada de e-mail dentro de alguns minutos.
Código fonte
Você pode encontrar o código-fonte para este exemplo no repositório Exemplos JxBrowser.