Posted on March 1, 2021

Good news everyone! A new version with great new features is available for download. In this version the Chromium engine has been upgraded to version 88. It enables support of macOS Big Sur. The long awaited Printing API has been introduced. Now you can programmatically print the web pages and PDFs.

We have made some updates to the public API. Please see the parts of the API which were removed from JxBrowser, and the alternatives we suggest to use instead.

What’s New

Chromium 88

Chromium has been updated to version 88.0.4324.182.

In this Chromium build, some of its features wrapped with the JxBrowser have been removed or changed, so this version of our library introduces several breaking changes in the public API.

Check out the migration guide for this version to see what API has been removed and what alternatives you should use instead.

macOS Big Sur

You can now run JxBrowser on macOS Big Sur on the Intel-based Macs. We plan to introduce support of the Apple Silicon M1 architecture in one of the next releases. Right now you can use JxBrowser in the Rosetta 2 emulation mode.

Printing API

Now you can print a web page or PDF document programmatically without displaying the Print Preview dialog.

With the new Printing API you can:

  • select a printer device;
  • provide the required print settings such as paper size, orientation, page ranges, etc.;
  • get notifications when printing is completed;
  • cancel printing;
  • save the currently loaded web page to a PDF document and more.

The following example demonstrates how to save the currently loaded web page as a PDF:

Browser browser = engine.newBrowser();
CountDownLatch latch = new CountDownLatch(1);

// Allow printing web pages programmatically
browser.set(PrintCallback.class, (params, tell) -> tell.print());
// When a web page is about to print, configure the print settings and proceed
browser.set(PrintHtmlCallback.class, (params, tell) -> {
    // Select PDF printer as the target device
    PdfPrinter<HtmlSettings> pdfPrinter = params.printers().pdfPrinter();
    // Access the print job to configure its settings and register events
    PrintJob<HtmlSettings> printJob = pdfPrinter.printJob();
    // Listen to the print completed event
    printJob.on(PrintCompleted.class, event -> latch.countDown());
    // Configure the required print settings including path to the target PDF file
    printJob.settings()
            .pdfFilePath(Paths.get("/Users/vladimir/Desktop/google.pdf"))
            .apply();
    // Notify the engine that we want to print using the given PDF printer
    tell.proceed(pdfPrinter);
});

// Load web page and wait until it's loaded completely
browser.navigation().loadUrlAndWait("https://google.com");
// Print the currently loaded web page
browser.mainFrame().ifPresent(Frame::print);
// Await until printing has been completed
if (latch.await(30, TimeUnit.SECONDS)) {
    throw new IllegalStateException("Failed to save web page as PDF within 30 sec");
}

Custom Schemes

The way of intercepting the requests is improved. To intercept URL requests with the custom jxb scheme, add the corresponding scheme and associate it with an intercept callback as shown in the example below:

EngineOptions.Builder optionsBuilder = EngineOptions.newBuilder(OFF_SCREEN);
optionsBuilder.addScheme(Scheme.of("jxb"), params -> {
    UrlRequestJob job = params.newUrlRequestJob(
            UrlRequestJob.Options.newBuilder(HttpStatus.OK)
                                 .addHttpHeader(HttpHeader.of("Content-Type", "text/html"))
                                 .build());
    job.write("<html><body>Hello!</body></html>".getBytes(UTF_8));
    job.complete();
    return Response.intercept(job);
});
Engine engine = Engine.newInstance(optionsBuilder.build());

Now, if you load jxb://anyhost/anypage.html, the URL requests will be intercepted, and the associated callback will be invoked. You will get the following output:

Custom Scheme

External Apps

Some applications installed in the operating system might be associated with a specific URI scheme. When user navigates to a URL with the scheme associated with the installed application, Chromium displays a dialog where the user can decide whether the link should be opened in the associated external application or not.

With this update, we introduced the callback that you can use to intercept such cases and display your own dialog to the end users or programmatically open the external application without prompting the user. For example:

browser.set(OpenExternalAppCallback.class, (params, tell) -> tell.open());

When you create a Swing, JavaFX, and SWT BrowserView instance, this callback is registered automatically, if it is not already registered, and displays a corresponding dialog:

Open External App Dialog

Improvements

  • Allow resizing Browser to 1x1. In the previous versions the minimum size was defined by the operating system.
  • Enable the multiple files download. Now, when you download multiple files, the StartDownloadCallback callback will be invoked for each file.
  • Handle the case when some system calls are interrupted with the EINTR signal on macOS and Linux. Which could lead to a native crash in the Chromium engine.
  • Allow configuring the render process unresponsive timeout via the --hung-render-delay-seconds=45 Chromium switch.
  • Allow empty username and password in AuthenticateCallback.

Fixed issues

  • The (SWT:12502): GLib-GObject-CRITICAL **: 14:58:41.997: g_object_set_data: assertion 'G_IS_OBJECT (object)' failed error when displaying a context menu in SWT BrowserView in the hardware accelerated rendering mode on Linux.
  • Incorrect key codes for numpad when receiving the keyboard events in the hardware accelerated rendering mode.
  • The IllegalStateException error when closing the Swing BrowserView popups in the off-screen rendering mode.
  • The BrowserView bounds not being updated when the component is embedded into a Swing container with the absolute layout and they have changed programmatically in the off-screen rendering mode.
  • Crash in the Main Chromium process when loading IFRAME with src="data:image/gif;base64,R0lGODlhE....
  • Crash in the Main Chromium process when multiple “Select Client SSL Certificate” dialogs are displayed, and a user selects a custom SSL certificate in one of them.
  • Angular apps not “seeing” some keyboard events in the off-screen rendering mode.
  • The Frame.children() method returning all nested children when it must return only immediate children.
  • The StartDownloadCallback.Action.cancel() action not cancelling download.

Get Free 30-day Trial
Download JxBrowser 7.13

Go Top