Search code examples
javascriptjavahtmlswtrcp

SWT Browser Widget: How to listen to JavaScript events?


so we are currently working on a RCP application, which integrates a SWT Browser. We would like to implement some sort of a communication between the browser and the RCP Application. Mainly we want that if the user presses a button in the Webinterface an event gets triggered, so the RCP Application can listen to it and handle it accordingly (an example would be opening a specific view inside the RCP Application).

How would you tackle this problem? I already tried to addMouseListener() on the browser. But the mouseevents are not helping much, since they dont carry any information on which element inside the webinterface got pressed...

I hope you could help me out/inspire me with possible solutions!

EDIT: Here are some Examples on how to the browser gets instantiated:

public class BrowserView extends ViewPart {
    Browser browser;

    private static final Log LOG = LogFactory.getLog(BrowserView.class);

    @Override
    public void createPartControl(Composite parent) {
        this.browser = new Browser(parent, SWT.NONE);

        browser.addMouseListener(new MouseListener() {

            @Override
            public void mouseUp(MouseEvent e) {         
            }

            @Override
            public void mouseDown(MouseEvent e) {
                // do something with the event

            }

            @Override
            public void mouseDoubleClick(MouseEvent e) {

            }
        });

    }

    @Override
    public void setFocus() {
        // Do nothing
    }

    public void setUrl(String url) {
        this.browser.setUrl(url);
    }


}

So mainly we create a browser in a specific composite. We tried to add a handler to a mouseDown Event, but it doesnt help much, since the event doesnt contain any information on which button got triggered inside the browser. How can we get extended information from events regarding the browser? Lets say the content inside the Browser has Button1, Button2 and Button3. We want to have something like

        public void mouseDown(MouseEvent e) {
            switch (e.getType.getName()) {
            case "Button1": handleButton1();
            break;
            case "Button2": handleButton2(); 
            break;
            case "Button3": handleButton3();
            break;
            }

        }

I am well aware that here are other possible solutions. This was just my naive approach


Solution

  • You could modify your web page to call a java function via javascript.

    You can create a java function which can be called from the browser by creating a BrowserFunction:

    1. in the constructor you pass the function name that javascript will have to invoke
    2. when that happens, the BrowserFunction.function method will be executed

    Simple example:

    Web page with a button that calls a java function when pressed (page.html):

    <!DOCTYPE html>
    <html>
    <body>
    
    <button type="button" onclick="javaFunction()">Click Me!</button>
    
    </body>
    </html> 
    

    The java code that shows how to display the web page from the SWT browser. When the button is pressed function is called and prints on the console:

    public class BrowserTest {
    
        public static void main(String[] args) {
            Display display = new Display();
            Shell shell = new Shell(display);
            shell.setLayout(new FillLayout());
    
            Browser browser = new Browser(shell, SWT.NONE);
            browser.setUrl("file:/C:/BrowserTest/page.html");
    
            new JavaFunction(browser, "javaFunction");
    
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
            display.dispose();
        }
    
        private static class JavaFunction extends BrowserFunction {
    
            JavaFunction(Browser browser, String name) {
                super(browser, name);
            }
    
            @Override
            public Object function(Object[] arguments) {
                System.out.println("Button pressed!");
                return null;
            }
        }
    
    }