If you know me a bit, you won't be surprised that I tried implementing a simple graph editor first. I will blog on that particular application in a separate post. Even though JavaFX is not primarily a graphical editing framework, it offers a lot of the required features, e.g.
- State of the art rendering and CSS styling
- A life scene-graph with affine transformations in all nodes
- An easy way to do data-binding and event propagation
- Easy to use APIs for effects and animations
- Built-in support for tablets and touch-aware devices
Lambda Expressions For Event Listeners
Each JavaFX Node has a couple of convenience methods to react on on UI events, such as mouse clicks, key strokes or multi-touch gestures. A mouse click can for example be handled asNode node = new Rectangle(); node.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { System.out.println(event.getButton() + " button clicked"); } });Xtend's lambda expressions (aka closures) are automatically coerced to interfaces with a single method. Using the implicit parameter it and the shortcut syntax for property access the above becomes
val node = new Rectangle node.onMouseClicked = [ println(button + " button clicked") ]
The With Operator => Obsoletes Builders
JavaFX has a couple of objects that need quite a few parameters to be customized. Instead of implementing a new constructor with a huge number of parameters for each use case, the JavaFX developers generated fluent builder APIs, e.g.Rectangle rectangle = RectangleBuilder.create() .width(80) .height(30) .fill(Color.BLUE) .stroke(Color.RED) .strokeWidth(1.2) .arcWidth(12) .arcHeight(12) .build();In Xtend, we have the with operator '=>' that binds the preceding argument to the parameter of a lambda expression and executes the latter. So we can achieve the same as above with an even shorter syntax and without the need for an accompanying builder class:
val rectangle = new Rectangle => [ width = 80 height = 30 fill = Color::BLUE stroke = Color::RED strokeWidth = 1.2 arcWidth = 12 arcHeight = 12 ]The with operator also facilitates the creation of object trees, e.g. subtrees of JavaFX's scenegraph.
Extension Methods For High-Level Property Binding
In JavaFX, properties can be derived from other properties by means of another fluent API for the calculation. The result is the best you can achieve with pure Java, e.g. given two DoubleProperties a and b, you can bind a mean value property which will be automatically updated when a or be change:mean.bind(a.add(b).divide(2));If these calculations get more difficult and you do a lot of them it will get quite unreadable. This is the right moment to think about overloaded operator extensions for DoubleProperties. With these, the last line can become as simple as
mean << a + b / 2Extension 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.
No comments:
Post a Comment