or almost a year now Microsoft has been touting XAML, its XML Application Markup Language, as being a significant disruptive technology changing how you will develop your applications, and in particular the presentation layer for .NET applications.
But thanks to a juggling of internal resources, XAML, and its parent, Longhorn, have been pushed into the vague future with a constantly shifting release date sometime after 2006. However the underlying idea?the separation of user interface declaration and application service logic?is a good one and you don’t have to wait for Longhorn and XAML to start developing with that paradigm today.
Enter the Luxor XML UI Language Toolkit, or XUL for short. XUL is more than just the markup language to describe the user interface. It is also a lightweight Web server, a portal engine, a template engine, and a scripting interpreter. It was originally pioneered by Mozilla and is an integral part of the Mozilla browser.
The philosophy behind XUL is to separate the user interface into four distinct layers
- Content: The structure and description of user interface elements
- Appearance: The theme, look and feel or ‘skin’ of the application
- Behavior: The underlying logic that the user interface exposes
- Locale: The intended international location for the application.
|Figure 1. Not So Hot: The Weather Finder application in action.|
In this article you will build a desktop application in Java and XUL that consumes a public Web service to tell you the temperature at any location based on its ZIP code. You will also look into running XUL documents within the Mozilla browser. This is just the tip of the XUL iceberg, but hopefully enough to whet your appetite for more.
The application that you will develop as a sample in this article is adapted from the famous Luxor calculator app, but has been extended to make it a Web service consumer. XMethods.Net host a Web service that accepts a ZIP code and returns a temperature. The WSDL for this file is available for inspection at http://www.xmethods.net/sd/2001/TemperatureService.wsdl.
The download included with this article includes all the source code as well as the JDeveloper workspace and project files. You can use these, or if you prefer a different IDE, you will need access to the Luxor jar file, available for download from the Luxor XUL homepage at http://luxor-xul.sourceforge.net.
A screenshot of the application in action can be seen in Figure 1. You type in the ZIP code using the calculator keypad and hit the GetTemp button. The calculator then calls the XMethods Web service, passing the ZIP code and getting the temperature back, which it then displays on the screen.
In Figure 1, the ZIP code entered is 10036 (Midtown, New York City), which on the day the screen shot was taken was a cool 63 degrees.
Describing the Application with XUL
The complete user interface for this application is described in XUL. It is available for you to use in the download with this article (see left column). A snippet of this code?describing the Display and Command buttons?is shown below.
As you can see, the XUL is very straightforward XML. The
|Figure 2. Group Picture: Relating the XUL Code to the UI.|
You will notice an unusual attribute within the XUL: ‘command.’ This attribute is used in the case that you use a button to tie the XUL to your Java code. When the user clicks the button, the XUL framework bubbles an event (actionPerformed, more on this later) up to be processed by your code, with the contents of this attribute (in this case, “C” or “G”) as a parameter. It is from this that you know which button has been pressed.
The other XUL tags used in this application are
You will notice that the buttons have a command attribute. This is used to map the button to the underlying logic within the application. You will see more on this later.
Using XUL In Your Java Application
The full source for the application is in the download. The main function is found in the GetTemperature.java file. It accepts an argument, which is the name of the startup directory that contains the XUL. If, for example, your XUL is located in C:XULSTARTUPGETTEMPERATURE.XUL, then you use C:XUL here. Note that the XUL has to be in a directory called Startup for the application to work.
The constructor for the GetTemperature class contains the logic that loads and interprets the XUL. It uses the following Luxor classes to achieve this:
Table 1. The Luxor XUL classes used to load the XUL document.
|XulResourceLoader||Base Resource Loading Class for XUL Documents|
|XulFileResourceLoader||Implements XulResourceLoader, used for loading XULDocuments from the File System|
|XulManager||Provides centralized access to your GUI resources|
For more detailed information on these and the other XUL classes, take a look at the XUL Alliance homepage at http://xul.sourceforge.net/.
This code shows how they are used to get the XUL and render it in a JFrame content pane:
File rootPath = new File(strStartupPath);XulResourceLoader xrl = new XulFileResourceLoader(rootPath);XulManager xul = XulManager.getXulManager();xul.setResourceLoader(xrl);xul.load();getContentPane().add(new TemperatureForm().getJComponent());
Now that the XUL is loaded and rendered, the next thing you want to do is to tie it up with the internal logic of the application. This is done using the TemperatureForm class. In the design of the application it was identified that the buttons have two different types of operation. Some buttons act as digits, namely that they are simply used for entering numbers, and the others act as operations, meaning that they are used to run some functionality.
The digit buttons are straightforward, implementing only GUI logic, allowing the numbers 0-9 to be entered. The GUI keeps track of the order in which they are entered so that tens, hundreds etc. can be handled. There are two operation buttons, the ‘C’ (for Clear) button that resets the display to ‘0’ and the ‘GetTemperature’ button, which reads the current display setting and passes it as a ZIP code to the Web service, gets the response from the Web service, and renders it on the display.
These button types are realized with the ‘EnterDigit’ and ‘EnterOperation’ classes, respectively. The 10-digit buttons are implemented using instances of the EnterDigit class, and assigned to a helper class called ‘TemperatureLogic’ that intercepts the events from the XUL framework when an action is performed on the button. In other words, when you press a button, the XUL framework generates an ‘actionPerformed’ event, which triggers the ‘execute’ action on EnterDigit, which extends XulAction. EnterOperation works in a very similar way.
These actions raise events on TemperatureLogic called ‘enterDigit’ and ‘enterOperation,’ respectively. In the case of the former, the display is updated with the current digit. In the case of the latter, if the operation is ‘C’ (the XUL command attribute for the clear button), then the display will be cleared, otherwise ‘G’ (the XUL command attribute for the ‘Get Temperature’ button) is assumed, and the Web service is consumed. Note that these command attributes are completely under your control, and are specified in the XUL document, so you don’t have to use pre-assigned command attributes.
There are many ways of consuming a Web service with Java. Most IDEs have a wizard that creates a stub for you, or you could hand code the SOAP proxy yourself. The download contains a Web services proxy created by the Oracle JDeveloper IDE. As such it contains some Oracle-specific JAR references. If you’re not using JDeveloper, be sure to remove this proxy and replace it with the appropriate one for your environment.
If you are using a different IDE or coding your own Web services stub, make sure that you build your proxy to consume the Web service described by the WSDL hosted by xmethods.net at http://www.xmethods.net/sd/2001/TemperatureService.wsdl.
XUL Isn’t Just For Desktop Applications
As XUL is integral in the Mozilla suite, you can use XUL to build browser-based applications, too. You have to make some minor changes to the XUL from this article, wrapping it with a
You can load this XUL into your browser from the command line:
This will render in the Mozilla Firefox browser as shown in Figure 3.
|Figure 3. Browser World: You can load the XUL for the sample application into Mozilla Firefox.|
onclick="alert(event.target.label); return false;"
Clicking any of the buttons will present a dialog with the label of the button.
This article has barely scratched the surface of XUL’s possibilities. If you are a Java applications developer, the clear benefits of defining your UI declaratively using XML are obvious. Internationalization, branding, clean upgrades and a host of other capabilities become a lot easier.
Don’t forget that XUL also gives you a miniature Web server that you can embed in your apps to give peer-to-peer functionality, a scripting interpreter that is Python-based, and portal and template engines. It all adds up to a pretty compelling framework. With a rich and competent offering like Luxor XUL ready to use, it’s easy to wonder why anyone would wait for XAML.