I have been developing Eclipse plugins for more than four years now. I have implemented many features in the ColdFusion Builder, which is an Eclipse based IDE. Eclipse SDK provides a SWT Browser control which can be used within Eclipse plugin to display HTML files. Eclipse does not include any browser, but it uses the system browser- on Windows it is Internet Explorer and on Macintosh it is Safari. I have used this control mainly to display static HTML content or open a URL on a remote server, e.g. for executing ColdFusion Builder extensions written in CFML.
Recently I have been doing a lot of mobile application dev elopement, and saw how easy it was to invoke Java objects from JavaScript in Android. I have blogged about this in one of my posts, Creating Android Applications with HTML User Interface. This got me thinking that it would be nice if SWT Browser control would also provide some way to pass Java Objects to JavaScript. Turned out that it is possible.
To expose Java Object from Eclipse to JavaScript, you need to create a class that extends BrowserFunction. The constructor of this class takes two arguments; the first one is Browser instance and second one is name of the the function that will be available in JavaScript code running the SWT browser control. For example, if you want to get list of files in a folder from JavaScript code, you would first write a class that extends BrowserFunction –
import java.io.File; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.BrowserFunction; public class ListFilesFunction extends BrowserFunction { Browser browser = null; String functionName = null; public ListFilesFunction(Browser browser, String name) { super(browser, name); this.browser = browser; this.functionName = name; } public Object function (Object[] args) { if (args.length == 0) browser.execute("alert('Function " + functionName + " requires one argument - parent folder path');"); File file = new File(args[0].toString()); if (!file.exists()) browser.execute("alert('Folder " + args[0] + " does not exist');"); if (!file.isDirectory()) browser.execute("alert('Path " + args[0] + " must be a folder');"); return file.list(); } }
Notice that you can call JavaScript code from Java using execute function of the Browser.
You then need to associate this function with the browser control, for example –
public class View extends ViewPart { Browser browserCtl = null; ... public void createPartControl(Composite parent) { ... browserCtl = new Browser(parent, SWT.None); new ListFilesFunction(browserCtl, "getFiles"); ... } ... }
You can invoke this function from JavaScript as follows –
<html> <head> <script type='text/javascript'> files = getFiles("c:/"); for (i = 0; i < files.length; i++) { document.writeln(files[i] + "<br>"); } </script> </head> <body> </body> </html>
Notice that getFiles function called in the above JavaScript code is associated with ListFilesFunction class declared earlier.
The value I see in being able to call Java from JavaScript, as described above, is that you can create very powerful UI using HTML5/JavaScript very easily and at the same time enhance capability of browser based applications – by creating your own custom Java classes that can access local resources, or make many functionality available that otherwise are not accessible using plain JavaScript.
I am working on an Eclipse RCP application that would take a path to zip file or a folder containing HTML and JavaScript code and display that in the Browser control – so essentially you can convert your web application easily into a standalone desktop application. And since it ia based on Eclipse, it is it cross platform.
You might find this somewhat similar to Adobe AIR. Of course AIR has a lot more features than this simple application that I am creating – but one aspect of AIR, which is easily converting web application to desktop application is same in the Eclipse RCP application I am developing.
-Ram Kulkarni
Awesome logic! thanks as this helped me today!!!
Valuable info…Thankyou.
Can you as well pass java objects through the SWT Browser control to the script in the html?
Eg: I create an object at the java end – MyClass interface = new MyClass();
And can I pass this “interface” object to the html so that it can be used in the javascript.
eg: interface.myFunction();
I think it should be possible. I don’t have a setup ready to test it, but you can expose getInterface function (just like in examples in this post ‘getFiles’ function is made available in JS). getInterface may return new MyClass(); and then you should be able to call functions on the returned Java object from JS
Thanks for the quick reply.
I did try this out. But somehow javascript doesn’t seem to understand the type of MyClass. By looking into the documentation of function() method of BrowserFunction, I think it is not possible to return an object whose type is not supported by javascript.
Ok, in that case you will have to create wrapper functions. If you want to return complex data, then you could return it as JSON string.
It has been a while since I looked at BrowserFunction APIs, so wan’t sure when I replied yesterday.
That is a good idea..Thankyou for the sugegstion.
I tested this above code, but it is not working.
How to call a function using class object from jsp page.
Is there any functions in java to bind javascript like addJavaScriptInterface() in Android?
I am not sure if you tried this solution in Eclipse browser. This solution works only in SWT browser control of Eclipse. It is not a generic solution which could work in any web browser.