Enhanced Navigation in Vaadin with NavigationBuilder

Developing your navigation needs in default Vaadin is ok, but I thought it could be enhanced a bit. Hence the idea of creating a new addon, NavigationBuilder.

The Idea Behind the Addon

In fact there where multiple reasons why I wanted to create some additional navigation functionality. Chaining calls to build navigation actions seemed just right. With such an approach you can achieve incredibly readable code, when properly formatted.

Besides the readability and the need to create navigation calls in a unified way, I thought that navigation actions often provide good events to trigger your own custom code. An event-handling implementation seemed suitable.

The general purpose was to make it all easier and more accessible. I also wanted to bundle refresh, back and next actions in the implementation, as they are simply navigation calls.

Builder Approach

It seemed fairly logical to apply a builder-pattern in the library. Let’s crack on with a quick example.

NavigationUtils.navigate()
                .to("www.google.com")
                .inNewTab()
                .withListener(event1 -> 
                 LOGGER.trace("Navigating to external url in a new tab."))
                .go();

With the above formatting, the chained calls are easy to read. The opening method NavigationUtils.navigate(); provides us with the Builder object from which we’ll always start. In the example above we specify an external destination url and we tell the builder that we’ll want to open the link in a new tab. After that, we attached a listener that executed our own custom code (in this case a simple log output line). Calling .go(); will build our navigation action and perform it right away. Straight forward, right?

In fact, many calls are optional and can simply be left out. The action can also be stored in a variable for later execution. That would look something like the next example.

NavigateExecutor navigation = NavigationUtils.navigate()
                .to("http://thibaulthelsmoortel.be")
                .build();
navigation.perform();

This way you can prepare all the required actions beforehand and just perform them whenever needed.

Reduced Boilerplate

At the moment of writing boilerplate code can be slightly reduced. The NavigationUtil class contains a few methods with very common navigation needs pre-configured.

Here are a few examples of how you could use those pre-built actions.

NavigationUtils.createReloadNavigation().withListener(l -> System.out.println("Page reloaded!")).go(); // Adding a listener to the pre-configured navigation.
NavigationUtils.createBackNavigation().go(); // Go back one page in the browser history
NavigationUtils.createNextNavigation().go(); // Go one page forward in the browser history

In fact, that pretty much sums it all up for now. If you have additional ideas for expanding the project, feel free to share them. I will respond to questions and feedback in comments.

If you are experiencing issues, please file them on GitHub. They will all be looked at.

The addon’s version at the time of writing is 1.1.2. Note that the addon will get updated every so often, so be aware of changes.

Interested in other Vaadin stuff? You might as well read my latest Vaadin related article about loading animations.

Adjust Loading Animations in Vaadin

By default, loading animations in Vaadin are already pretty awesome, though you might want to adjust them to make them fit better with your custom theme.

While tweaking around with the animations myself, I found that there wasn’t too much information to find about it around the web, so here’s me contributing.

It’s All CSS

To adjust the loading animations, there’s actually no need at all to fiddle in Java code. Everything can be easily set up in css. You only need to edit one file, which would be your custom theme’s scss file.

First of all, it is important to know that the styling for the animations is not located under the .v-app class. All the editing can be done top-level, right after the base theme include statement. For the Valo theme, this would be right after the following line: @include valo;.

Top Loading Indicator

In this example I will cover a minor tweak to the loading bar you see on the top of the page, which by default is blue. It is displayed upon page navigation.

To simply adjust the color you can use following code snippet, where all style attributes are just coppied from the default styling. The only property you’ll want to tweak will be the background-color one.

.v-loading-indicator {
    position: fixed !important;
    z-index: 99999;
    left: 0;
    right: auto;
    top: 0;
    width: 50%;
    opacity: 1;
    height: 4px;
    background-color: red;
    pointer-events: none;
    -webkit-transition: none;
    -moz-transition: none;
    transition: none;
    -webkit-animation: v-progress-start 1000ms 200ms both;
    -moz-animation: v-progress-start 1000ms 200ms both;
    animation: v-progress-start 1000ms 200ms both;
}

Connection Lost Spinner

Since we’re at it, we might as well adjust the color of the spinner that shows when the connection was lost. Once again, this snippet must be placed outside the .v-app class. Obviously, if you want to adjust all spinners application-wide, apply the styling to the .spinner class only.

The resulting box with spinner.
The resulting box with spinner.
.v-reconnect-dialog .spinner {
    border-top-color: red;
    border-right-color: red;
}

Centered Loading Spinner

Vaadin’s default spinner is shown upon page refresh, for instance. At least in the Valo theme, it is relatively small. Its’ styling is somewhat basic, so it might be good to give it a more customized touch, like the spinner below.

A custom loading spinner.
A custom loading spinner.

Right along the previously provided css snippet, another one can be placed. Following example shows how to replace the default spinner with our own.

.v-app-loading::before {
    opacity: .8; 
    filter: alpha(opacity=80); 
    width: 100px; height: 100px; 
    background: transparent url(../customtheme/img/spinner.gif); 
}

Update the Vaadin Theme

After these small tweaks in this one file you are all set and ready to check out the result of the applied changes.

Keep in mind that you will need to update the theme first. Vaadin has this Maven plugin com.vaadin:vaadin-maven-plugin:8.0.0, that you can add to your pom.xml. Once added, you can simply update and compile the theme and rebuild your project. Besides that, you will probably have to clear your browser’s cache before reloading your application. If you don’t do that, a previous version of your theme’s css file will be used.

First Impressions On Vaadin

Lately I have been working a bit with Vaadin, a web UI framework for business applications. The framework offers an experience similar to Swing. ‘Similar’ is a very important word here. Vaadin uses a component based approach as well, but it is not at all a carbon copy of Swing.

Vaadin Logo

All Java

The main advantage about Vaadin is that its framework is written in Java, meaning that you could place your UI logic right next to your Java back-end logic. No need to hop from Java to Javascript or whatever other front-end programming language.

All of your UI code will run server-side. Vaadin will take care of server-client communication.

There is one small catch though. Custom styling is done in CSS (scss), so if you want to create a personalized theme, you will have to tweak around quite a bit in CSS files.

Strengths & Shortcomings

Vaadin’s biggest advantage is that you can use it to quickly create decent web application UI. You can even create your own theme fairly easily.

The framework is also struggling with some frustrating flaws. By default, Vaadin lacks the possibility to add Components to a Grid. If you want to do that anyway, you would have to install an addon. If the addon uses a widget set, it isn’t even a straight-forward installation.

Besides that I can provide a good example of an annoying flaw in Vaadin. As I was developing a Window that contained a Grid, I had the requirement to bind a boolean value to a column. The column wouldn’t just contain the boolean value as a String, but it was to be displayed as an OptionGroup with two values, ‘yes’ and ‘no’, with the correct value selected based on the boolean’s value.

The binding process went as follows: I defined a BeanItemContainer and from that I created a GeneratedPropertyContainer. On that container I performed calls of addGeneratedProperty() (for the OptionGroup I made use of a custom PropertyValueGenerator returning the OptionGroup to be displayed) . After all that I called setContainerDataSource() on the Grid. That was binding done, or at least I believed so. Once checking out the result in the UI, I noticed all cells were properly bound to their respective data, except for the OptionGroup one. Even more bizarre was the fact that at the time that a new record was added to the Grid, the data was correctly bound to all the OptionGroup cells. Somehow the Grid didn’t initialize correctly, I figured.

So it was time to find some workaround to this issue. Of course things went all smooth when using a CheckBox in stead of an OptionGroup, but that wasn’t really the requirement. Anyway, while playing around with Vaadin in some other personal project, I found out about vaadin-push. That is basically a dependency that enables you to update the UI from a different thread.

I ultimately fixed the issue by calling grid.getUI().push() right before calling grid.setColumns(). That did the trick, allthough it doesn’t look quite right.

Conclusion

I have been playing with the Vaadin framework for a few weeks now, and I’m sure I haven’t seen half of it yet. Overall I can say I’m satisfied with it, except for some frustrations that can arise on banal aspects. It is really easy to write UI fragments that are easy to read. It isn’t really hard to get into the basics. I also have to say it runs absolutely smoothly on any of my Tomcat configurations.

Overall, the framework is an excellent tool for web developers, but it is also an imperfect one. However, it is good to know that the company takes note of what developers are saying and they are always ready to help out.

If you’d like to see what Vaadin looks like, I strongly suggest you to play around with the Vaadin Sampler.