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!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

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,720 views