New version is available You are viewing the documentation for JxBrowser 6 which is not supported since December 2019. Go to the current documentation.
List icon Contents

This guide describes how to create, use, and dispose Browser.

Creating Browser

Each Browser instance must be initialized with BrowserContext. The BrowserContext instance holds the context needed for a browsing session and provides path to the directory where Chromium stores cookies, cache data files, etc.

The following code creates a new Browser instance initialized with default context:

Browser browser = new Browser();

The code above equals to:

Browser browser = new Browser(BrowserContext.defaultContext());

The BrowserContext.defaultContext() method returns the default BrowserContext that is configured to store Chromium data files such as cookies, cache, etc. in user’s temp directory on macOS and Linux and AppData\Local\JxBrowser on Windows. You can get path to the directory where data files are stored using the BrowserPreferences.getDefaultDataDir() method.

Two Browser instances with the same BrowserContext instances will use the same user data directory. As result they will share cookies and cache files. For example:

BrowserContext context = new BrowserContext(
    new BrowserContextParams("C:\\my-data1"));
Browser browser1 = new Browser(context);
Browser browser2 = new Browser(context);

To create the independent Browser instances that don’t share cookies and cache data, you must initialize each Browser instance with a different BrowserContext instance configured to use a different data directory. For example:

BrowserContext context1 = new BrowserContext(
    new BrowserContextParams("C:\\my-data1"));
Browser browser1 = new Browser(context1);

BrowserContext context2 = new BrowserContext(
    new BrowserContextParams("C:\\my-data2"));
Browser browser2 = new Browser(context2);

To get BrowserContext of the Browser instance you can use the browser.getContext() method.

User Data

By default, JxBrowser stores user data in a folder with the path that usually looks like %LocalAppData%\JxBrowser\browsercore-<version>\data on Windows. On Linux and macOS user’s temp directory is used.

To change the default behavior and customize the path to the user data directory use the following approach:

BrowserContext context = new BrowserContext(
        new BrowserContextParams("Users/Me/JxBrowser/Data"));
Browser browser = new Browser(context);

In case of using a custom user data directory, it is completely possible to upgrade JxBrowser from an older version to a newer one, however, in case of a downgrade, the user data folder may appear incompatible. Such functionality is not supported, so you should avoid such situations when you downgrade JxBrowser and tell it to use the user data directory created by a newer version.

Important to Know

Using several BrowserContext instances configured to use same data directory in a single or multiple Java application instances is forbidden. In this case Browser constructor will throw the BrowserException exception to prevent unexpected behavior or errors such as native crash in the Chromium engine.

If it’s possible to launch more than one instance of your Java application at the same time on the same machine, then please don’t create Browser instance in your application using default constructor. In this case both Browser instances running in different Java applications at the same time will be configured to use the same Chromium data directory which is forbidden. The BrowserException exception will be thrown when the second Java application instance will try to create a new Browser instance.

To solve this issue please make sure that only one instance of your Java application can be used at the same time. If you would like to let end users to run multiple instances of your Java application at the same time, then please make sure that each instance of your Java application configures JxBrowser library to use unique Chromium data directory.

Multiple instances of Java application

// App instance #1
Browser browser = new Browser(); // OK

// App instance #2
Browser browser = new Browser(); // <= BrowserException
// App instance #1
BrowserContext context = new BrowserContext(
    new BrowserContextParams("C:\\data"));
Browser browser = new Browser(context); // OK

// App instance #2
BrowserContext context = new BrowserContext(
    new BrowserContextParams("C:\\data"));
Browser browser = new Browser(context); // <= BrowserException
// App instance #1
BrowserContext context = new BrowserContext(
    new BrowserContextParams("C:\\data1"));
Browser browser = new Browser(context); // OK

// App instance #2
BrowserContext context = new BrowserContext(
    new BrowserContextParams("C:\\data2"));
Browser browser = new Browser(context); // OK

A single Java application instance

Browser browserOne = new Browser(); // OK

String dataDir = BrowserContext.defaultContext().getDataDir();
BrowserContext context = new BrowserContext(
    new BrowserContextParams(dataDir));
Browser browserTwo = new Browser(context); // <= BrowserException
BrowserContext context1 = new BrowserContext(
    new BrowserContextParams("C:\\shared-data"));
Browser browser1 = new Browser(context1); // OK

BrowserContext context2 = new BrowserContext(
    new BrowserContextParams("C:\\shared-data"));
Browser browser2 = new Browser(context2); // <= BrowserException
BrowserContext context1 = new BrowserContext(
    new BrowserContextParams("C:\\my-data1"));
Browser browser1 = new Browser(context1); // OK

BrowserContext context2 = new BrowserContext(
    new BrowserContextParams("C:\\my-data2"));
Browser browser2 = new Browser(context2); // OK
Browser browser1 = new Browser(); // OK
Browser browser2 = new Browser(); // OK
Browser browser3 = new Browser(BrowserContext.defaultContext()); // OK

Limitations

At the moment there is a limit on how many BrowserContext instances can be held by one Chromium process. Holding more than that limit can lead to unexpected crashes in Chromium process. The limit is around 50 instances of BrowserContext per process and varies depending on the operating system.

On Linux and MacOS Chromium does not release its file descriptors. That behavior leads to the file descriptors leak and after some point, it becomes impossible to create new BrowserContext instances because of hitting the hard limit of the file descriptors.

On Windows, new BrowserContext instances are acquiring thread-local storages from Chromium pool of thread-local storages and never releases them, which may lead to Chromium process crashes when trying to create new BrowserContext.

To avoid issues with multiple BrowserContext instances, the following approaches can be used:

  1. Multiple Browser instances can use the same BrowserContext. If you do not need to create the Browser instances that don’t share cookies, caches and other user data, you can use a single BrowserContext instance. For example:
BrowserContext browserContext = new BrowserContext(new BrowserContextParams(
        new File("user_data_dir").getAbsolutePath()));
Browser browserOne = new Browser(browserContext);
Browser browserTwo = new Browser(browserContext);
  1. In case you need to use multiple Browser instances that don’t share cookies and other user data and you have to create multiple BrowserContext instances, we recommend that you dispose all Browser instances periodically to destroy all created BrowserContext instances, and terminate Chromium native process to release file descriptors and other resources. After that, you can continue creating the new BrowserContext and Browser instances.

Creating Incognito Browser

By default, each Browser instance stores all user data such as history, cookies, cache on disk. Since 6.8 you can configure Browser instance to store all user data in memory (Chromium’s “Incognito” mode), so that all user data will be cleared once your Java application is terminated.

The following example demonstrates how to configure Browser instance to work in “Incognito” mode and store all user data in memory:

import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserContext;
import com.teamdev.jxbrowser.chromium.BrowserContextParams;
import com.teamdev.jxbrowser.chromium.StorageType;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;

import javax.swing.*;
import java.awt.*;

/**
 * This sample demonstrates how to configure Browser instance
 * to use in-memory data storage.
 */
public class IncognitoModeSample {
    public static void main(String[] args) {
        // No user data will be stored to the "user-data-dir" folder.
        // This directory will be used for internal purposes
        // on macOS and Linux platforms.
        BrowserContextParams params = new BrowserContextParams("user-data-dir");
        params.setStorageType(StorageType.MEMORY);

        BrowserContext browserContext = new BrowserContext(params);
        Browser browser = new Browser(browserContext);
        BrowserView view = new BrowserView(browser);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(view, BorderLayout.CENTER);
        frame.setSize(700, 500);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        browser.loadURL("http://google.com");
    }
}

Disposing Browser

When you don’t need to use a Browser instance you must dispose it using the Browser.dispose() method.

For example:

browser.dispose();

Accessing disposed instance

Once you dispose a Browser instance, you cannot use it anymore. If you try to access already disposed Browser instance the IllegalStateException exception will be thrown. For example:

browser.dispose();
browser.getDocument(); // IllegalStateException will be thrown

To check if the Browser instance is disposed or not, you can use the Browser.isDisposed() method.

Dispose Events

Each Browser instance can be also disposed from JavaScript via the window.close() function. In this case you might be interested in receiving notification when a Browser instance is disposed. To get such notifications, you can use DisposeListener. For example:

browser.addDisposeListener(new DisposeListener<Browser>() {
    @Override
    public void onDisposed(DisposeEvent<Browser> event) {
        // B<span class="fr-marker" data-id="0" data-type="false" style="display: none; line-height: 0;"></span><span class="fr-marker" data-id="0" data-type="true" style="display: none; line-height: 0;"></span>rowser is disposed
    }
});

When you dispose a Browser instance manually via the Browser.dispose() method, the Dispose event will also be fired.

Restoring Browser

You can restore a Browser instance after an unexpected crash in Chromium render process using the following approach:

import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.events.RenderAdapter;
import com.teamdev.jxbrowser.chromium.events.RenderEvent;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;

import javax.swing.*;
import java.awt.*;

/**
 * This sample demonstrates how to restore Browser instance after its
 * native process unexpectedly terminated. In general to restore a Browse instance you just need to load the same or another URL.
 */
public class RestoreBrowserSample {
    public static void main(String[] args) {
        Browser browser = new Browser();
        BrowserView browserView = new BrowserView(browser);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(browserView, BorderLayout.CENTER);
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        browser.addRenderListener(new RenderAdapter() {
            @Override
            public void onRenderGone(RenderEvent event) {
                Browser browser = event.getBrowser();
                // Restore Browser instance by loading the same URL
                browser.loadURL(browser.getURL());
            }
        });

        browser.loadURL("http://www.google.com");

        System.out.println("Run 'Task Manager' app and kill the 'jxbrowser-chromium.exe' " +
                "process with the '--type=renderer' command line argument.");
    }
}

Preferences

JxBrowser provides functionality that allows you to enable or disable various features, such as images, JavaScript, videos, etc., for each Browser instance. Use BrowserPreferences class to work with Browser features/preferences. To modify some features/preferences you must obtain BrowserPreferences instance using the Browser.getPreferences() method, modify preferences, and save them using the Browser.setPreferences() method.

The following sample demonstrates how to disable loading images and JavaScript execution on www.google.com web page:

Browser browser = new Browser();

// Gets the current Browser's preferences
BrowserPreferences preferences = browser.getPreferences();
preferences.setImagesEnabled(false);
preferences.setJavaScriptEnabled(false);

// Updates Browser's preferences
browser.setPreferences(preferences);

// Images and JavaScript will be disabled
browser.loadURL("http://www.google.com/");

Forwarding Mouse Events

You can programmatically forward mouse events to the currently loaded web page. The mouse events will be send to the loaded web page as if they were sent due to user actions.

The following example demonstrates how to use this functionality:

import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyModifiers;
import com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyModifiersBuilder;
import com.teamdev.jxbrowser.chromium.BrowserMouseEvent.BrowserMouseEventBuilder;
import com.teamdev.jxbrowser.chromium.BrowserMouseEvent.MouseButtonType;
import com.teamdev.jxbrowser.chromium.Callback;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import static com.teamdev.jxbrowser.chromium.BrowserMouseEvent.MouseButtonType.*;
import static com.teamdev.jxbrowser.chromium.BrowserMouseEvent.MouseEventType.*;
import static com.teamdev.jxbrowser.chromium.BrowserMouseEvent.MouseScrollType.WHEEL_BLOCK_SCROLL;

/**
 * This sample demonstrates how to create and forward mouse events
 * containing scroll parameters, modifiers, and button options to Chromium engine.
 */
public class ForwardMouseEventsSample {
    public static void main(String[] args) {
        final Browser browser = new Browser();
        BrowserView view = new BrowserView(browser);

        JButton scrollDown = new JButton("Scroll Down");
        scrollDown.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                forwardMouseScrollEvent(browser, -1, 11, 62);
            }
        });
        JButton scrollUp = new JButton("Scroll Up");
        scrollUp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                forwardMouseScrollEvent(browser, 1, 11, 62);
            }
        });
        JButton clickMe = new JButton("Click");
        clickMe.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                forwardMouseClickEvent(browser, PRIMARY, 11, 12, 629, 373);
            }
        });

        JPanel actionPane = new JPanel();
        actionPane.add(scrollDown);
        actionPane.add(scrollUp);
        actionPane.add(clickMe);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(actionPane, BorderLayout.SOUTH);
        frame.add(view, BorderLayout.CENTER);
        frame.setSize(600, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        Browser.invokeAndWaitFinishLoadingMainFrame(browser, new Callback<Browser>() {
            @Override
            public void invoke(Browser value) {
                browser.loadHTML("<div>" +
                        "<button onclick=\"alert('Mouse has been clicked.');\">Click Me</button></div>" +
                        "<textarea autofocus rows='10' cols='30'>" +
                        "Line 1 \n Line 2 \n Line 3 \n Line 4 \n Line 5 \n " +
                        "Line 6 \n Line 7 \n Line 8 \n Line 9 \n Line 10 \n " +
                        "Line 11 \n Line 11 \n Line 12 \n Line 13 \n Line 14 \n " +
                        "Line 15 \n Line 16 \n Line 17 \n Line 18 \n </textarea>");
            }
        });

    }

    private static void forwardMousePressEvent(Browser browser,
                                               MouseButtonType buttonType,
                                               int x,
                                               int y,
                                               int globalX,
                                               int globalY) {
        BrowserMouseEventBuilder builder = new BrowserMouseEventBuilder();
        builder.setEventType(MOUSE_PRESSED)
                .setButtonType(buttonType)
                .setX(x)
                .setY(y)
                .setGlobalX(globalX)
                .setGlobalY(globalY)
                .setClickCount(1)
                .setModifiers(new KeyModifiersBuilder().mouseButton().build());
        browser.forwardMouseEvent(builder.build());
    }

    private static void forwardMouseReleaseEvent(Browser browser,
                                                 MouseButtonType buttonType,
                                                 int x,
                                                 int y,
                                                 int globalX,
                                                 int globalY) {
        BrowserMouseEventBuilder builder = new BrowserMouseEventBuilder();
        builder.setEventType(MOUSE_RELEASED)
                .setButtonType(buttonType)
                .setX(x)
                .setY(y)
                .setGlobalX(globalX)
                .setGlobalY(globalY)
                .setClickCount(1)
                .setModifiers(KeyModifiers.NO_MODIFIERS);
        browser.forwardMouseEvent(builder.build());
    }

    private static void forwardMouseClickEvent(Browser browser,
                                               MouseButtonType buttonType,
                                               int x,
                                               int y,
                                               int globalX,
                                               int globalY) {
        forwardMousePressEvent(browser, buttonType, x, y, globalX, globalY);
        forwardMouseReleaseEvent(browser, buttonType, x, y, globalX, globalY);
    }

    private static void forwardMouseScrollEvent(Browser browser,
                                                int unitsToScroll,
                                                int x,
                                                int y) {
        BrowserMouseEventBuilder builder = new BrowserMouseEventBuilder();
        builder.setEventType(MOUSE_WHEEL)
                .setX(x)
                .setY(y)
                .setGlobalX(0)
                .setGlobalY(0)
                .setScrollBarPixelsPerLine(25)
                .setScrollType(WHEEL_BLOCK_SCROLL)
                .setUnitsToScroll(unitsToScroll);
        browser.forwardMouseEvent(builder.build());
    }
}

Forwarding Keyboard Events

JxBrowser API provides functionality that allows forwarding keyboard events to the currently focused element on the currently loaded web page.

This functionality is useful when you need to programmatically send keyboard events to a web page. For example, if you develop a Web-base Kiosk Java application that should run on a terminal/PC with a touch screen monitor and no physical keyboard, you might want to display your own screen keyboard. The end user will use this screen keyboard to type on the loaded web page. In this case the screen keyboard can programmatically forward the appropriate key events to the currently loaded web page using this functionality.

The following example demonstrates how to programmatically send keyboard events to type text and press Enter in the currently focused textarea on the loaded web page:

import com.teamdev.jxbrowser.chromium.*;
import com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyCode;
import com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyModifiers;
import com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyModifiersBuilder;
import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent;
import com.teamdev.jxbrowser.chromium.events.LoadAdapter;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;

import javax.swing.*;
import java.awt.*;

import static com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyCode.*;
import static com.teamdev.jxbrowser.chromium.BrowserKeyEvent.KeyEventType.*;

/**
 * This sample demonstrates how to create and forward keyboard events
 * containing characters, modifiers, and control keys to Chromium engine.
 */
public class ForwardKeyEventsSample {
    public static void main(String[] args) {
        Browser browser = new Browser();
        BrowserView view = new BrowserView(browser);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(view, BorderLayout.CENTER);
        frame.setSize(700, 500);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        browser.addLoadListener(new LoadAdapter() {
            @Override
            public void onFinishLoadingFrame(FinishLoadingEvent event) {
                if (event.isMainFrame()) {
                    Browser browser = event.getBrowser();

                    // Sending 'Hello' to the currently focused textarea
                    forwardKeyEvent(browser, VK_H, 'H');
                    forwardKeyEvent(browser, VK_E, 'e');
                    forwardKeyEvent(browser, VK_L, 'l');
                    forwardKeyEvent(browser, VK_L, 'l');
                    forwardKeyEvent(browser, VK_O, 'o');

                    // Sending 'Enter' to insert a line break
                    forwardKeyEvent(browser, VK_RETURN);

                    // Selecting text in the textarea using Ctrl+A shortcut
                    forwardKeyEvent(browser, VK_A,
                            new KeyModifiersBuilder().ctrlDown().build());
                }
            }
        });

        browser.loadHTML("<textarea autofocus rows='10' cols='30'></textarea>");
    }

    private static void forwardKeyEvent(Browser browser, KeyCode code, char character) {
        browser.forwardKeyEvent(new BrowserKeyEvent(PRESSED, code, character));
        browser.forwardKeyEvent(new BrowserKeyEvent(TYPED, code, character));
        browser.forwardKeyEvent(new BrowserKeyEvent(RELEASED, code, character));
    }

    private static void forwardKeyEvent(Browser browser, KeyCode code) {
        browser.forwardKeyEvent(new BrowserKeyEvent(PRESSED, code));
        browser.forwardKeyEvent(new BrowserKeyEvent(TYPED, code));
        browser.forwardKeyEvent(new BrowserKeyEvent(RELEASED, code));
    }

    private static void forwardKeyEvent(Browser browser, KeyCode code, KeyModifiers modifiers) {
        browser.forwardKeyEvent(new BrowserKeyEvent(PRESSED, code, modifiers));
        browser.forwardKeyEvent(new BrowserKeyEvent(TYPED, code, modifiers));
        browser.forwardKeyEvent(new BrowserKeyEvent(RELEASED, code, modifiers));
    }
}

Editor Commands

JxBrowser provides functionality that allows you to execute commands such as “Cut”, “Copy”, “Paste”, “Undo”, “Redo”, “Insert Text”, etc. on the loaded web page. JxBrowser supports two types of commands: simple commands (e.g. “Copy”, “Cut”, “Paste”) and parametrized commands (“InsertText”, “FindString”, etc.).

Most of commands can be executed only in a WYSIWYG editor (e.g. “FontSize”, “ForegroundColor”, “Bold”, etc.), HTML text filed or text area (“InsertText”, “Cut”, “Delete”, etc.).

To execute command you need to use the Browser.executeCommand(EditorCommand command) method to execute simple commands or the Browser.executeCommand(EditorCommand command, String value) method to execute parameterised command.

browser.executeCommand(EditorCommand.SELECT_ALL);
browser.executeCommand(EditorCommand.COPY);
browser.executeCommand(EditorCommand.CUT);
browser.executeCommand(EditorCommand.PASTE);
browser.executeCommand(EditorCommand.INSERT_TEXT, "Text");

Render Process Events

Each Browser instance is running in a separate native process where the web page is rendered. Sometimes this process can exit unexpectedly because of the crash in plugin. To receive notifications about unexpected render process termination you can use RenderListener. When you receive notification about render process termination you can display a “sad” icon like Google Chrome does, for example, to inform the user that this particular Browser component has crashed.

browser.addRenderListener(new RenderAdapter() {
    @Override
    public void onRenderCreated(RenderEvent event) {
        System.out.println("Render process is created.");
    }

    @Override
    public void onRenderGone(RenderEvent event) {
        System.out.println("Render process is gone:");
        TerminationStatus terminationStatus =
                event.getTerminationStatus();
        System.out.println("Termination Status: " + terminationStatus);
    }
});

If you refresh or load the same or another URL, the render process and Browser instance will be restored. Example:

browser.addRenderListener(new RenderAdapter() {
    @Override
    public void onRenderGone(RenderEvent event) {
        Browser browser = event.getBrowser();
        // Restore Browser instance by loading the same URL
        browser.loadURL(browser.getURL());
    }
});

User Agent

The user-agent string can be modified only once, before you create any Browser instances. You can provide your own user-agent string using the BrowserPreferences.setUserAgent(String userAgent) method or via the jxbrowser.chromium.user-agent Java System Property:

BrowserPreferences.setUserAgent("My User Agent String");