JavaFX Loves Xtend
JavaFX is Java's new rich client platform. With JavaFX it is easy to create modern graphical user interfaces. It has built-in support for visual effects and animations, supports touch-aware devices and it includes an API for data-binding and event propagation. JavaFX is the official successor to Java Swing but it will result in much better looking apps.
        Xtend is a statically
        typed programming language developed at Eclipse. Based on Java, Xtend
        removes the syntactic noise and adds the missing bits such as
        type inference, lambda expressions, extension methods or
        operator overloading. It is compiled to Java code and thus
        integrates seamlessly with existing libraries and frameworks.
        Xtend brings the fun back to Java programming without any
        trade-off in terms of compatibility. Xtend's additional features
        are a perfect match to the needs of a JavaFX programmer. It will
        make your code shine the same way as a JavaFX application does.
        In this article, I will demonstrate that with a couple of
        examples.
 This article relates to Xtend version 2.4.
      
Event Listeners
        Each JavaFX Node has a couple
        of convenience methods to react on UI events such as mouse
        clicks, key strokes or multi-touch gestures. In Java a mouse
        click can for example be handled with the following code:
      
// Java code
Rectangle node = new Rectangle();
node.setOnMouseClicked(new EventHandler<MouseEvent>() {
   @Override
   public void handle(MouseEvent event) {
      System.out.println(event.getButton() + " button clicked");
   }
});
      
        Let's see how we can improve this code by using Xtend. First of
        all, Xtend's type inference allows to skip the type when it can
        be inferred from the context. So the
        Rectangle
        construction becomes
      
val node = new Rectangle
Note that semicolons can be skipped as well as empty parentheses.
        Anonymous classes with a single method such as the
        EventHandler
        instance is a very common Java idiom. Xtend improves on this
        significantly by allowing to use lambda
          expressions instead. The type is inferred from the actual
        context. In the example the expected type is an
        EventHandler<MouseEvent>
        , so the lambda expression is automatically converted to this
        type:
      
val node = new Rectangle node.setOnMouseClicked([ MouseEvent event | println(event.getButton + "button clicked") ])
        The part
        MouseEvent event |
        denotes the parameter list of the lambda. If the lambda has only
        one parameter it can be skipped and it will be named
        it
        . The parameter type is also inferred from the context, in this
        case it must be
        MouseEvent
        . Like
        this
        you can omit
        it
        as the receiver of feature call. Without the explicit parameter
        the code looks like this:
      
val node = new Rectangle node.setOnMouseClicked([ println(getButton() + "button clicked") ])
        Finally, Xtend has a shortcut
          syntax for getters and setters: Instead of
        getButton()
        you can just write
        button
        . Similarly,
        setOnMouseClicked(arg)
        becomes
        onMouseClicked = arg
        . Once again this is just syntactic sugar. The accessor methods
        are still called. Our final result reads as:
      
val node = new Rectangle node.onMouseClicked = [ println(button + "button clicked") ]
This snippet of Xtend code is completely equivalent to the Java version above. It is a lot shorter, but it is still easier to understand as all the syntactic noise has been cut out. Still everything is type-safe and well defined.
The With Operator vs Generated Builder Classes
Sometimes a JavaFX object has quite a lot of parameters to be customized. Instead of implementing a new constructor with a huge number of parameters for each use case, the JavaFX developers generated builder classes with fluent APIs, e.g.
   // Java code
   Rectangle rectangle = RectangleBuilder.create()
      .width(80)
      .height(30)
      .fill(Color.BLUE)
      .stroke(Color.RED)
      .strokeWidth(1.2)
      .arcWidth(12)
      .arcHeight(12)
      .build();
      
        In Xtend the generated boilerplate is not needed at all because
        there is the with operator
        =>
        that binds the preceding argument to the parameter of a lambda
        expression and executes the latter:
      
val rectangle = new Rectangle => [ Rectangle r | r.setWidth(80) r.setHeight(30) r.setFill(Color::BLUE) r.setStroke(Color::RED) r.setStrokeWidth(1.2) r.setArcWidth(12) r.setArcHeight(12) ]
        Using the implicit
        it
        as closure parameter and the sugared setter call as explained
        above our code becomes:
      
val rectangle = new Rectangle => [ width = 80 height = 30 fill = Color::BLUE stroke = Color::RED strokeWidth = 1.2 arcWidth = 12 arcHeight = 12 ]
Note that the Xtend code is shorter than the Java builder syntax even though it does not require an extra builder class. In a similar way, the with operator facilitates the creation of object trees, e.g. subtrees of JavaFX's scene-graph.
Extension Methods For High-Level Property Binding
        In JavaFX, the value of a property can be derived from other
        properties by means of another fluent API for the calculation.
        E.g. given two
        DoubleProperties
        a
        and
        b
        , you can bind a property
        average
        which will be automatically updated when
        a
        or
        b
        change:
      
// Java code average.bind(a.add(b).divide(2));
        When these calculations get more sophisticated and you do a lot
        of them the code becomes very unreadable. This is the right
        moment to think about overloaded
          operator extensions for JavaFX's
        DoubleExpressions
        . The code to overload an operator looks like this:
      
def static operator_plus(DoubleExpression a, ObservableNumberValue b) {
   a.add(b)
}
      
        You would usually collect all such overloading methods in a
        class
        DoublePropertyExtensions
        and make them available using a static
          extension import whenever you need them. The above Java
        example becomes as simple as
      
import static extension my.company.DoublePropertyExtensions.* //... average << a + b / 2
        Extension methods and operator overloading can also be used to
        add the missing APIs for geometry calculation, e.g. to apply a Transform to a Point3D or to
        accumulate
        Transforms
        . For detail please see the article on "Accumulating
          JavaFX Transforms With Xtend".
      
Declaring Properties
        JavaFX properties are usually wrapped in getters and setters
        to comply with the JavaBeans
        specification. For a lazily created
        DoubleProperty
        radius
        the recommended
          code looks like this:
      
//Java code
public class Balloon {
   private DoubleProperty radius;
   private double _radius = 20;
   public double getRadius() {
      return (radius != null)? radius.get() : _radius;
   }
   public void setRadius(double value) {
      if (radius != null)
         radius.set(value);
      else
         _radius = value;
   }
   public DoubleProperty radiusProperty() {
      if (radius == null)
         radius = DoubleProperty(this, "radius", _radius);
      return radius;
   }
   // ...
}
      
        This is a lot of code for a simple property and a perfect use
        case for a new language feature of Xtend: With Active
          Annotations you can manipulate how Xtend is compiled to
        Java. In our case, you could implement an Active Annotation
        @FXBean
        that describes the code pattern above. If an Xtend class is
        annotated as
        @FXBean
        , this pattern is expanded for all its fields in the generated
        Java code automatically by the compiler. So the Xtend version
        becomes
      
@FXBean
class Balloon {
   double radius = 20
   //...
}
      
        The exemplary code for
        @FXBean
        can be found here.
        Note that Active Annotations are loaded from the
        classpath of the project at compile time, thus can reside in the
        same workspace as the client code. They neither have to be
        deployed to be used nor shipped with the application code. For
        more infos on Active Annotations please refer to the
        other article in the newsletter.
      
I hope I could convince you that JavaFX and Xtend make a perfect couple. If you want to stay up-to-date with our work on Xtend, join us on Twitter or ask your questions in our Google Group.
About the Authors
