Browser Tales – Java to JavaScript and vice versa with the SWT Browser Widget

The SWT Browser widget makes it very easy to run HTML and JavaScript within Eclipse. This widget encapsulates a browser (system dependent) into a SWT widget.

The following screenshot is from the second example below. This example is based on a blog entry from Ian Bull and SWT Snippet 307.

swtexample

The following coding will be defining views for Eclipse RCP or via Eclipse plugins so I assume you are familiar with these topics.

Lets start with a simple example. Via the following coding you can setup a View in your Eclipse RCP and inject some JavaScript from your Java Code.

package de.vogella.javascript.simple;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart {
	public static final String ID = "de.vogella.javascript.simple.view";


	public void createPartControl(Composite parent) {
		// You need XULRunner installed to use this line
//		final Browser b = new Browser(parent, SWT.MOZILLA);
		final Browser b = new Browser(parent, SWT.NONE); // Uses IE on MS Windows
		b.setUrl("http://www.vogella.de");
		b.addProgressListener(new ProgressListener() {
			@Override
			public void completed(ProgressEvent event) {
				System.out.println("Page loaded");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// Execute JavaScript in the browser
				b.execute("alert(\"JavaScript, called from Java\");"); 
			}
			@Override
			public void changed(ProgressEvent event) {
			}
		});
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
	}
}

The next example is a bit more complex (it is the example from the screenshot). This demonstarte how JavaScript can also call back to your Java Code.


package de.vogella.javascript.maps;

import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart {
	
	public static final String ID = "de.vogella.javascript.maps.view";
	private static List list;
	
	
	public void createPartControl(Composite parent) {
		SashForm sash = new SashForm(parent, SWT.HORIZONTAL);
		
		File f = new File("C:/temp/demofile/map.html");
		final Browser browser = new Browser(parent, SWT.NONE); // Uses IE on MS
		
		browser.addControlListener(new ControlListener() {
			public void controlResized(ControlEvent e) {
				// Use Javascript to set the browser width and height
				browser
						.execute("document.getElementById('map_canvas').style.width= "
								+ (browser.getSize().x - 20) + ";");
				browser
						.execute("document.getElementById('map_canvas').style.height= "
								+ (browser.getSize().y - 20) + ";");
			}

			public void controlMoved(ControlEvent e) {
			}
		});
		
		 new CustomFunction (browser, "theJavaFunction");
		 
		    Composite c = new Composite(sash, SWT.BORDER);
		    c.setLayout(new GridLayout(2, true));
		    Button b = new Button(c, SWT.PUSH);
		    b.setText("Where Am I ?");
		    b.addSelectionListener(new SelectionAdapter() {
		        public void widgetSelected(SelectionEvent e) {
		            double lat = ((Double) browser.evaluate("return map.getCenter().lat();")).doubleValue();
		            double lng = ((Double) browser.evaluate("return map.getCenter().lng();")).doubleValue();
		            list.add(lat + " : " + lng);
		        }
		    });
		    
		    Button addMarker = new Button(c, SWT.PUSH);
		    addMarker.setText("Add Marker");
		    addMarker.addSelectionListener(new SelectionAdapter() {
		        public void widgetSelected(SelectionEvent e) {
		            browser.evaluate("createMarker();");
		          
		        }
		    });
		    list = new List(c, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
		    GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
		    gridData.horizontalSpan=2;
		    list.setLayoutData(gridData);
		  
		   
		    browser.setUrl(f.toURI().toString());
//		    sash.setWeights(new int[] {4,1});
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {

	}
	
	 // Called by JavaScript
	 class CustomFunction extends BrowserFunction {
	    CustomFunctionData data = new CustomFunctionData(null);
	    
		CustomFunction (Browser browser, String name) {
	        super (browser, name);
	        this.data.browser = browser;
	    }
	    public Object function (Object[] arguments) {
	        double lat = ((Double) arguments[0]).doubleValue();
	        double lng = ((Double) arguments[1]).doubleValue();
	        list.add(lat + " : " + lng);
	        data.browser.execute("document.getElementById('map_canvas').style.width= "+ (data.browser.getSize().x - 20) + ";");
	        data.browser.execute("document.getElementById('map_canvas').style.height= "+ (data.browser.getSize().y - 20) + ";");
	        return null;
	    }
	 }
}

The coding above reads a HTML (with some JavaScript code) file “C:/temp/demofile/map.html”. If you save it somewhere else you need to adjust line 28 in the coding above.

<!DOCTYPE html "-//W3C//DTD XHTML 1.0 Strict//EN" 

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>

    <title>Google Maps JavaScript API Example</title>

    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg&sensor=false"
            type="text/javascript"></script>
    <script type="text/javascript">

	var map;

 
    function initialize() {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map_canvas"));
        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
        map.setUIToDefault();

     
		
		// Callback to Java from JavaScript
	    theJavaFunction(map.getCenter().lat(), map.getCenter().lng());

		 
      }

    }
	
    function createMarker(){
		var lat = map.getCenter().lat();
		var lng = map.getCenter().lng();
        var point = new GLatLng(lat,lng);
		var d=new Date();
		
		var marker = new GMarker(point, {draggable: true});

		GEvent.addListener(marker, "dragstart", function() {
			map.closeInfoWindow();
		});

		GEvent.addListener(marker, "dragend", function() {
		});

		map.addOverlay(marker);
		addMassiveData();
		
		
    }
	
	function addMassiveData(){
	// Add 10 markers to the map at random locations
		var bounds = map.getBounds();
        var southWest = bounds.getSouthWest();
        var northEast = bounds.getNorthEast();
        var lngSpan = northEast.lng() - southWest.lng();
        var latSpan = northEast.lat() - southWest.lat();
        for (var i = 0; i < 100; i++) {
         var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
               southWest.lng() + lngSpan * Math.random());
        map.addOverlay(new GMarker(point));
		}
	}


    </script>

 
  </head>

  <body onload="initialize()" >

    <div id="map_canvas" style="width: 600px; height: 400px"></div>

  </body>

</html>

This should demonstrate how easy you can integrate HTML and JavaScript into Eclipse. This is something the Eclipse E4 OpenSocial Gadget project also targets.

Check it out! The Open Social Gadgets with Eclipse E4 – Tutorial tries to give a little introduction.

About Lars Vogel

Lars Vogel is the founder and CEO of the vogella GmbH and works as Eclipse and Android consultant, trainer and book author. He is a regular speaker at international conferences, With more than one million visitors per month his website vogella.com is one of the central sources for Eclipse and Android programming information.
This entry was posted in Eclipse and tagged , , . Bookmark the permalink.

One Response to Browser Tales – Java to JavaScript and vice versa with the SWT Browser Widget

  1. Andy says:

    Hey, nice Snippet.

    Can you please add the Source Code?!

    Thanks a lot

Comments are closed.