For many years, SWT has had a built-in browser component. That is a simplistic component that relies on a web engine from the operating system. The component works well for displaying web pages and handling simple tasks. But it’s not sufficient for more advanced cases where you need to have consistent behavior across platforms, more control over the engine, user data isolation, et cetera.

That’s why many developers look for alternatives like JxBrowser. With a richer API and a single browser engine across platforms, JxBrowser is the most popular replacement for the built-in browser.

In this guide, we give you code examples for replacing every method in the SWT Browser API and links to the related JxBrowser documentation.

This guide is about how to migrate to JxBrowser. To learn more about why, checkout the JxBrowser or SWT Browser article where we explain the technical and architectural difference between the solutions.

JxBrowser 

JxBrowser is a commercial library that embeds Chromium into Java applications. It provides a much wider set of features compared to the built-in Browser, and web view component that natively supports SWT and Eclipse RCP applications.

On every operating system, the library works with the same version of Chromium that is supplied within the library. This ensures stable and consistent behavior and rendering on every operating system.

Being a commercial software, the library comes with unlimited hours of technical assistance, bug fixes, and the ability to request a new feature.

Comparison of API sizes between SWT browser and JxBrowser

The API surface of built-in browser and JxBrowser.

Dependencies for SWT projects 

Adding JxBrowser to the project is as simple as adding a couple of JAR files to the classpath. For example, an SWT application that runs on Windows will need the following files:

  • jxbrowser-8.6.0.jar. This file contains most of the JxBrowser API.
  • jxbrowser-swt-8.6.0.jar. This file contains the SWT component of JxBrowser.
  • jxbrowser-win64-8.6.0.jar. This file contains Chromium binaries for 64‑bit Windows.

You can download the necessary files from the JxBrowser 8.6.0 release notes.

If you’re using plain Maven or Gradle, you can add JxBrowser the usual way, by adding dependencies from our Maven repo.

Dependency for Eclipse RCP 

If you’re using Apache Tycho, you know that nothing comes easy in life. But we’ve got your back. In our tutorial on adding JxBrowser to Eclipse RCP applications, we cover:

  • How to use Maven to download JxBrowser dependencies at build time.
  • How to use fragments to distribute Chromium binaries for multiple platforms.

Migration 

Thread safety 

Like with the other UI components in SWT, you should only use the Browser in the UI thread.

JxBrowser is thread-safe: you can safely use JxBrowser objects in different threads. But be mindful about calling the JxBrowser API in the UI thread as many of its methods are synchronous. To avoid glitches in user experience, we generally don’t recommend calling JxBrowser in the UI thread.

Creating the browser 

In SWT, creating the browser is as simple as it gets. This code snippet adds the web view component to the parent and loads a web page:

var browser = new Browser(shell, SWT.NONE);
browser.setUrl("https://www.example.com");
...
// Dispose the browser when it's not needed anymore.
browser.dispose();

In JxBrowser, the similar logic looks like this:

var engine = Engine.newInstance(HARDWARE_ACCELERATED);
var browser = engine.newBrowser();

var view = BrowserView.newInstance(shell, browser);
browser.navigation().loadUrl("https://example.com");
...
// Close the browser when it's not needed anymore.
browser.close();
// Or close the engine. More on the difference in a moment.
engine.close();

As you see, there is more code with JxBrowser, but there is also more control.

Modern browsers have complex process models, security features, and different ways to render web content. However, the SWT Browser API doesn’t reflect this complexity because it wasn’t designed for this. Its idea is to be simple and engine-agnostic.

JxBrowser, however, is based solely on the Chromium engine and gives you nuanced control over it. Let’s break down the previous code snippet and see what this control includes.

We start by creating an Engine, which starts the main Chromium process. You can think of it as opening Google Chrome on your computer:

var engine = Engine.newInstance(HARDWARE_ACCELERATED);

Then, we create a new browser. You can think of it as a single tab in Google Chrome. As with the tabs, you can create as many Browser instances as you need:

var browser = engine.newBrowser();

The created browser object is fully functional. You can’t see it yet, but you can load web pages and fetch information from it:

browser.navigation().loadUrl("https://example.com");

And finally, you can show the browser in the UI by adding an SWT component, BrowserView:

var view = BrowserView.newInstance(shell, browser);

We describe this and other architectural details in great detail in our documentation.

Closing the browser 

In SWT, you should dispose of the browser when you no longer need it:

browser.dispose();

In JxBrowser, you need to close the browser too, but you have a choice: either a single “tab” or the engine with all created browsers at once:

// You can close a single "tab".
browser.close()

// Or you can close the whole engine, which will automatically
// close all the browsers created within it.
engine.close();

In SWT, you can receive a notification that the browser is closed. It comes only when a JavaScript closes the page by calling window.close():

browser.addCloseWindowListener(event -> {
    // The browser has been closed by JavaScript.
});

In JxBrowser, the equivalent event will come regardless of how the browser was closed:

browser.on(BrowserClosed.class, event -> {
    // The browser has been closed by JavaScript, 
    // or by calling browser.close(), or engine.close().            
});

Most of the navigation methods in SWT Browser have a one-to-one counterpart in JxBrowser:

SWT
JxBrowser
browser.setUrl("https://example.com");
var url = browser.getUrl();

browser.reload();
browser.stop();
browser.back();
browser.forward();
var canGoBack = browser.isBackEnabled();
var canGoForward = browser.isForwardEnabled();
var navigation = browser.navigation();
navigation.loadUrl("https://example.com");
var url = browser.url();

navigation.reload();
navigation.stop();
navigation.goBack();
navigation.goForward();
var canGoBack = navigation.canGoBack();
var canGoForward = navigation.canGoForward();

You can load a URL with a POST payload and additional headers in both browsers. In SWT, you specify data and headers as raw strings. In JxBrowser, we have a higher-level API:

SWT
JxBrowser
var url = "https://example.com/login";
var postData = "username=user&password=secret";
var headers = new String[] {
        "Content-Type: application/x-www-form-urlencoded",
        "Authorization: Bearer xyz1234"
};
browser.setUrl(url, postData, headers);
var url = "https://example.com/login";
var formData = FormData.newBuilder()
        .addPair(Pair.of("username", "user"))
        .addPair(Pair.of("password", "secret"))
        .build();
var header = HttpHeader.of("Authorization", "Bearer xyz1234");
var params = LoadUrlParams.newBuilder(url)
        .addExtraHeader(header)
        .uploadData(formData)
        .build();
navigation.loadUrl(params);

Location listener 

In SWT, you register a LocationListener to monitor when the location loaded in the browser changes. In JxBrowser, you do this by subscribing to the NavigationFinished event:

SWT
JxBrowser
browser.addLocationListener(new LocationAdapter() {
    @Override
    public void changed(LocationEvent event) {
        var url = event.location;
        var isMainFrame = event.top;
    }
});
navigation.on(NavigationFinished.class, event -> {
    var url = event.url();
    var frame = event.frame();
    var hasCommitted = event.hasCommitted();
    var isSameDocument = event.isSameDocument();
    var isErrorPage = event.isErrorPage();
    if (isErrorPage) {
        var error = event.error();
    }
});

There are nine granular navigation events in JxBrowser. Check the complete list.

In SWT, the LocationListener is also used to prevent unwanted navigation. In JxBrowser, you can achieve this by registering StartNavigationCallback:

SWT
JxBrowser
browser.addLocationListener(new LocationAdapter() {
    @Override
    public void changing(LocationEvent event) {
        var url = event.location;
        if (...) {
            event.doit = true;
        } else {
            event.doit = false;
        }
    }
});
navigation.set(StartNavigationCallback.class, params -> {
    var url = params.url();
    var isRedirect = params.isRedirect();
    var isMainFrame = params.isMainFrame();
    if (...) {
        return StartNavigationCallback.Response.start();
    } else {
        return StartNavigationCallback.Response.ignore();
    }
});

Progress listener 

In SWT, you get events about the page loading progress, and, in particular, about the loading completion.

In JxBrowser, you can’t check the loading progress, but you can detect when the page is fully loaded, and you can use it:

SWT
JxBrowser
browser.addProgressListener(new ProgressAdapter() {
    @Override
    public void completed(ProgressEvent event) {
        // A location has been completely loaded.
    }
});
// Check if the HTML document has been fully loaded.
browser.navigation().on(FrameDocumentLoadFinished.class, event -> {
    var frame = event.frame();
    var isMainFrame = frame.isMain();
    frame.document().ifPresent(document -> {
        var element = document.documentElement();
    });
});

JxBrowser doesn’t provide an API equivalent to the ProgressLister.changed(ProgressEvent) method.

Calling JavaScript from Java 

In SWT, you execute the JavaScript code in the current document by calling the execute() and evaluate() methods. If possible, the latter automatically converts the return value to the Java primitive type and String. Both are synchronous:

boolean isSuccessful = browser.execute("document.documentElement");
String zipCode = browser.evaluate("getZipCode()");

In JxBrowser, you can execute JavaScript in the context of any frame, and JxBrowser will convert the return value to one of 11 available types:

Element element = frame.executeJavaScript("document.documentElement");
String zipCode = frame.executeJavaScript("getZipCode()");

// There is an asynchronous version too:
frame.executeJavaScript("longOperation()", (result) -> {
    // The result of the non-blocking JavaScript call.
});

In SWT, you can turn JavaScript on and off. In JxBrowser, we have drop-in replacements for these methods:

SWT
JxBrowser
browser.setJavascriptEnabled(false);
var isEnabled = browsser.getJavascriptEnabled();
var settings = browser.settings();
settings.enableJavaScript();
settings.disableJavaScript();

var isEnabled = settings.isJavaScriptEnabled();

Calling Java from JavaScript 

In SWT, you need to register BrowserFunction to call Java code from JavaScript. This function will be accessible in all web pages until it’s disposed of. The types of arguments and the return values will be automatically converted to a corresponding Java primitive type and String.

// This function will be available in the top frame and two other frames
// as `sayHello()`.
var function = new BrowserFunction(br, "sayHello") {
    @Override
    public Object function(Object[] args) {
        return "Hello from Java!";
    }
};
...
function.dispose();

In JxBrowser, you can inject arbitrary Java objects into JavaScript, but only when the frame is ready. You don’t need to close injected objects, as this will happen automatically when the page is reloaded.

// This callback is invoked when the document has been created, 
// and before the page executes its own scripts.
browser.set(InjectJsCallback.class, params -> {
    var frame = params.frame();
    JsObject window = frame.executeJavaScript("window");
    window.putProperty("sayHello", (JsFunctionCallback) args -> {
        return "Hello from Java!";
    });
    return InjectJsCallback.Response.proceed();
});

Loading HTML 

In both browsers, you can load a simple HTML from memory:

SWT
JxBrowser
browser.setText("<html>Hello</html>");
frame.loadHtml("<html>Hello</html>");

In JxBrowser, the loadHtml() method works by loading a data URL from the given HTML, limiting the page size to ~2 MB.

To exceed this limit and cover other advanced cases, check our guide on loading HTML and local resources.

Fetching page content 

In SWT, you can use the getText() of the browser to read the HTML of the page. In JxBrowser, you will need to get the inner or outer HTML of the document:

SWT
JxBrowser
var html = browser.getText();
frame.document().flatMap(Document::documentElement).ifPresent(element -> {
    var innerHtml = element.innerHtml();
    var outerHtml = element.outerHtml();
});

Status line and title 

In both browsers, you can receive notifications when the status line changes:

SWT
JxBrowser
browser.addStatusTextListener(event -> {
    var newStatus = event.text;
});
browser.on(StatusChanged.class, event -> {
    var newStatus = event.statusText();
});

You can track the page title changes similarly:

SWT
JxBrowser
browser.addTitleListener(event -> {
    var newTitle = event.title;
});
browser.on(TitleChanged.class, event -> {
    var newTitle = event.title();
});

Cookies 

You can read existing cookies in SWT using the getCookie() method. In JxBrowser, you can read the cookies using the CookieStore:

SWT
JxBrowser
String cookie = Browser.getCookie("auth_token", "https://example.com");
var cookieStore = browser.profile().cookieStore();
for (Cookie cookie : cookieStore.cookies("https://example.com")) {
    String domain = cookie.domain();
    Timestamp expiration = cookie.expirationTime();
    ...
}

To create a new cookie, use setCookie() in SWT and CookieStore.set() in JxBrowser:

SWT
JxBrowser
Browser.setCookie("auth_token=abc123; Path=/;", "https://example.com");
var cookieStore = browser.profile().cookieStore();
var cookie = Cookie.newBuilder("example.com")
        .name("auth_token")
        .value("abc123")
        .path("/")
        .build();
cookieStore.set(cookie);

Similarly, you can clean up the cookies:

SWT
JxBrowser
Browser.clearSessions();
// Delete a specific cookie.
cookieStore.delete(cookie);

// Delete all the cookies.
cookieStore.deleteAll();

Authentication 

In SWT, you register an AuthenticationListener to handle server requests for authentication automatically. In JxBrowser, you will need to use AuthenticateCallback:

SWT
JxBrowser
browser.addAuthenticationListener(event -> {
    var url = event.location;
    if (...) {
        event.user = "username";
        event.password = "password";
        event.doit = true;
    } else {
        event.doit = false;
    }
});
var network = browser.profile().network();
network.set(AuthenticateCallback.class, (params, action) -> {
    var url = params.url();
    var proxy = params.isProxy();
    var scheme = params.scheme();
    var hostPort = params.hostPort();
    if (...) {
        action.authenticate("username", "password");
    } else {
        action.cancel();
    }
});

Popups 

When a web page wants to open a new pop-up window, SWT sends you an event. Depending on the event, the OS will create the new browser window for you, or let your application create it:

browser.addOpenWindowListener(event -> {
    if (event.required) {
        // Your application is required to create a window for the pop-up.
        event.browser = new Browser(shell, SWT.NONE);
    } else {
        // Operating system will create the pop-up.
    }
});

JxBrowser automatically creates the browser object for the new pop-up. It’s up to you to show it in the user interface or use it off-screen. By default, JxBrowser will open a pop-up in a new Shell:

// First, allow creating a pop-up browser.
browser.set(CreatePopupCallback.class, e -> {
    var url = e.targetUrl();
    var name = e.targetName();
    if (...) {
        return CreatePopupCallback.Response.create(); 
    } else {
        return CreatePopupCallback.Response.suppress();
    }
});

browser.set(OpenPopupCallback.class, e -> {
    var popupBrowser = e.popupBrowser();
    var bounds = e.initialBounds();
    var scaleFactor = e.scaleFactor();
    // You can embed the `popupBrowser` into the UI here.
    return OpenPopupCallback.Response.proceed();
});

JxBrowser allows you to programmatically handle JavaScript, file, color picker, and other dialogs. Learn how in the guide on dialogs.

Conclusion 

Migrating from SWT’s browser to JxBrowser is essentially a matter of translating API calls, as most methods have direct equivalents in JxBrowser.

In this guide, we provided the drop-in replacements from JxBrowser API for every SWT Browser, covering the entire Browser API.

While the real-world migration may be hard, we believe it should not be. This guide is a good starting point to learn how JxBrowser can replace the SWT browser in your application.

Spinner

Sending…

Sorry, the sending was interrupted

Please try again. If the issue persists, contact us at info@teamdev.com.

Read and agree to the terms to continue.

Your personal JxBrowser trial key and quick start guide will arrive in your Email Inbox in a few minutes.