Vaadin and Scala

The Scala support in Eclipse has taken huge leaps recently with the new version
Scala IDE Eclipse plugin
. The plugin is still in beta, but it’s already very nice to use. I have updated the
Vaadin Scala HOWTO
in our wiki to reflect this.

While Vaadin does not yet have any official support for Scala it already works very well with it. However, the current Java API is not very Scala-like. I have explored this a little, and I think that it would be quite easy to create a set of wrappers that would offer a more Scala-like API for Vaadin. These wrappers would most probably be published as a Vaadin add-on.

I would like to invite everyone to suggest ideas on how the current API could be improved to be more Scala friendly.

To throw a few possible ideas out there:

  • Provide a method that can be used to configure a component without having to spread the different options (caption, size, immediateness, …) across several lines.
  • Provide a clean way to supply anonymous functions to component event listeners.
  • Provide methods to ComponentContainers to add and configure the properties (alignment, expand ratio, …) of child components.
  • Provide a clean way to access and manipulate child component sets of ComponentContainers.

These can be implemented in several ways, eg. as traits or per component basis with subclasses.

What else?

Another area where Scala’s features might be taken advantage of is its support for XML. Here is a simple example:


addComponent(new Label(<span>This is a <em>label</em> with a <b>HTML</b> caption</span>))

I’ll try to add more comprehensive support for this to the library that I’ve begun on
github

Best regards as always,

Steve

I find myself wanting to add a feature to a component or changing a behavior here ant there all the time.

I get the feeling that traits really would allow me to compose the components I now have to struggle to get together. Sometimes I have to create a single method class, instantiate it, add it to another class to get something to work. If I could send in a function It would save me some code and make it cleaner.

I’m looking forward to see what a Scala wrapper of Vaadin could offer. If I find more examples where and how Scala features could be used I post again.

Do you have an example of this particular pain point you could share? I’m pretty new to Vaadin, but have been trying to put together a
library
to address some of the spots that feel a little rough from a Scala perspective. Any input you could provide would be greatly appreciated.

Thanks and best regards,

Steve Thompson

One example would be to wrap components and allow me to add a function instead of a listener.

I’ll try to get a colleague with greater Scala experience to add more examples here.

Everyone interested in the topic should take a look what Steve has accomplished so far. His work already includes several things I’ve had in mind.

One way to allow it would be to do something like this:

trait ValueChangeListener extends AbstractField {
	def addValueChangeListener(valueChangeListener: (Property.ValueChangeEvent) => Unit) = {
		addListener(new Property.ValueChangeListener {
			def valueChange(e: Property.ValueChangeEvent) = valueChangeListener(e)
		})
	}	
}

You can mixin that to any Field, and after that it’s easy to add an anonymous function to handle the ValueChangeEvents, eg:

val dateField = new DateField with ValueChangeListener
dateField.addValueChangeListener(_ => {/* handle event */})

But traits do not support arguments, and adding a single ValueChangeListener to a Field is very common, so it might be even better to do add a subclass doing this:

class EnhancedDateField(caption: String = null, dataSource: Property = null, value: Date = null,
		valueChangeListener: (Property.ValueChangeEvent) => Unit = null)
		extends DateField(caption) with ValueChangeListener {
	if(dataSource != null) setPropertyDataSource(dataSource)
	if(value != null) setValue(value)
	if(valueChangeListener != null) addValueChangeListener(valueChangeListener)
}

Now usage is even simpler, and I can use named constructor parameters to set up the DateField:

val dateField = new EnhancedDateField(caption = "Caption", value = new Date,
	valueChangeListener = _ =>   {/* handle event */})

The downside is that we’d need to subclass (almost?) all Vaadin components. However, I think that would be prudent anyway, since we need to do it to add other enhancements to them. For example, I would like to see helper stuff like:

def getDateValue = getValue.asInstanceOf[Date]

in an enhanced DateField.

I think there are at least three approaches to adding event handlers to Vaadin, each with its own set of pros and cons:

  1. Event handlers can become arguments in the construction of Vaadin components. For relatively simple things like buttons, I think this holds a lot of appeal. It would mean doing a lot of subclassing as Henri alluded to, which might not be a big deal.

  2. Traits could be mixed in with existing classes to provide extra functionality, where desired, for a range of different components without having to create subclasses. I find this very compelling in the case of a Tree for example where there are perhaps a few different types of events (select/expand/collapse) that I have an interest in handling.

  trait TreeExpand {
    self: Tree =>
    def onExpand(action: TreeExpandEvent => Unit) = {
      addListener(new TreeExpandListener {
        def nodeExpand(event: TreeExpandEvent) = action(event)
      })
    }
  }

  trait TreeCollapse {
    self: Tree =>
    def onCollapse(action: TreeCollapseEvent => Unit) = {
      addListener(new TreeCollapseListener {
        def nodeCollapse(event: TreeCollapseEvent) = action(event)
      })
    }
  }

The downside to the traits approach is that it isn’t as concise to express.

  1. A toss up with #2 would be implicit conversions, which I’ve been using a lot of myself. Implicits would extend the functionality of a whole family of components without having to mix in anything. For instance, with this
  implicit def abstractFieldToRichAbstractField(field: com.vaadin.ui.AbstractField) = new RichAbstractField(field)

  class RichAbstractField(field: com.vaadin.ui.AbstractField) {
    def onValueChange(action: ValueChangeEvent => Unit) = field.addListener(new ValueChangeListener {
      def valueChange(event: ValueChangeEvent) { action(event) }
    })
  }

anything with a lineage back to AbstractField would be able to add value change event handlers. The downside again though is that unlike solution #1, it would require a little more expression.

What do people think? A problem that I am having is that I’ve not been able to decide on a specific strategy, which means that I don’t yet have a consistent approach to this. Any ideas would be greatly appreciated.

Best regards to all,

Steve Thompson

Hi all,

I’ve recently completed work on a web application using Vaadin, Scala and IntelliJ IDEA and Maven. I did not use Eclipse when the project started as the Scala plugin for IDE was lagging behind IntelliJ’s in ways that made development a bit difficult. But things are a lot better now and the Eclipse IDE is great for Scala work. For what it’s worth, I found myself using some patterns quite often. Here they are.

Using traits to capture UI properties such as use of margins, spacing, full height, or full width. I found that this made my code a bit more declarative. For example:

trait FullWidth extends Component{
setWidth(“100%”)
}
val table = new Table with FullWidth

Some of my widgets relied on being refreshed from time to time, so I encapsulated the logic required to use the refresher plugin as a trait that could be mixed-in to an abstract layout subclass.

In order to facilitate the styling of some of my widgets via CSS, I’ve added an auto CSS trait which automatically add a style name based on the name of the class I am trying to style.

I’ve used implicit conversions to augment components so that functions and closures can be used to handle events. I think this a pattern which has been mentioned many times.

I have augmented abstract layout subclasses with a method which creates a component, add it to the layout and returns a handler to the created component. This allows me to create and add components in one go. I use this quite a lot, as it makes the code more declarative. This also eliminates errors which occur when you create an object but forgot to add it to the container.

For example:

val myTree = myLayout add new Tree

This is shorted than

val myTree = new Tree
myLayout.add (myTree)

The Vaadin Java maven artifact is a good starting point for those working on Java-based UI with Vaadin, especially if your build process is based around Maven. I don’t think it would be a lot of work to put together a Scala equivalent. This would be very useful as good way to boostrap projects.

I hope this helps.

Guillaume

There are some broad categories within the general issue of providing a more Scala-like API for Vaadin.



Concise component parametrization

With component parameters I mean the properties found in the main interfaces and superclasses like
com.vaadin.ui.Component
,
com.vaadin.terminal.Sizeable
and
com.vaadin.ui.AbstractField
. We should provide at least one easy way to set up all of those parameters without having to spread the component setup over several lines. Personally I’m in favor of subclassing the components and making the parameters constructor arguments. They should have sensible defaults.



Flexible listener management

We have discussed this somewhat already, and everyone seems to agree that a mechanism to pass a listener as an anonymous function to a component is needed. There are a few ways to implement as outlined by Steve above.

Vaadin includes dozens of listener interfaces, but by far the most used ones are
Button.ClickListener
and
Property.ValueChangeListener
. In my opinion an acceptable way to solve this would be to allow passing the most used ones as constructor parameters in the subclasses, and leave the rest to traits or implicit conversions.



ComponentContainer management

Many methods in
com.vaadin.ui.AbstractComponentContainer
,
com.vaadin.ui.AbstractLayout
and
com.vaadin.ui.AbstractOrderedLayout
could be streamlined to make component container construction and child set manipulation more concise.

Guillaume describes one way above, and Steve’s library has more.



Data layer improvements

Construction and manipulation of containers, items, properties and validators probably have lots of room for improvement. I have no suggestions about these yet.



Miscellaneous tricks

In addition to these there are lots of other improvements and tweaks that can be done. Some of them are outlined by Guillaume above, and I think they depend a lot from the individual style of each developer.

Thoughts?

Regarding your “Data layer improvements” section, Scala has various features which make it easy to implement reusable and composable logic. You can use this for instance to format the rendering of container properties. To be a bit more specific, I’ve implemented a generic stackable trait to render date properties in a table. Because the trait is stackable, you can mix it in with other traits that customise the rendering of other properties (for example a trait to render all numeric values as right aligned). Although I’ve used traits, I am sure there are other ways of achieving the same results, maybe through the use of -partial- functions.

Hi,

I just committed some very initial stuff to the
scala-wrappers
project in our SVN. Currently, the project contains components and layouts related code.

Most of the ideas and concepts are already discussed here and in Steve’s github project, but some comments and thoughts:

Subclass each Vaadin component (com.vaadin.ui.Button vs. vaadin.scala.Button) and provide a constructor with named parametes to allow easy instantiation of components. Parameters have default values. For defining the size of a component, constructor provides named parameters width and height with default values.



Component Sizing

Implicit conversions:

Instead of

new HorizontalLayout("100%", "100%");
 
component.setWidth("300px");

can be said:

new HorizontalLayout(100 percent, 100 percent);
 
 component.setWidth(300 px);

Inspired by Guillaume’s FullWidth trait, I created FullSize and UndefinedSize traits:

new HorizontalLayout with FullSize;



Layouts

Layouts has add method for easier adding of components. To make possible to chain add calls, the method returns the layout.

val layout = new VerticalLayout(100 percent, 300 px, margin = true)
        .add(new Label("Hello World!"), 1, Alignment.MIDDLE_CENTER)
        .add(new Button("Click me!"), alignment = Alignment.BOTTOM_RIGHT)

This version of add works differently compared to Guillaume’s version that returns the added component. What do you think, which one is better?

Cheers,

-Henri

hm…
Chaining of add methods is certainly the way to go, but what’s wrong with


val layout = new VerticalLayout(100 percent, 300 px, margin = true) {
 add(new Label("Hello World!"), 1, Alignment.MIDDLE_CENTER)
 add(new Button("Click me!"), alignment = Alignment.BOTTOM_RIGHT)
}

Thanks,
Oleg.

Thanks for the tip. I’m still learning Scala :slight_smile:

-Henri

that’s actually not much different from java (see
http://www.c2.com/cgi/wiki?DoubleBraceInitialization
)
i’m not sure if that’s better way than chaining, but i’m kinda addicted to it coming from swing and gwt

Although the Scala pattern for object initialization looks like Java’s double brace initialization, it is not implemented the same way. As far as I understand, in Scala, you actually create a subclass and all statements within the curly braces are used as part of the constructor for that class. In Java, you create an anonymous inner class.

Assuming you ‘pimp’ the add method to return you a handle on the component you’ve just added to the layout, you can also build a path to any component.

For example:

To access the hello label: layout.hello

Great, thanks!

This is nice.

However, I’m not sure if I agree with the next one:

In my mind a trait is something that’s intrinsic to the object and as such can’t be modified later. This is not a case with the FullSize trait though - you can set the component height and width to something else later, and

layout.isInstanceOf[FullSize]

will return true even if the component is not full size anymore.

What do people think? Is this a problem?

In my opinion the version in Guillaume’s last post is the best one yet.

Having used jQuery and CSS to build web applications, I quite like the idea of using selectors to select a group of components which satisfy certain properties. There is a “port” of jQuery to GWT (see http://code.google.com/p/gwtquery/). I think a similar pattern can be applied to Vaadin to select components with a certain type, certain css class, or with other properties. It does not have to be based on Scala, but it might actually be easier using Scala.

I
created an implementation
based on that selector idea,. Basically it allows you to do stuff like val list = layout \ (c => c.getStyleName == "foo") which selects matching components from the layout (the \ -method would select also from it’s children).