This page describes how to work with pop-ups, display or suppress them.

Overview

Any web page can display pop-up windows using one of the following ways:

  1. Using the window.open() JavaScript function. For example:

     window.open("https://www.google.com", "_blank", "resizable=yes,
         top=500, left=500, width=400, height=400");
    
  2. Through a link with the target attribute:

     <a href="https://www.google.com" target="_blank">Open Google</a>
    

By default all pop-ups are suppressed.

Opening Pop-ups

In order to change the default behavior and take control over creation of pop-ups use the CreatePopupCallback and OpenPopupCallback callbacks.

The CreatePopupCallback callback is invoked when the engine wants to know whether pop-up can be created or not. The following code shows how to allow creating a pop-up:

browser.set(CreatePopupCallback.class, (params) -> Response.create());

If the CreatePopupCallback callback allows to create a pop-up, the OpenPopupCallback callback will be invoked. In this callback you can access the created pop-up and display it if necessary. For example:

browser.set(OpenPopupCallback.class, (params) -> {
    // Access the created popup.
    Browser popup = params.popupBrowser();
    return Response.proceed();
});

The popup instance in the sample above does not have any web page loaded at the time the callback is invoked. The web page will be loaded later. At this moment you can register all required event listeners and callbacks, but you cannot access DOM or JavaScript, because the popup does not have a Frame yet.

Suppressing Pop-ups

To suppress pop-ups use the following approach:

browser.set(CreatePopupCallback.class, params -> Response.suppress());

Displaying Pop-ups

When you create a Swing or JavaFX BrowserView, it automatically configures the given Browser instance with the default implementation of the CreatePopupCallback and OpenPopupCallback callbacks.

The default implementation of the CreatePopupCallback allows creating all pop-ups:

browser.set(CreatePopupCallback.class, params -> Response.create());

The default implementation of the OpenPopupCallback callback for both Swing and JavaFX you can find below.

Swing

The default implementation for Swing BrowserView is the following:

import static javax.swing.SwingUtilities.invokeLater;

import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.OpenPopupCallback;
import com.teamdev.jxbrowser.browser.event.BrowserClosed;
import com.teamdev.jxbrowser.browser.event.TitleChanged;
import com.teamdev.jxbrowser.browser.event.UpdateBoundsRequested;
import com.teamdev.jxbrowser.ui.Rect;
import com.teamdev.jxbrowser.ui.Size;
import com.teamdev.jxbrowser.view.swing.BrowserView;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;

/**
 * The default {@link OpenPopupCallback} implementation for the Swing UI toolkit
 * that creates and shows a new window with the embedded popup browser.
 */
public final class DefaultOpenPopupCallback implements OpenPopupCallback {

    private static final int DEFAULT_POPUP_WIDTH = 800;
    private static final int DEFAULT_POPUP_HEIGHT = 600;

    @Override
    public Response on(Params params) {
        Browser browser = params.popupBrowser();
        invokeLater(() -> {
            BrowserView view = BrowserView.newInstance(browser);
            JFrame frame = new JFrame();
            frame.add(view, BorderLayout.CENTER);
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    invokeLater(browser::close);
                }
            });

            updateBounds(frame, params.initialBounds());

            browser.on(TitleChanged.class, event -> invokeLater(() ->
                    frame.setTitle(event.title())
            ));
            browser.on(BrowserClosed.class, event -> invokeLater(() -> {
                frame.setVisible(false);
                frame.dispose();
            }));
            browser.on(UpdateBoundsRequested.class, event -> invokeLater(() ->
                    updateBounds(frame, event.bounds())
            ));

            frame.setVisible(true);
        });
        return Response.proceed();
    }

    private static void updateBounds(JFrame frame, Rect bounds) {
        if (bounds.size().isEmpty()) {
            frame.setLocationByPlatform(true);
            frame.setSize(DEFAULT_POPUP_WIDTH, DEFAULT_POPUP_HEIGHT);
        } else {
            frame.setLocation(toPoint(bounds.origin()));
            frame.getContentPane().setPreferredSize(toDimension(bounds.size()));
            frame.pack();
        }
    }

    private static Dimension toDimension(Size size) {
        return new Dimension(size.width(), size.height());
    }

    private static Point toPoint(com.teamdev.jxbrowser.ui.Point point) {
        return new Point(point.x(), point.y());
    }
}

JavaFX

The default implementation for JavaFX BrowserView is the following:

import static javafx.application.Platform.runLater;

import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.OpenPopupCallback;
import com.teamdev.jxbrowser.browser.event.BrowserClosed;
import com.teamdev.jxbrowser.browser.event.TitleChanged;
import com.teamdev.jxbrowser.browser.event.UpdateBoundsRequested;
import com.teamdev.jxbrowser.ui.Rect;
import com.teamdev.jxbrowser.view.javafx.BrowserView;

import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * The default {@link OpenPopupCallback} implementation for the JavaFX UI toolkit
 * that creates and shows a new window with the embedded popup browser.
 */
public final class DefaultOpenPopupCallback implements OpenPopupCallback {

    private static final int DEFAULT_POPUP_WIDTH = 800;
    private static final int DEFAULT_POPUP_HEIGHT = 600;

    @Override
    public Response on(Params params) {
        Browser browser = params.popupBrowser();
        runLater(() -> {
            BrowserView view = BrowserView.newInstance(browser);
            Stage stage = new Stage();
            StackPane root = new StackPane();
            Scene scene = new Scene(root);
            root.getChildren().add(view);
            stage.setScene(scene);

            updateBounds(stage, params.initialBounds());

            stage.setOnCloseRequest(event -> browser.close());
            browser.on(TitleChanged.class, event ->
                    runLater(() -> stage.setTitle(event.title()))
            );
            browser.on(BrowserClosed.class, event ->
                    runLater(stage::close)
            );
            browser.on(UpdateBoundsRequested.class, event ->
                    runLater(() -> updateBounds(stage, event.bounds()))
            );
            stage.show();
        });
        return Response.proceed();
    }

    private static void updateBounds(Stage stage, Rect bounds) {
        if (bounds.size().isEmpty()) {
            stage.setWidth(DEFAULT_POPUP_WIDTH);
            stage.setHeight(DEFAULT_POPUP_HEIGHT);
        } else {
            stage.setX(bounds.origin().x());
            stage.setY(bounds.origin().y());
            stage.setWidth(bounds.size().width());
            stage.setHeight(bounds.size().height());
        }
    }
}

SWT

The default implementation for SWT BrowserView is the following:

import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.OpenPopupCallback;
import com.teamdev.jxbrowser.browser.event.BrowserClosed;
import com.teamdev.jxbrowser.browser.event.TitleChanged;
import com.teamdev.jxbrowser.browser.event.UpdateBoundsRequested;
import com.teamdev.jxbrowser.ui.Rect;
import com.teamdev.jxbrowser.view.swt.BrowserView;

import org.eclipse.swt.SWTException;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;

/**
 * The default {@link OpenPopupCallback} implementation for the SWT UI toolkit
 * that creates and shows a new window with the embedded popup browser.
 */
public final class DefaultOpenPopupCallback implements OpenPopupCallback {

    private static final int DEFAULT_POPUP_WIDTH = 800;
    private static final int DEFAULT_POPUP_HEIGHT = 600;

    @Override
    public Response on(Params params) {
        Browser browser = params.popupBrowser();
        try {
            Display display = Display.getDefault();
            display.asyncExec(() -> {
                Shell shell = new Shell(display);
                shell.setLayout(new FillLayout());
                BrowserView view = BrowserView.newInstance(shell, browser);
                updateBounds(shell, view, params.initialBounds());

                shell.addDisposeListener(event -> {
                    if (!browser.isClosed()) {
                        asyncExec(shell, browser::close);
                    }
                });

                browser.on(TitleChanged.class, event ->
                        asyncExec(shell, () -> shell.setText(event.title())));
                browser.on(BrowserClosed.class, event ->
                        asyncExec(shell, shell::dispose));
                browser.on(UpdateBoundsRequested.class, event ->
                        asyncExec(shell, () -> updateBounds(shell, view, event.bounds())));

                view.setVisible(true);
                shell.pack();
                shell.open();

                while (!shell.isDisposed()) {
                    if (!display.readAndDispatch()) {
                        display.sleep();
                    }
                }
            });
        } catch (SWTException ignore) {
            Response.proceed();
        }
        return Response.proceed();
    }

    private static void updateBounds(Shell shell, BrowserView view, Rect bounds) {
        shell.setLocation(bounds.x(), bounds.y());
        if (bounds.size().isEmpty()) {
            view.setSize(DEFAULT_POPUP_WIDTH, DEFAULT_POPUP_HEIGHT);
        } else {
            view.setSize(bounds.width(), bounds.height());
        }
    }

    private static void asyncExec(Widget widget, Runnable doRun) {
        widget.getDisplay().asyncExec(() -> {
            if (!widget.isDisposed()) {
                doRun.run();
            }
        });
    }
}

Closing Pop-ups

The opened pop-up can be closed via the Browser.close() method, or via window.close() from JavaScript. In both cases the BrowserClosed event is fired.

We recommend you to always register the BrowserClosed event listener to get notifications when pop-up is closed. This will allow you to hide the pop-up window if you have it displayed.

popup.on(BrowserClosed.class, event -> {
    // Hide the pop-up window.
});
Go Top