Skip to main content

Scripting Java with Javascript: trapping Swing events

Posted by carcassi on November 12, 2008 at 7:59 AM PST

A few months ago, we had to decide which technology to use for the front end
gui of our project. We ended up
choosing Swing/Applets due to the progress that they both have done in the past
couple of years. To name a few: better deployment for applets, SwingX
components, the NetBeans graph library and the overall speed and PLAF fidelity
improvements. (Given the turmoil in the blogosphere, we will see whether I will
need to revisit my choice in a couple of years... but that's another story. And
decision always need to be revisited... ;-) ).

One of the requirement I had, was to give the ability to the user to create
pieces of my work and create their own pages. Given that I am lazy, and I didn't
want to implement every call to every possible scenario, I said to myself: "Why
don't I just give them access to the Swing events?". That way I can simply
design my Swing widget, and they are automatically Swing widgets and "Javascript"
widgets.

The idea is the following: let us assume I have a JList full of ComponentType
objects, which have a Manufacturer, a description String and a couple of other
properties. I want to put that JList in an applet, have some javascript called
when an item is selected which fills some HTML fields. I have something like:

  function componentTypeChanged(res1) {
    document.getElementById('manufacturer').value = res1.getSource().getSelectedValue().getManufacturer().toString();
    document.getElementById('description').value = res1.getSource().getSelectedValue().getDescription().toString();
    document.getElementById('ffactor').value = res1.getSource().getSelectedValue().getFormFactor().toString();
    document.getElementById('name').value = res1.getSource().getSelectedValue().getName();
  }

  document.applet1.registerEvent("valueChanged","componentTypeChanged");

The core of the work is done

this class
, which is amazingly small for what it does. The entry point is a
single static method:

public class JavaScriptEventBridge {
  public static void registerEvent(Object jObject, String eventName, String jsFn, JSObject win) {
    ...

You give it a JavaObject (i.e. a JList), an eventName (a method name of a
listener, such "valueChanged"), a JavaScript function name (i.e. "componentTypeChanged")
and a JavaScript object on which that method can be called. What the method does
is introspect the Java Object, find out which Listener implements that method
call, creates a Proxy object of that Listener type that responds to the event by
calling the javascript method.

It may sound complicated, but if you look at the implementation it's less
than 100 lines of code (counting all the empty lines).

The question is: is this something that is interesting only to me? Or should we
have something like this in Java?

Related Topics >>

Comments

This is cool. I've been thinking about implementing something like this for Pivot (http://pivot-toolkit.org). -Greg