Thursday, December 22, 2011

Building SWT User Interfaces with Xtend

Xtend is a programming language that compiles to Java, but adds new features, such as closures. This article applies Xtend to implement SWT UIs and shows how the resulting code can be more readable and concise compared to Java.

When you’ve been programming desktop applications with Eclipse before, you probably have used the Standard Widget Toolkit (SWT), since it provides the fundamental UI elements (aka Widgets), such as windows, buttons, edit fields, checkboxes, etc.

The first thing you probably did was to create a window with several nicely arranged widgets. This task includes choosing the proper parent widget for all widgets, configuring layouts, etc. Then, the next step usually is to implement behavior for some widgets, so that the user can interact with the UI. This includes for example implementing selection listeners for buttons.

These two tasks have different characteristics:

  • To arrange widgets nicely, the developer's code needs to creates trees of objects. In such trees, windows are the root nodes, composites etc. the intermediate nodes and buttons, text fields, etc. are the leaf nodes. In the context of the web and HTML, an equivalent tree is the DOM (Document Object Model). For SWT, this tree becomes very visible in the XML-based approaches to specify UIs, such as CookSwt and swtxml.
  • To implement behavior, the developer usually creates anonymous or nested classes in Java. These classes implement event handlers and are registered as event listeners.

SWT User Interfaces are usually implemented using Java. However, the way to implement both patterns in Java bears room for improvement, because:

  • Java doesn’t have a special pattern to create trees. The standard pattern is to imperatively create objects and establish references between them. Whether the resulting objects form a tree or a graph is not obvious to the reader of the code, since for him/her it is just a linear sequence of statements.
  • Anonymous classes in Java have a particularly noisy syntax. The extreme scenario (which is fairly common) is when the actual code that handles the event is only a single Java statement. In this scenario, the majority of the code is not the execution logic of the handler, but the declaration of the class and the handlers method.

Designing User Interfaces using Trees: Builder Syntax

Xtend offers to improve the situation due to its support for a builder syntax and its support for closures.

  • Builder syntax is a pattern that creates an object tree and allows the code to be formatted like a tree (using indentation an brackets).
  • Closures allow to define instructions that can be executed later. You may perceive it as similar to an anonymous class with a single method, but without the syntactic overhead of a method declaration.

The following snippet illustrates the builder syntax in Xtend. As indicated already, the style of the code reflects the tree structure of the SWT widgets. This example creates a shell with one label, one text filed and one button. Additionally, it arranges them using a GridLayout.

Builder Syntax

val shell = newShell(display) [ 

    layout = new GridLayout(3, false)

    newLabel(SWT::NONE) [ 

        text = "To:"


    newText(SWT::BORDER) [

        layoutData = newGridData() [

            grabExcessHorizontalSpace = true

            horizontalAlignment = SWT::FILL



    newButton(SWT::PUSH) [

        text = "Send"



To understand the code from the Xtend code snippet above and to compare it with Java, the following things may be noteworthy:

  • All referenced elements in the snippet are Java elements from SWT, except for the new*()-methods. Those are methods implemented in a custom Java factory class. They all conform to the following pattern illustrated in the next code snippet.

    public static Button newButton(Composite parent, int style, Procedure1<Button> init) {

        Button btn = new Button(parent, style);


        return btn;


    The new*()-methods can be invoked from the snippet like member methods since they have been imported as extension methods. Extension methods are methods defined in a different class which can be invoked like member methods on any kind of object that the method accepts as its first parameter. In the snippet, the extension methods are invoked on the implicit variable it.
  • You probably have noticed that all invocations of new*()-methods are followed by a code block surrounded by brackets "[]". This code block defines a closure which is passed as the last parameter to the new*()-method. You could as well pass in the closure explicitly as the last parameter to the method. However, this syntax can improve readability of the code. Since the closure has one parameter and no return value, its class implements interface Procedure1 (src).
  • No closures in this example declare parameters. However, they do have one implicit parameter. An example of a closure with parameters is [param | param.doSomething() ]. Xtend supports an implicit variable named it. If a closure has a parameter but does not declare the parameter, the parameters' value can be accessed through the variable it. Usage of the variable it is implicit in the same way as you know it from this, with the difference that you can not assign new values to this. When accessing members of it (e.g. horizontalAlignment), stating the name it is optional. Furthermore, you can invoke extension methods on it: In the code snippet, the method newText(Composite, int) has two parameters. The value for Composite is the value of it from the surrounding closure, which is in fact the shell (the window).
  • Xtend allows to use Getter/Setter-pairs like properties: Instead of setText("Send") you may write text = "Send"

Using Closures to make User Interfaces Interactive

To implement event handlers it is common in Java to use anonymous or nested classes. The snippet below uses Xtends closures to do the same in a syntactically more concise way.

Event Handling

newButton(SWT::PUSH) [

    text = "Send"

    addListener(SWT::Selection) [

        newMessageBox((widget as Control).shell, SWT::OK) [ 

            message = "Hello World"




The snippet above uses the Builder Syntax (as described in the last section) to create a Button. When the button is clicked, a MessageBox will be created and shown to the user.

The interesting part here is addListener(int, Listener) . This method accepts two parameters with the second parameter being an instance of interface Listener (src) . In the snippet the second parameter for addListener is a closure (the code block surrounded with [] in addListener(SWT::Selection) [ ... ] ). When the Xtend code is compiled to Java, the closure is compiled into an anonymous Java class which implements the interface Listener . This, however, is only possible for interfaces that have just a single method.

A Comprehensive Example

Builder Syntax and Event Handling

package blog_001_xtend_and_swt

import org.eclipse.swt.SWT

import org.eclipse.swt.layout.GridLayout

import org.eclipse.swt.widgets.Display

import static extension blog_001_xtend_and_swt.XtendSWTLib.*

class MessageForm {

    def static void main(String[] args) {

        new MessageForm().run(args)



    def void run(String[] args) {

        val display = new Display()

        val shell = newShell(display) [ 

            setSize(400, 400)

            layout = new GridLayout(3, false)

            newLabel(SWT::NONE) [ 

                text = "To:"


            val to = newText(SWT::BORDER) [

                layoutData = newGridData() [

                    grabExcessHorizontalSpace = true

                    horizontalAlignment = SWT::FILL



            val send = newButton(SWT::PUSH) [

                text = "Send"


            val msg = newText(SWT::BORDER) [

                layoutData = newGridData() [

                    grabExcessHorizontalSpace = true

                    grabExcessVerticalSpace = true

                    horizontalSpan = 3

                    horizontalAlignment = SWT::FILL

                    verticalAlignment = SWT::FILL 



            send.addListener(SWT::Selection) [

                newMessageBox(, SWT::OK) [ 

                    message = to.text + "\n" + msg.text





        while (!shell.isDisposed()) {

            if (!display.readAndDispatch())







Anonymous said...

still to much code to achive one small window .

Anonymous said...

Nice - I'm working on a DSL for JavaFX 2.0 using xText ( What I'm not sure it is a good idea is if one should mix UI-Construction and Behavior in the same code

skin27 said...

55 lines isn't that much (try a gui generator), more important is that the code is readable.

Besides this, the example is more about showing how the closures work in Xtend.

If was wondering what this line does:

import static extension blog_001_xtend_and_swt.XtendSWTLib.*

Also when swt properties are left out, does this give sane defaults. Can Xtend change this?

I also tried to make a simpler approach without the closures. Could some of it applied to default code:

class userinterface {

    def main(){

    gui = swtGui(layout = grid)
    button1 = swtButton(text = "Send")
    field1 = swtTextField(size = 20,400
                                      label = "To:")
    area1 = swtTextArea(size = 400,400)



Moritz Eysholdt said...

What I'm not sure it is a good idea is if one should mix UI-Construction and Behavior in the same code

Yes, that's reasonable for larger applications. I didn't do it for my example because I wanted to keep it as simple as possible.

If was wondering what this line does:
import static extension blog_001_xtend_and_swt.XtendSWTLib.*

This line makes all static methods from Java Class XtendSWTLib available as extension methods. In the example that are methods such as newLabel(...), newShell(...), etc.

Also when swt properties are left out, does this give sane defaults. Can Xtend change this?

Since this approach uses self-defined library methods (defined in XtendSWTLib), you can introduce any defaults you like. Xtend itself is agnostic of SWT.

About your code example:
You're avoiding closures by implementing the behavior directly inside the applications message-loop. This approach may lead to bloated code once the application gets larger because there is only one message loop per UI-thread. Event handler (independently of whether they are implemented with closures or java classes) solve this elegantly since they are registered on the widgets and since they don't require you to modify the thread's message loop.

Nick Edgar said...

Nice. Have you looked at Glimmer?

Unknown said...

Very informative article.Thank you author for posting this kind of article .

Both are really good,.

Smith said...

Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Java developer learn from Java EE Online Training from India. or learn thru Java EE Online Training from India . Nowadays Java has tons of job opportunities on various vertical industry.

bahadur kaun said...

Thanks for updating this quality stuff. Treasurebox always provide you quality stuff for your home and garden.
We will also provide you outdoor furniture with home delievery.

Martin said...

very nice and Quality of the Leather Jackets are Avalible at very Affordable rates with
Nice and Comfortable touch and Quality..

Thanks Alot.

Shanthi Cabs said...

The article is very interesting and very understood to be read, may be useful for the people. I wanted to thank you for this great read!! I definitely enjoyed every little bit of it. I have to bookmarked to check out new stuff on your post. Thanks for sharing the information keep updating, looking forward for more posts..
Kindly visit us @
Madurai Travels | Travels in Madurai
Best Travels in Madurai
Cabs in Madurai | Madurai Cabs
Tours and Travels in Madurai

Rigid Box said...

Excellent Blog. I really want to admire the quality of this post. I like the way of your presentation of ideas, views and valuable content. No doubt you are doing great work. I’ll be waiting for your next post. Thanks .Keep it up!
Kindly visit us @
Luxury Packaging Box
Wallet Box
Perfume Box Manufacturer
Candle Packaging Boxes
Luxury Leather Box
Luxury Clothes Box
Luxury Cosmetics Box
Shoe Box Manufacturer
Luxury Watch Box

KIT said...

Nice blog, it's so knowledgeable, informative, and good looking site. I appreciate your hard work. Good job. Thank you for this wonderful sharing with us. Keep Sharing.
Kindly visit us @
100% Job Placement
Best Colleges for Computer Engineering
Biomedical Engineering Colleges in Coimbatore
Best Biotechnology Colleges in Tamilnadu
Biotechnology Colleges in Coimbatore
Biotechnology Courses in Coimbatore
Best MCA Colleges in Tamilnadu
Best MBA Colleges in Coimbatore
Engineering Courses in Tamilnadu
Engg Colleges in Coimbatore

Jackie Co Kad said...

Great Article
Final Year Project Domains for CSE
Final Year Project Centers in Chennai

JavaScript Training in Chennai
JavaScript Training in Chennai

Inoventic Creative Agency said...

Hello Admin!

Thanks for the post. It was very interesting and meaningful. I really appreciate it! Keep updating stuffs like this. If you are looking for the Advertising Agency in Chennai | Printing in Chennai , Visit Inoventic Creative Agency Today..

Kimberley Thacker said...

Forex Signals, MT4 and MT5 Indicators, Strategies, Expert Advisors, Forex News, Technical Analysis and Trade Updates in the FOREX IN WORLD

Forex Signals Forex Strategies Forex Indicators Forex News Forex World

Ontario Security Training said...

Shield Security Solutions Provides Ontario Security Training, Security Guard License or Security License in Ontario. Get Started Today

Ontario Security license said...

Shield Security Solutions Offers Security Guard License Training across the province of Ontario. Get Started Today!

Security Guard License | Security License | Ontario Security license | Security License Ontario | Ontario Security Guard License | Security Guard License Ontario

Christian Kenar said...

Thank you for this post! I want to follow you on facebook, but I don't see the link. If you have few followers, visit this site to get facebook followers

Henrietta Karlsnut said...

An deiner Stelle würde ich ein YouTube Video dazu veröffentlichen und YouTube Likes von hier für dieses Video erhalten. Möchtest Du das tun?

Quikads said...

So informative. I was searching like this for a few days. Thank you for sharing this information.classified ads platform in Bangladesh

aditya said...

Thanks for sharing this valuable information to our vision. You have posted a trust worthy blog keep sharing.

Derivative Calculator
How to find the height of a trapezoid
Area of a Rectangle

opbestcom said...

What a fantabulous post this has been. Never seen this kind of useful post.
I am grateful to you and expect more number of posts like these. Thank you very much.

MY homepage :::: 휴게텔