Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 206 posts at DZone. You can read more from them at their website. View Full User Profile

Develop Vaadin Apps With Scala

04.18.2012
| 3961 views |
  • submit to reddit
Home / Develop Vaadin apps with Scala Develop Vaadin apps with Scala Submitted by Nicolas Frankel on Sat, 04/14/2012 - 11:59

More than a year ago, I tried to use Scala to develop an example Vaadin application. Even though I'm no Scala guru (far from it), I must admit results were below what I expected them to be. Time has passed and Henri Kerola, a Vaadin team member, has commited to create a Scala add-on that aims to ease Scala Vaadin integration: the Scaladin add-on (formerly known as scala-wrappers) is more than meeting my expectations.

There are four brilliant ideas I want to focus on in this article:

The first idea is to provide a simple Application with a single main window with a content set during the init() method. As a developer, I just have to override the default content and I have everything I need to quickstart my development:

import vaadin.scala.SimpleApplication
 
class VaadinScalaApp extends SimpleApplication {
 
  override def main = new CompositeFieldButton()
}

The second idea is to use Scala's named parameters to ease components configuration. In the Java API, components constructors are few and far between and generally are available in three forms: default, one with the label and the last with both label and value. If you do want no label and a value, you have to pass null as the first parameter.
In Scala, named parameters allow to write the following: 

new vaadin.scala.TextField(value = "world!")

The third idea is to use Scala's functional nature in place of anonymous inner classes for event management. In Java, event management is handled like so: 

Button button = new Button("Click");
 
button.addListener(new Button.ClickListener() {
    public void buttonClick(ClickEvent event) {
        getWindow().showNotification("Click me!");
    }
});

It's not very concise and most of the code is only boilerplate. With Scaladin, leveraging Scala's functional nature and the former point, it can be replaced by: 

new vaadin.scala.Button(action = _ => getWindow().showNotification("Click me!"))

The final idea is to provide a concise syntax for adding components. With the Java API, we have to instantiate a component in order to reference it, only can we add it to a container: 

HorizontalLayout layout = new HorizontalLayout();
 
Button button = new Button("Click me!");
 
layout.add(button);

Note: inner fields can be referenced by using the dotted notation (for example, layout.button

With the help of all previous features, I redeveloped my first Scala example with only two classes, the application (which code can be found above) and the custom component:

import com.vaadin.ui.CustomComponent
import vaadin.scala.{ HorizontalLayout, TextField, Button }
 
@SerialVersionUID(1L)
class CompositeFieldButton() extends CustomComponent {
 
  val layout = new HorizontalLayout(spacing = true, margin = true) {
 
    val button = add(new Button(caption = "Hello", action = _ => displayMessage()))
 
    val field = add(new TextField(value = "world!"))
  }
 
  setCompositionRoot(layout)
 
  def displayMessage(): Unit = {
 
    getWindow().showNotification(layout.button.getCaption() + " " + layout.field.getValue().asInstanceOf[String])
  }
}

In conclusion, where Scala and Vaadin don't play nice together, Scaladin let us really leverage Scala's power to ease our Vaadin development. If you're fan of Scala and Vaadin, you should probably run to get the Scaladin add-on.

Complete source for this article can be found here.

 

 

Published at DZone with permission of Nicolas Frankel, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Erik Post replied on Thu, 2012/04/19 - 7:15am

Instead of

def displayMessage(): Unit = {

you can write Unit methods more concisely like this:

def displayMessage() { 

You could most likely also drop the parentheses after getWindow, getValue, getCaption and so on, since they seem to be non-side effecting getters. Furthermore, isn't that last getValue() call automatically coerced to a string, so you can drop the .asInstanceOf[String]? Then you'd have something like: 

def displayMessage() {
  getWindow.showNotification(layout.button.getCaption + " " + layout.field.getValue)
}

Also, you could omit the argument names to the constuctors as long as you're supplying them in order. I don't know Vaadin, so I'm not sure this is the case here, but perhaps you could write 'new TextField("world!")' instead of explicitly naming the argument.

As a side note, I think the Scala API would be a tad nicer if it provided builders for its components, so you could write 'Button(...)' instead of 'new Button(...)'. I think Scala Swing and some Scala JavaFX API I saw do it like that. 

Nicolas Frankel replied on Sun, 2012/04/22 - 4:29am

Hello Erik,

Thanks for your excellent feedback! I updated the code with all your comments (only the TextField has to keep the attribute since the first parameter is the label, not the value).

I encourage you to contact the Scaladin developer on the add-on page to suggest builders for components. If not enough experience in Scala to know if there are reasons no to do it.

Erik Post replied on Sun, 2012/04/22 - 8:05am in response to: Nicolas Frankel

Hi Nicolas,

Cool ;) I just noticed that one of my edits has disappeared into the void though. I'll mention it again because it's a feature I quite like, especially for experimenting in the REPL or whipping up a prototype: you can also drop the parentheses from 'class CompositeFieldButton()', and from the call site.

Furthermore (sorry, it's Sunday and this sort of thing is my hobby) you have ' _ => displayMessage', where you're turning the method displayMessage into a function (eta expansion). However, the compiler can do this for you:

val button = add(new Button("Hello", displayMessage))

Sometimes, when the compiler can't infer the type, you may have to throw in a '_' after the method name. See http://stackoverflow.com/questions/2064193/why-and-when-do-i-need-to-follow-a-method-name-with.

Cheers,
Erik 

Nicolas Frankel replied on Sun, 2012/04/29 - 5:31am in response to: Erik Post

Dropped the parenthesis for the class declaration. Unfortunately, the compiler complains about dropping the _.

Erik Post replied on Mon, 2012/04/30 - 3:54pm in response to: Nicolas Frankel

Hi Nicolas, you're right, I looked up the code and Scaladin expects a function taking a ClickEvent, which is what the _ is a placeholder for. (So your displayMessage() would have had to take a ClickEvent argument in order for the underscore-less syntax to work.) My bad... Oh well, we got rid of a few characters, didn't we? ;)

Nicolas Frankel replied on Tue, 2012/05/01 - 3:53am in response to: Erik Post

Yes, and I thank you for it :-)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.