Sunday, 2 November 2008

new XUL on Java project

Remember this June post about using XUL, Javascript, and Beanshell in a ARINC 661 Client-Server framework ?
Well it occurred to me that the XUL / Javascript / Beanshell part of this was not specific to ARINC661 and could be useful to others as well.
Also if you look in the wild you will only find two Java XUL frameworks:

  • A Java project called jXUL had exactly this goal, but it seemed that its development stalled very quickly in 2001, while still in Beta or even Alpha stage (no activity since then)

  • Luxor is huge and complex, and also has no activities since some years

So why not sharing some code, being able to use XUL "out of the box" in Java can be useful, and even cool ;-)

So let me introduce my new project: javaXUL.

javaXUL is not intended to compete with much more complete RIA offerings, such as Flash, Silverlight or javaFX. Instead it tries to leverage the expressivity of XUL in the java developement area. Compatibility with Mozilla XUL (such as the Firefox implementation) is a goal, but ease to use in the Java world is also one.
The goal of version 0.1 (underway) is to be able to use javaXUL "out of the box" to add user-defined UIs on Java projects:

  • import existing sources and make them compile

  • make them work on simple use cases

  • add simple examples

  • allow setting of Look and Feel

  • ability to add other script engines than Javascript

And now, Just a simple example for your pleasure:

Lets look at the code for this example (its available in the javaXUL website):

import java.awt.BorderLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import org.xul.script.scripts.AbstractScriptContext.JSFunctionBinding;
import org.xul.script.scripts.ScriptListener;
import org.xul.script.xul.DefaultScriptManager ;
import org.xul.script.xul.model.XULDocument;

public class BasicXULSample extends JFrame {
private JTabbedPane pane = new JTabbedPane();
private XULListener listener = new XULListener();

public BasicXULSample() {
super("Basic XUL Sample");
this.setLayout(new BorderLayout());
this.setSize(500, 500);

private URL getResource(String name) {
return Thread.currentThread().getContextClassLoader().getResource(name);

private void init() {
DefaultScriptManager manager = new DefaultScriptManager ();
manager.setLookAndFeel(new WindowsLookAndFeel());
try {
URL boxes = getResource("org/xul/samples/resources/boxes.xul");
XULDocument boxesdoc = manager.addXULScript(boxes.toString(), boxes);
JComponent boxescomp = boxesdoc.getRootComponent();
if (boxescomp != null) {
pane.addTab(boxesdoc.getFile().getName(), new JScrollPane(boxescomp));
URL test = getResource("org/xul/samples/resources/test.xul");
XULDocument testdoc = manager.addXULScript(test.toString(), test);
JComponent testcomp = testdoc.getRootComponent();
if (testcomp != null) {
pane.addTab(testdoc.getFile().getName(), new JScrollPane(testcomp));
URL buttons = getResource("org/xul/samples/resources/buttons.xul");
XULDocument buttonsdoc = manager.addXULScript(buttons.toString(), buttons);
JComponent buttonscomp = buttonsdoc.getRootComponent();
if (buttonscomp != null) {
pane.addTab(buttonsdoc.getFile().getName(), new JScrollPane(buttonscomp));
} catch (Exception ex) {

public static final void main(String[] args) {
BasicXULSample sample = new BasicXULSample();
private class XULListener implements ScriptListener {
public void print(String message) {
public void setCurrentJSScript(JSFunctionBinding binding) {
public void showException(String message, Exception e) {
public void showException(Exception e) {

All you have to do is:

  • Create a Scriptmanager (the library provide a ready-to-use DefaultScriptManager implementation)

  • provide a ScriptListener which will be fired for actions on the javaScript side (for now, it is very very basic, I agree)

  • Add various XUL Scripts for this manager, and grab the corresponding components:

    URL test = ...;
    XULDocument testdoc = manager.addXULScript(test.toString(), test);
    JComponent testcomp = testdoc.getRootComponent();

You can already grab the code and make it work. a LOT of things need to be done on it of course, but I think it can already be useful. As soon as the ability to add other script engines than Javascript has been added I will post a first 0.1 version. For now, consider it a Beta ;-)

No comments: