Some Vaadin at last.
Download Vaadin from here and unpack it. You only really need the minimal one jar download, but with documentation this well written it’d be a shame not to grab it all.
They have platform specific downloads because some pieces of the underlying GWT toolset use SWT. As far as I can tell, there’s no runtime platform specificity and I’m not going to be touching the GWT tools in this series, so don’t worry about it.
From the download copy the vaadin-6.0.0.jar file ( hidden inside the WebContent directory if you downloaded the full installation ) into your spike/lib directory.
SBT adds any jars it finds in the lib directory to the classpath. Old-school styling baby!
And now some code.
The first “why don’t you follow along at home” example from the Book of Vaadin is on page 24.
You need to configure the Vaadin servlet in the web.xml file. Sorry, back to the XML grindstone.
Insert this into the web-app element:
<display-name>myproject</display-name> <context-param> <description>Vaadin production mode</description> <param-name>productionMode</param-name> <param-value>false</param-value> </context-param> <servlet> <servlet-name>Spike Application</servlet-name> <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class> <init-param> <description>Vaadin application class to start</description> <param-name>application</param-name> <param-value>spike.SpikeApplication</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Spike Application</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
The web.xml will now route all requests through the Spike Application servlet that’s will look for the spike.Application class. I’ve changed the class and package name from the example to match the project and to keep package hierarchies short-ish.
The original Java code on the first example looks like this:
package com.example.myproject;
import com.vaadin.Application;
import com.vaadin.ui.*;
public class MyprojectApplication extends Application
{
@Override public void init() {
final Window mainWindow = new Window("Myproject Application");
Label label = new Label("Hello Vaadin user");
mainWindow.addComponent(label);
mainWindow.addComponent(
new Button("What is the time?",
new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
mainWindow.showNotification("The time is " + new Date());
}
}));
setMainWindow(mainWindow);
}
}
Not too bad. Particularly when you consider what it generates - a full page of HTML with a button with a server-side call back that displays the server time on screen in an area that fades out after a few seconds.
Not too bad, but I think Scala can do better. Stage 1 - Transliteration.
Create the application class:
~/code/spike : mkdir src/main/scala/spike ~/code/spike : touch src/main/scala/spike/Application.scala
Then edit the class so that it looks like so:
package spike
import com.vaadin.Application
import com.vaadin.ui._
import java.util.Date
class SpikeApplication extends Application {
override def init(): Unit = {
val mainWindow = new Window("Spike Application")
val label = new Label("Hello Spike Application User!")
mainWindow.addComponent(label)
mainWindow.addComponent(
new Button("What is the time?",
new Button.ClickListener() {
def buttonClick(event: Button#ClickEvent) {
mainWindow.showNotification("The time is " + new Date())
}}))
setMainWindow(mainWindow)
}
}
Start Jetty:
~/code/spike : sbt >jetty-run
Then navigate to http://localhost:8080
Exciting - not so much. Still, the Scala here is pretty much identical to the Java code. It is nice to know that you can take a piece of Vaadin code and translate it without too much trouble. But if the Scala isn’t any better - then Java would be a ’safer’ choice.
Let’s see if we can pimp this code.
Hmm, I don’t like the inner class listener. In Java this is the best choice, in Scala we have more choices. Closures/Blocks/BlockClosures/Anonymous Functions/Lambdas/Anonymous Delegates/whatever you want to call them. to the rescue. We can create a button that takes a closure and never have to write one of those ugly little inner classes again.
Another thing that bothers me is that call to setMainWindow. Inheritance like this makes testing and TDD harder because I’m tied into the way the Application class works. I don’t like that. That’s not a game I’m going to play. I’ve an idea of how to extract us from that hole using abstract traits. But that can wait until I try writing tests.
After removing the inner class, slight blemishes in the rest of the code became more obvious so I’ve done a spot of in-lining and removed a few extraneous braces. I often find that once you can’t see the little pimples until you’ve removed the massive warts. Anyway, the code now looks like this:
package spike
import com.vaadin.Application
import com.vaadin.ui._
import java.util.Date
class SButtonClickListener(action: Button#ClickEvent => Unit) extends Button.ClickListener {
def buttonClick(event: Button#ClickEvent): Unit = {
action(event)
}
}
class SButton(text: String, action: Button#ClickEvent => Unit) extends Button(text, new SButtonClickListener(action))
class SpikeApplication extends Application {
override def init: Unit = {
val mainWindow = new Window("Spike Application")
mainWindow.addComponent(new Label("Hello Spike Application User!"))
mainWindow.addComponent(
new SButton("What is the time?", _ => mainWindow.showNotification("The time is " + new Date)))
setMainWindow(mainWindow)
}
}
But, but, but, that’s longer I hear you cry. Yes it is. But the first two classes can be pulled out and stored away somewhere and you’re free of inner class event handlers for every button hence-forth.
The important part is the init method, isn’t that much cleaner than before? You create a window, add a couple of components and pass it on.
For my money, this is a win.
Swap this code into place, execute a:
>jetty-restart
and take a look to make sure it hasn’t changed.
Next time - continuous build and deploy and on to the next example.

Recent Comments