Skip to main content
Jump to: navigation, search

JFace Data Binding/Rhino

Target

The goal of JFace Data Binding/Rhino is to support binding to a Rhino Javascript Scriptable Object. The sources of a working prototype are available in TK-UI SVN but we are discussing with the Eclipse Team on where it can be made available.

JFace Data Binding/Rhino needs Rhino 1.6.6, because to detect the change of a Javascript Object property (thanks to Simon Kaegi), the Rhino observable value has to use ScriptableObject#setGetterOrSetter(....) to fire JFace Databinding events.

Use-case

Let's start with a simple example. Imagine you have this script :

function Person(name) {
  this.name = name
};

var person = new Person('Simon')

And you wish to bind the property 'name' of the scriptable object 'person' with an SWT Text widget.

Jface-db-rhino-person.png

When the form page loads, SWT Text's value is 'Simon'. When the user types 'Boris' into the the Text widget, it updates the property 'name' of the scriptable object 'person' with the value 'Boris'.

RhinoObservables

Like the other JFace Databinding implementations (SWT, Beans, Pojo...), the Rhino bindings project gives you several JFace IObservableValue and IObservableList implementations accessible via the IObservable factory org.eclipse.core.databinding.rhino.RhinoObservables.

Here is how to use RhinoObservables ti do the binding:

// 1. Prepare script to execute
String script = "function Person(name) {this.name = name}; " +
		" var person = new Person('Simon')";
		
// 2. Load Rhino script by using ImporterTopLevel  
ScriptableObject global = null;
try {
  Context cx = ContextFactory.getGlobal().enterContext();
  global = new ImporterTopLevel(cx);
  cx.evaluateString(global, script, null, 0, null);
} finally {
  Context.exit();
}

		
// 3. Get UI observable 
IObservableValue uiObservable = SWTObservables.observeText(textWidget, SWT.Modify);
				
// 4. Get Rhino observable
IObservableValue rhinoObservable = RhinoObservables.observeValue(global, "person", "name");
			
// 5. Bind JS Person#name with SWT Text
DataBindingContext bindingContext = new DataBindingContext();
bindingContext.bindValue(uiObservable, rhinoObservable, null, null);

Why JFace Rhino Databinding?

One might ask "why would I need JFace Rhino Databinding?"? I will try to explain step by step why I think JFace Rhino Databinding could be useful.

Eclipse E4/Declarative UI

One Eclipse E4 target is to have declarative UI capabilities. XWT is a declarative UI proposal. With XWT, creating a shell with a text widget can be done using this xml snippet :

<Shell xmlns="http://www.eclipse.org/xwt/presentation"
    xmlns:x="http://www.eclipse.org/xwt">
    <Shell.layout>
       <FillLayout/>
    </Shell.layout>
    <Text />
</Shell>

XWT/Bean binding

XWT supports Beans binding with declarative means. For instance if we bind the text attribute of Text to a property “Name” of a Bean Person, here is the data binding expression:

...
<Text text="{binding path=Name}"/>
...

Internally, XWT use JFace Databinding to manage the binding, so we can extend it to manage different bindings (EMF, DOM...).

XWT/Javascript binding

XWT is intending to support Javascript (see Bug 266772). If we take the previous #Use-case with XWT we could write this :

<Shell xmlns="http://www.eclipse.org/xwt/presentation"
    xmlns:x="http://www.eclipse.org/xwt"
    xmlns:r="http://www.eclipse.org/rhino">
    <r:script>
       function Person(name) {
         this.name = name
       };
       var person = new Person('Simon')
    <r:script>
    <Shell.layout>
       <FillLayout/>
    </Shell.layout>
    <Text text="{binding source=person path=name}" />
</Shell>

So the "text" property of SWT Text will be bound with the "name" property of the javascript object person by using this binding expression :

  <Text text="{binding source=person path=name}" />

Declarative UI/Javascript/Akrogen

Another question which may arise is "why having scriptable object management with declarative UI ?" Before answering to this, I would like to speak about Akrogen which is an Eclipse plugin for code generation.

With Akrogen you can describe your Eclipse wizard with declarative means using XML/XUL and javascript. The XML points to a template (Freemarker, XSL, velocity) which will be called when the Finish button is pressed. You can define some ScriptableObjects in the XUL wizard, bind them to the SWT widgets and reference them in the template. I'm planning to improve Akrogen by using the E4 Declarative UI solution. Take a sample. Imagine you want have a wizard page with an SWT Text Widget. The User types 'Simon' and hits the Finish button of the wizard page, which results int the followoing file being generated :

Hello Simon!

You wish to manage this with a Javascript Object Person. If you were to use a Freemarker template, you can write the following HelloWord.ftl template :

Hello {person.name}!

And here is the wizard page description with XWT :

<Shell xmlns="http://www.eclipse.org/xwt/presentation"
    xmlns:x="http://www.eclipse.org/xwt"
    xmlns:r="http://www.eclipse.org/rhino"
    xmlns:a="http://akrogen.sourceforge.net/">
    <r:script>
       function Person(name) {
         this.name = name
       };
       var person = new Person('Simon')
    <r:script>
    <Shell.layout>
       <FillLayout/>
    </Shell.layout>
 
    <Text text="{binding source=person path=name}" />
 
    <a:template uri="HelloWord.ftl" />
</Shell>

Back to the top