Wednesday, August 22, 2012

GWT programming with Xtend

One of the advantages of Xtend over other Java alternatives is that it translates to readable Java code, which for instance allows to do GWT programming with it.

I'm happy to announce that our nightly builds now also produce the needed GWT-compatible libs. They are not yet in the Maven repo but can be downloaded from here:

http://build.eclipse.org/common/xtend/gwt/xtend-gwt.zip

I've played around with a bit. It's very cool how much of the browser API is available in GWT. This is a demo (available on github) using HTML5 Canvas written 100% in Xtend:

Why is Xtend a good match for GWT?

Xtend code is just much more readable and expressive, yet unlike other Java alternatives it works with existing Java APIs seamlessly. Programming GWT with all its asynchronous server calls and event handlers is tedious when done in Java. Here's some code from the Java version of the canvas demo:

    // Java version
    canvas.addMouseMoveHandler(new MouseMoveHandler() {
      public void onMouseMove(MouseMoveEvent event) {
        mouseX = event.getRelativeX(canvas.getElement());
        mouseY = event.getRelativeY(canvas.getElement());
      }
    });

    canvas.addMouseOutHandler(new MouseOutHandler() {
      public void onMouseOut(MouseOutEvent event) {
        mouseX = -200;
        mouseY = -200;
      }
    });

    canvas.addTouchMoveHandler(new TouchMoveHandler() {
      public void onTouchMove(TouchMoveEvent event) {
        event.preventDefault();
        if (event.getTouches().length() > 0) {
          Touch touch = event.getTouches().get(0);
          mouseX = touch.getRelativeX(canvas.getElement());
          mouseY = touch.getRelativeY(canvas.getElement());
        }
        event.preventDefault();
      }
    });

    canvas.addTouchEndHandler(new TouchEndHandler() {
      public void onTouchEnd(TouchEndEvent event) {
        event.preventDefault();
        mouseX = -200;
        mouseY = -200;
      }
    });

    canvas.addGestureStartHandler(new GestureStartHandler() {
      public void onGestureStart(GestureStartEvent event) {
        event.preventDefault();
      }
    });
    // and so on
With Xtend this is totally elegant. And there is no intermediate Xtend library, it's just plain GWT API:
    // The same written in Xtend
    canvas.addMouseMoveHandler [
        mouseX = getRelativeX(canvas.element)
        mouseY = getRelativeY(canvas.element)
    ]

    canvas.addMouseOutHandler [
        mouseX = -200
        mouseY = -200
    ]

    canvas.addTouchMoveHandler [
        preventDefault
        if (touches.length > 0) {
          touches.head => [
            mouseX = getRelativeX(canvas.element)
            mouseY = getRelativeY(canvas.element)
          ]
        }
        preventDefault
    ]

    canvas.addTouchEndHandler [
        preventDefault
        mouseX = -200
        mouseY = -200
    ]

    canvas.addGestureStartHandler [
        preventDefault
    ]
Just try it, it's fun!