Skip to Main Content

Oracle Forms

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

SWT Browser component in an Oracle Forms application

electrotypeFeb 19 2015 — edited May 18 2015

Where I work we have some Oracle Forms applications and, in one of them, we need to embed a webpage which will itself contain an applet... Pretty much the only solution I found to achieve this in Java 6+ is the SWT Browser component.

I have made a proof of concept embedding the SWT Browser component inside a JApplet and everything works fine! But when we replace the top JApplet with a VBean and we embed it in our Forms application, it gives this error :

java.lang.IllegalArgumentException: Argument not valid [peer not created] 
at org
.eclipse.swt.SWT.error(Unknown Source)
at org
.eclipse.swt.awt.SWT_AWT.new_Shell(Unknown Source)
at xx
.xxxxx.forms.utils.webbrowser.BrowserCanvas$1.run(BrowserCanvas.java:65)

I found some posts about this error on the net but nothing helped! The tests are done on a Windows 64bits machine. The Java version is JRE 1.6.0_12-b04 Java HotSpot(TM) Client VM.

Here's the code (heavily based on this article) :


SwtWebBrowser (the VBean) :

import java.awt.BorderLayout;

import javax.swing.JPanel;

import oracle.forms.handler.IHandler;

import oracle.forms.ui.VBean;

import org.eclipse.swt.browser.Browser;

//public class SwtWebBrowser extends JApplet {

public class SwtWebBrowser extends VBean {

    private static final long serialVersionUID = 1L;

    private JPanel panel;

    private BrowserCanvas browserCanvas;

    @Override

    //public void init() {

    public void init(IHandler handler) {

        // Required for Linux systems

        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=161911

        try {

            System.setProperty("sun.awt.xembedserver", "true");

        } catch (Exception ex) {

            // ok on Windows

        }

        this.browserCanvas = new BrowserCanvas();

        this.panel = new JPanel(new BorderLayout());

        this.panel.setPreferredSize(this.getPreferredSize());

        this.panel.add(this.browserCanvas, BorderLayout.CENTER);

        add(this.panel);

        // This is VERY important: Make the frame visible BEFORE

        // connecting the SWT Shell and starting the event loop!

        setVisible(true);

        this.browserCanvas.connect();

        setURL("http://google.com");

    }

    protected Browser getBrowser() {

        return this.browserCanvas.getBrowser();

    }

    protected JPanel getPanel() {

        return this.panel;

    }

    protected void executeInBrowser(Runnable runnable) {

        getBrowser().getDisplay().asyncExec(runnable);  

    }

    public void setURL(final String url) {

        executeInBrowser(new Runnable() {

            @Override

            public void run() {

                getBrowser().setUrl(url);

            }

       });       

    }

}

BrowserCanvas :


import java.awt.Canvas;

import org.eclipse.swt.SWT;

import org.eclipse.swt.awt.SWT_AWT;

import org.eclipse.swt.browser.Browser;

import org.eclipse.swt.layout.FillLayout;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

public class BrowserCanvas extends Canvas {

    private static final long serialVersionUID = 1L;

    private Thread swtThread;

    private Browser swtBrowser;

    /**

     * Connect this canvas to a SWT shell with a Browser component and

     * starts a background thread to handle SWT events. This method waits

     * until the browser component is ready.

     */

    public void connect() {

        if (this.swtThread == null) {

            final Canvas canvas = this;

            this.swtThread = new Thread() {

                @Override

                public void run() {

                    try {

                        Display display = new Display();

                        // The exception is here :

                        Shell shell = SWT_AWT.new_Shell(display, canvas);

                        shell.setLayout(new FillLayout());

                        synchronized (this) {

                            BrowserCanvas.this.swtBrowser = new Browser(shell, SWT.NONE);

                            this.notifyAll();

                        }

                        shell.open();

                        while (!isInterrupted() && !shell.isDisposed()) {

                            if (!display.readAndDispatch()) {

                                display.sleep();

                            }

                        }

                        shell.dispose();

                        display.dispose();

                    } catch (Exception e) {

                        interrupt();

                    }

                }

            };

            this.swtThread.start();

        }

        // Wait for the Browser instance to become ready

        synchronized (this.swtThread) {

            while (this.swtBrowser == null) {

                try {

                    this.swtThread.wait(100);

                } catch (InterruptedException e) {

                    this.swtBrowser = null;

                    this.swtThread = null;

                    break;

                }

            }

        }

    }

    /**

     * Returns the Browser instance. Will return "null" before "connect()"

     * or after "disconnect()" has been called.

     */

    public Browser getBrowser() {

        return this.swtBrowser;

    }

    /**

     * Stops the swt background thread.

     */

    public void disconnect() {

        if (this.swtThread != null) {

            this.swtBrowser = null;

            this.swtThread.interrupt();

            this.swtThread = null;

        }

    }

    /**

     * Ensures that the SWT background thread is stopped if this canvas is

     * removed from it's parent component (e.g. because the frame has been

     * disposed).

     */

    @Override

    public void removeNotify() {

        super.removeNotify();

        disconnect();

    }

}

Any idea on how to make it work would be really appreciated! Or in fact any other ideas on how to embed a webpage that contains an applet.

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 15 2015
Added on Feb 19 2015
9 comments
2,881 views