Skip to main content

Building Vaadin UI with Xtend

Today I have decided to say hello to Xtend . I had wish to learn some new programming language. The list of the criteria for choosing one, wasn't so big .

  • It must be a programming language running on JVM,
  • and it would be nice if i don't need to learn completely new eco system for building application. 

I have checked a few options. The list of programming language for JVM is quit big, but at I was deciding between the following ones: Groovy, Scala and Xtend. At and i have choose Xtend.
Scala did not fit well in my criteria, on the other hand groovy fits my criteria but it will be the next programming language which i will learn, after Xtend. It is hard to explain why I choose Xtend. I don't even think that the Xtend is a programming language, it's more like extension, but it's my opinion.  

What is Xtend

So here is a few words about the language. For more info go on the Xtend web page.
It's nice and simple language which modernize Java. Instead of compiled byte code, Xtend is translated in to pretty-printed Java class, which makes it suitable for working with platforms which don't work with byte code like GWT. The code written in Xtend produce Java classes, as i already mention, so there is no limitation in usage of any existing Java framework.
The language is created with Xtext so it comes with already prepared Eclipse, and there are maven plugins for the language, so using it out of Eclipse will not be a problem.

Learning

Learning Xtend is not hard. There is a few syntax changes and few new semantics concepts which are currently missing in Java. There is nothing revolutionary comparing to the other programming language, Xtend just extends Java with the new feature which will allow you to create nicer,shorter classes.
The features which get most of my attention were closure, lambda expression and extensions. Those stuff allow you to create a really nice builder classes. You can easily create UI Builders API, which will allow you to create simpler view(not in context of functionality, but in context of understanding of code) .

Engaging Xtend

I've already mentioned that Xtend is build with Xtext, and that means that eclipse is already able to correctly handle Xtend language. After creating new Xtend class eclipse will complain about missing libs and offer you to add them in the class path, if you do not use maven for getting dependencies.
The goals of this blog post are to show how Xtend can improve the way of building UI
I've found nice examples for JavaFX, GWT ... but I didn't find anything for Vaadin, so I have decide to build a simple class for building Vaadin UI. Or to be more precise just a segment of it. The following example is not fully implemented and it can build just some part of UI, but it can be easily extend.
Vaadins UI is example of imperative UI written in the Java. Process of building UI is similar to the building imperative UI in GWT or SWT. Here is the simple example how it looks like:
1:  package org.pis.web.application;  
2:  import org.eclipse.xtext.xbase.lib.InputOutput;  
3:  import com.vaadin.Application;  
4:  import com.vaadin.ui.Button;  
5:  import com.vaadin.ui.Button.ClickEvent;  
6:  import com.vaadin.ui.Button.ClickListener;  
7:  import com.vaadin.ui.HorizontalLayout;  
8:  import com.vaadin.ui.Panel;  
9:  import com.vaadin.ui.Window;  
10:  @SuppressWarnings("serial")  
11:  public class MainWindow extends Application {  
12:   public void init() {  
13:   Window main = new Window();  
14:   HorizontalLayout hl = new HorizontalLayout();  
15:   Panel panel = new Panel();  
16:   final Button button = new Button("First button");  
17:   button.addListener( new ClickListener() {  
18:    @Override  
19:    public void buttonClick(ClickEvent event) {  
20:    sayHello("Hello First Button");  
21:    button.setCaption("First button clicked");  
22:    }  
23:   });  
24:   panel.addComponent(button);  
25:   Button button2 = new Button("Second button");  
26:   button2.addListener(new ClickListener() {  
27:    @Override  
28:    public void buttonClick(ClickEvent event) {  
29:    sayHello("Hello Second Button");  
30:    }  
31:   });  
32:   main.addComponent(hl);  
33:   setMainWindow(main);  
34:   }  
35:   public void sayHello(final String string) {  
36:   InputOutput.<string> println(string);  
37:   }  
38:  }  

The example above is typical implementation of Vaadin UI, and my goal is to make it easier and more readable. To do that I will start with the builder class.

Making UI Builder API

For getting nicer way for creating UI, I will create a component builder first. This is not a standard implementation of builder pattern, like we can do in pure Java. Actually we are building extension class. This class contains extension methods which will extend existing class with new methods.
And here is implementation of the class.
1:  package org.pis.web.application  
2:  import com.vaadin.ui.Window  
3:  import com.vaadin.ui.Button  
4:  import com.vaadin.ui.Panel  
5:  import com.vaadin.ui.HorizontalLayout  
6:  import com.vaadin.ui.ComponentContainer  
7:  class ComponentBuilder{  
8:   def window ( (Window) => void initializer){  
9:   new Window().init(initializer)  
10:   }  
11:   def panel( ComponentContainer it, (Panel) => void initializer){  
12:   val panel = new Panel().init(initializer)  
13:   it.addComponent(panel)  
14:   return panel  
15:   }  
16:   def horizontalLayout (ComponentContainer it, (HorizontalLayout) => void initializer){  
17:   val hl = new HorizontalLayout().init(initializer)  
18:   it.addComponent(hl);  
19:   return hl  
20:   }  
21:   def button ( ComponentContainer it, (Button)=> void initializer){  
22:   println('Button in panel creation')  
23:   val that = new Button().init(initializer);  
24:   it.addComponent(that);  
25:   return that  
26:   }  
27:   def private <t> T init(T obj, (T) => void init){  
28:   init?.apply(obj)  
29:   return obj   
30:   }  
31:  }  
The builder class alone can not do so much, it has basic functionality like building window, adding the different kinds of panels and button, and if you are familiar with Vaadin you know that there is a lot more components built in the framework.
Almost all methods in the builder have two parameters. First parameter represent container class which will handle new component, and second parameter is closure which will contain code for the component initialization.

Making UI

The code, in the following snippet, is illustration of using builder class for building a Vaadin UI. The first line, in the class body, include ComponentBuilder as an extension. And powerful Xtend's lambda syntax allows that the code looks more simple and easier to understand. This way we eliminated Java's inner class and lot of boilerplate code which we would have in the case of pure Java. More about Xtend lambda expressions can be found in Xtend's documentation
1:  package org.pis.web.application  
2:  import com.vaadin.Application  
3:  import com.vaadin.ui.Button  
4:  class MainWindowXtend extends Application{  
5:    extension ComponentBuilder = new ComponentBuilder  
6:    override init() {   
7:       mainWindow = window[  
8:               horizontalLayout[  
9:                   panel[  
10:                      button[  
11:                          caption = "First button"  
12:                          it.addListener()[  
13:                            sayHello('Hello First Button');  
14:                            component as Button  
15:                            component.caption = 'First button clicked'  
16:                         ]  
17:                      ]  
18:                      button[  
19:                          caption = "Second button"  
20:                          it.addListener()[  
21:                            sayHello('Hello');  
22:                         ]  
23:                      ]  
24:                   ]  
25:               ]  
26:            ];   
27:     }  
28:     def void sayHello(String string) {   
29:       println(string)  
30:     }  
31:  }  

Conclution

So this is really nice language, learning process take just few hours. Documentation is well written, the main language concept is shown in about 50 pages. After few hours you are ready for improving you application. This is something how Java should look like. In short, playing with Xtend was fun and it is worth of investing time.

Comments

Popular posts from this blog

Checking file's "magic numbers"

Few days ago I had very interesting task. Our customer required that we perform checking of so called file's "magic numbers" to determinate does uploaded file correspond to it's extension.  We are already allowed only to upload files with some predefined extensions (PDF, DOC ...). But this can not prevent some evil user to update an exe file after renaming it to PDF or DOC. So first of all I will explain what are "magic numbers", and then I will show how we handle them.

Running Spring Boot Web App on the Random Port from Port Range

By default the spring boot web application is listening on the port 8080 for the incoming connection. This behavior can be changed by providing server.port property value during starting of the application or as part of the application.properties or through the code by implementing EmbeddedServletContainerCustomizer. But it would be even better if we could specified a range of the ports which can be used for the starting the application. It would be great if I could specify a property like server.portRange=8100..8200 to define a list of the port on which I want to start my service. In this blog post I will describe how this can be done.

Simple Workflow Engine With Spring

Few months ago, during working on one of the company project, we had need to developed  REST services which is used for sending an email depending on data sent by client application. During developing this service we decide to create simple workflow engine which will be charged for sending an email, but also this engine can be used for any kind of simple flows. In this article i will explain step by step how you can implement your simple workflow engine which can handle sequence flow.