My article from last week left me mildly depressed: my efforts trying to ease my Vaadin development was brutally stopped when I couldn’t inherit from a Java inner class in Scala. I wondered if it was an impossibility or mere lack of knowledge on my part.
Fortunately, Robert Lally and Dale gave me the solution in their comments (many thanks to them). The operator used to access an inner class from Java in Scala is #. Simple, yet harder to google… This has an important consequence: I don’t have to create Java wrapper classes, and I can have a single simple Maven project!
Afterwared, my development went much better. I tried using the following Scala features.
Conciseness
As compaired to last week, my listener do not use any Java workaround and just becomes:
@SerialVersionUID(1L)
class SimpleRouterClickListener(eventRouter:EventRouter) extends ClickListener {
def buttonClick(event:Button#ClickEvent) = eventRouter.fireEvent(event)
}
Now, I can appreciate the lesser verbosity of Scala. This becomes apparent in 3 points:
@SerialVersionUID
: 10 times better than the field of the same name- No braces! One single line that is as readable as the previous Java version, albeit I have to get used to it
- A conciseness in the class declaration, since both the constructor and the getter are implicit
Trait
CustomComponent
does not implement the Observer pattern.
Since it is not the only one, it would be nice to have such a reusable feature, in other words, a Scala trait.
Let’s do that:
trait Router {
val eventRouter:EventRouter = new EventRouter()
}
Note to self
Next time, I will remember that |
Now, I just have to declare a component class that mixin the trait and presto, my component has access to an event router object.
Late binding
Having access to the event router object is nice, but not a revolution. In fact, the trait exposes it, which defeats encapsulation and loose coupling. It would definitely be better if my router trait would use the listener directly. Let’s add this method to the trait:
def addListener(clazz:Class[_], method:String) = eventRouter.addListener(clazz, this, method)
I do not really know if it’s correct to use the late-binding term in this case, but it looks like it, since this
references nothing in the trait and will be bound later to the concrete class mixing the trait.
The next stop
Now, I’ve realized that the ClickListener
interface is just a thin wrapper around a single function: it’s the Java way of implementing closures.
So, why should I implement this interface at all?
Why can’t I write something like this val f(event:Button#ClickEvent) = (eventRouter.fireEvent(_))
and pass this to the addListener()
method of the button?
Because it doesn’t implement the right interface.
So, I ask myself if there is a bridge between the Scala first-class function and single method interfaces.
Conclusion
I went further this week with my Scala/Vaadin experiments. It’s getting better, much better. As of now, I don’t see any problems developing Vaadin apps with Scala. When I have a little more time, I will try a simple app in order to discover other problems, if they exist.
You can find the sources of this article here, in Maven/Eclipse format.