days
-4
-3
hours
-1
-1
minutes
-5
-6
seconds
-5
-2
search
JAX Developers Puzzle deadline approaching: Play for a chance to win a complimentary JAX London 2018 ticket!
Part 3 – Binding data to components and a full stack example

Easy Swing to Web with Vaadin

Matti Tahvonen

Light image via Shutterstock

For the final part of Matti Tahvonen’s series on Vaadin web apps, we get the scoop on data binding and structuring your UI code.

Binding data means the task of moving data between your UI components and your backend/domain objects, in both directions. Some Swing users are using advanced data binding libraries like BeansBinding. BeansBinding concepts could be adapted to Vaadin applications as well, but there are also really handy built-in helpers in Vaadin.

At the heart of Vaadin data binding there are interfaces called Item and Property (and utility implementations for those). Property is also implemented by all Vaadin Field components. You can use those directly, but most often you’ll use the built in BeanItem implementation, and typically via BeanFieldGroup helper. BeanFieldGroup can automatically bind your entities/DTOs to the corresponding Field components. Similarly to BeansBinding in Swing development, this saves you from writing a huge amount of boilerplate code that basically just moves values from UI to your domain objects and vice versa.

The BeanFieldGroup in Vaadin also supports by default Bean Validation annotations, that you might have already defined into your domain objects. The same rules can then be used on the UI layer to automatically perform validation before throwing your domain objects back to business layer.

If you have ever used JTable component you are probably familiar with Swing’s interface called TableModel that is used to provide a way for JTable to list the actual data into it. In Vaadin the similar task is delegated to Container interface that contains Item instances. There are built in container implementations in the framework, of which BeanItemContainer will most probably become very familiar to you. It is a simple and efficient way to list your entities in Vaadin Table and in various select components.

Lazy loading large data sets

In your Swing apps, if you have listed big data sets into your UI, you probably know you need to be careful what you load into your applications memory. Also, as your data is probably on the server in business applications, the network usage between your server and client may easily become the bottleneck. Typically this is solved by showing just the top most results of your DB query or using some sort of “paging” when listing lots of data.

As we discussed earlier, Vaadin applications UI code has a huge aid from being executed right next to your data. The data is often already in your application servers memory or in a DB server that is either in the same physical server or most likely at least connected with strong network connection to your application server. This makes accessing the data both efficient and simple.

At the same time the well optimized UI components in Vaadin only send the essential part of your data through the wire from server to the client. For example in Table and ComboBox, only the visible parts of the data is sent to the client side and this ways network usage stays low, even when (virtually) displaying huge amounts of data.

SEE ALSO: Easy Swing to Web with Vaadin – Part 1

In case you can’t load all your data into servers memory (due to scalability, memory usage), you’ll have to do similar tricks in Vaadin as well or you might run out of memory with lots of concurrent users. Limiting the result set and using paging at UI level is naturally in basic tools for Vaadin developers as well.

But as UI components already do “lazy loading” between your server and client, you can also extend the lazy loading chain all the way to the database using “lazy loading” implementations of the Container API. You can pretty easily write a totally custom version for your specific use case, but the strongly suggested method is to use helpers like LazyList or LazyQueryContainer instead. In most lazy loading cases, those are the tools that you really should use, but in some architectures you can also consider using SqlContainer or JPAContainer which do rather optimized lazy loading automatically as well.

Structuring your UI code

If you have maintained a large Swing application, you probably know it is possible to write messy code, even with Java and its static typing and great IDEs. For large desktop applications, especially with large teams and long maintained projects, you have probably applied some sort of design patterns like MVC or MVP to structure your UI code.

The very same applies to Vaadin code as well. In large applications you most likely want to use some sort of strict rules to structure your code. In smaller applications it is fine to just separate logical parts of your UI to different, possibly reusable, classes.

Thanks to similarities with Vaadin and Swing, you can apply your existing experience on this topic directly to Vaadin. Implementing a clean MVP pattern is a part of Advanced Vaadin course, in case you want some proven experiences on the topic. Also, consider to use tools like CDI or Spring, which may help you to implement your patterns in even more cleaner manner.

Testing

One of the largest advantages of using well structured UI code is that it often becomes easier to write tests for your UI logic. By using e.g. MVP pattern in your code you can write unit tests for your presenter classes.

In addition to writing unit tests to your backend and UI logic, it is good to have full stack integration tests or automated acceptance tests. Arquillian is a nice tool to write tests that run in integrations tests in Java EE container against a real DB.

Another nice helper to implement full end-to-end tests is Vaadin TestBench. It is based on the open source Selenium project and drives real browsers and simulates user interactions. This way you can test the whole application stack from browser level to the database.

Example CRUD and its Vaadin conversion

Lets image you have a server that stores your customer data. The persistency and business logic is hidden behind an EJB and your Swing based rich client reads and writes data via a remote EJB. There are lots of this kind of applications or relatively similar ones that use more lower level communication mechanism to the database.

We will use this kind of example application and look at what the different UI implementations look like. Using this example you can hopefully get a pretty realistic idea what converting a Swing based Applet or desktop application into a Vaadin based web application might require and cost.

The heart of the example is the EJB that talks to the underlying RDBMS. This part is shared by both Swing and Vaadin UI. The server used in the example is a pretty modern Apache TomEE. Although your application might be using older technology, the concepts are most likely very similar, even if you were using lower level RMI, CORBA or even raw DB connection.

SEE ALSO: Easy Swing to Web with Vaadin – Part 2

Our example is a pretty trivial CRUD, but the business logic running in the EJB is typically the most critical part of your application. Luckily you can most often recycle this part of your application, as such as in this case, or with some light modernization, and just re-write the UI part. Also at the UI part the programming model will be very familiar, so the task will be really easy for you and your colleagues – even without any web development experience.

In this example we will just use raw Swing and Vaadin APIs in the UI. Some vice men in the industry have prepared for big changes in technologies in their architectures. In case you have done something like this into your UI code the “Vaadin upgrade” might be even easier. For example one of our customer, when moving from AWT to Swing, wrote a bit more generic wrappers for their UI component and split all the UI logic to separate controllers. This was to help transition to yet another UI framework in the future. Today, in desktop world, you would naturally first think of JavaFX. Instead of going into JavaFX, they wanted to eliminate Java requirement from their clients totally and go with pure browsers technologies.vaadin to swing

An architectural overview how a Swing based “thin client application” backed by an EJB can be transferred to web era using Vaadin. In the example application we build a both Swing and Vaadin UIs, connecting to exactly same EJB backend.

Application initialization

If you have been working with some larger Swing apps, you are, instead of starting up a JFrame from your main method like in our example, most probably using some sort of application framework as a basis. The NetBeans Platform is an example of such. Similarly with Vaadin, it is hardly ever a good idea to go with raw Vaadin and a servlet container.

There are couple of nice choices and in this example we are using a standard Java EE basis and use Vaadin CDI as the “framework” that help us to bootstrap the UI and also in the next step to bind it to our backend.

As a bonus, when using Vaadin CDI, you need to know even less about Servlets and web specific stuff. In Vaadin CDI application, the entry point to your application is the UI class that you annotate with @CDIUI(“”). The empty string means the UI’s “deployment path”, the last part in your url that you use to access your application, which in our example is the actual “root” of our application. If you want, you can have multiple UI’s in your application, just map them to different urls. The Vaadin CDI add-on will “magically” introduce the low level Servlet and configure your CDI managed UI instances to be displayed via it.

If you look at the actual UI class in the example application, you’ll see it is practically empty. This is because we are using a yet another extension (our class extends ViewMenuUI from a cdi-helpers library) to Vaadin CDI that creates you a basic top level application layout and a view navigation automatically. This may be just what you need, but in many complex applications you might want to write a more domain specific version for this this part.

The actual meat of the user interface code is written into views, annotated with @CDIView. If you introduce a following class to your application, it will automatically automatically mapped to http://yourapp.com/contextpaht/#!about and the cdi-helpers will automatically register it to your applications main menu.

@CDIView("about")
public class AboutView extends VerticalLayout implements View {

    @PostConstruct
    void init() {
        addComponent(new Label("Hello Vaadin World!"));
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
    }
}

If you are not familiar with CDI or managed beans in general, you might think why I’m doing the addComponent call in the @PostConstruct annotated init method instead of creating a basic constructor. In this particular case there wouldn’t be a difference, but in the next step we will be using dependency injection to connect to our EJB. As dependencies are not resolved yet during constructor call, it is often simpler to do all view initialization in a @PostConstruct annotated init method instead.

The enter method is called by Vaadin each time user enters the view. It is handy to refresh some some often changing data in it, but most often you don’t need to do anything in it.

EJB lookup

In our desktop Swing example we have an ejb-client available on our classpath, and when the application first time needs access to the (remote) EJB, it gets resolved using a JNDI lookup with proper parameters. This is pretty handy actually, especially as we don’t have any proper security control in our example.

In a real world application, if you are not using a remote EJB, client server communication might be bit trickier, but you most likely have some sort of remote interface you’ll somehow detect.

In Vaadin application we could use the EJB exactly in the same way, but as we chose a proper Java EE + Vaadin CDI basis for our example application, the very same procedure can be done in much cleaner and more maintainable manner. As our UI objects are CDI managed beans, we can simply use @EJB or @Inject annotation to get the reference to the very same CustomerFacade. The example below uses simple field injection, but stricter architects might want you to use constructor or method injection.

@Inject
CustomerService service;

In the further steps we’ll notice that the actual accessing our stateless EJB is pretty much the same in both cases.

Listing entries from the backend to Table

In our example Swing application we are using a simple TableModel, based on AbstractTableModel, to bind our customer database to UI table. We simply grab all entities from the backend to local List instance and create a TableModel that serves the data from the list. For a larger table you’d probably need to implement some sort of paging or just rudely limit the amount of listed entities. The code snippet from our Swing example is listed below. The CustomerTableModel is then passed to JTable instance.

private List<Customer> customers;

class CustomerTableModel extends AbstractTableModel {

    @Override
    public int getRowCount() {
        return customers.size();
    }

    @Override
    public int getColumnCount() {
        return 3;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (customers == null) {
            customers = getCustomerFacade().findAll();
        }
        Customer c = customers.get(rowIndex);
        switch (columnIndex) {
            case 0:
                return c.getFirstName();
            case 1:
                return c.getLastName();
            case 2:
                return c.getEmail();
        }
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column];
    }
}

In our Vaadin application we are using technically a pretty similar in-memory table view for the database. The example actually uses a commonly used helper class from an add-on called Viritin, that just accepts the list of pojos, but you gain similar result with BeanItemContainer and raw Table component as well. Creating a basic BeanItemContainer containing all our customers would look like this:

BeanItemContainer bic
= new BeanItemContainer&lt;&gt;(Customer.class, facade.findAll());

The BeanItemContainer makes bean introspection to detect the available properties and you can then limit the available columns by configuring your Table instance. You can also get to the low level with Vaadin, like with the Swing example, and implement a custom Container implementation that you can pass to the Table. Most often the utility containers are what you want.

Listing the whole (database) table in a Vaadin user interface this way is already far more efficient because the most of the data is still only in your server. The Table component only sends the visible viewport to the Vaadin’s “thin client” and when user scrolls down more rows are fetched from the servers memory. You’ll save a lots of bandwidth compared to the desktop version.

However, if we still want to make our Vaadin version better, we could use lazy loading of data also on the server side. The MTable from the Viritin add-on used in the following example only needs strategies to fetch the total number of entities and to fetch lists of entities in paged manner. With Java 8 style constructs a lazy loading “binding” to our CustomerFacade could look like this:

MTable<Customer> table = new MTable(
firstRow -> facade.findRange(firstRow, maxResults),
facade.count(),
maxResults
);

That scales really well both in client and in server, and uses only a tiny bit of memory on the server side. There are lots of various lazy loading container implementations available in the Vaadin Directory and you can naturally write one yourself as well.

Binding entity to a form for editing

In our Swing example, we are creating an editor for our domain object in class called CustomerForm. In it we prepare some JTextField instaces for the essential properties of the domain model, whose values we copy to domain object when users clicks the save button.

JTextField firstName = new JTextField();
JTextField lastName = new JTextField();
JTextField email = new JTextField("yourname@yourdomain.com");
JButton create = new JButton("Create");
JButton update = new JButton("Update");

@Override
public void actionPerformed(ActionEvent e) {
Customer c = editedCustomer;
if (e.getSource() == create) {
c = new Customer();
}
c.setFirstName(firstName.getText());
c.setLastName(lastName.getText());
c.setEmail(email.getText());
if (e.getSource() == create) {
application.getCustomerFacade().create(c);
} else {
application.getCustomerFacade().edit(c);
}
}

When an existing entity is set for editing, we set the existing values for the fields.

void editCustomer(Customer c) {
this.editedCustomer = c;
firstName.setText(c.getFirstName());
lastName.setText(c.getLastName());
email.setText(c.getEmail());
updateButtonStates();
}

Using this kind of low level approach is pretty similar in Vaadin as well. Instead of JTextField you are just using TextField class from Vaadin core and instead of getText() method you use getValue() to grab the value from the field.

In a real life, in both Vaadin and Swing apps, you probably want to use your life for something better than writing lots of boilerplate code for this kind of basic forms. Vaadin comes with a really powerful tool called BeanFieldGroup to free yourself from writing the “glue code” between your UI fields and domain object’s properties. You can use either use naming convention or a @PropertyId annotation to hint BeanFieldGroup to do the “two way mapping” automatically. The getter-setter parts of the above can be replaced using BeanFieldGroup as follows:

TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
TextField email = new TextField("Email");

public void setCustomer(Customer customer) {
this.customer = customer;
BeanFieldGroup<Customer> bfg
= BeanFieldGroup.bindFieldsUnbuffered(customer, this);
}

The BeanFieldGroup can also attach automatically constructed validators to your fields, based on the standard Bean Validation annotations, that you already might have on your domain objects. Naturally, you can manually define and configure validators at UI layer as well. BeanFieldGroup also provides “UI level buffering”, that might be handy in case you happen to be using “live objects”. In typical business apps, the backend and your DTOs is the right level that does the “buffering” for you.

In our Vaadin example, we are using BeanFieldGroup via an AbstractForm based class. In addition to bean binding, it provides us with basic save, reset and delete buttons. In your own application you have the liberty to go with low level manual binding, automatic binding using BeanFieldGroup or with a handy helpers like the AbstractForm or your application specific version of it. The first option has the most control, the last has the cleanest code and is probably what you want in most cases.

Possible conversion strategy: wrappers for your own UI framework

Some Swing developers have created a domain specific wrappers to hide the actual Swing API from their application code. One of our clients did this when moving their application from AWT to Swing and then wanting to prepare for a yet another UI library change in the future. They just needed to make some changes to their wrappers and then create an “adapter” for Vaadin UI.

Whether this kind of wrapper strategy really pays off probably depends on the characteristics of the application itself. In our recent customer case it was estimated that even though their application was huge, going with pure Vaadin solution would have had smaller expenses. Also by creating your own UI abstraction layer, you will lose some flexibility and make additional development more expensive. However, the solution has also other advantages. With this approach it is cheap to maintain and support both modern Vaadin web client and the legacy Swing app and still implement fixes and enhancements to only one code base.

The concept is by no means unique in the industry and SibVisions JVx framework is based on a similar approach. UI can be implemented just once can be deployed to both Swing and Vaadin based client applications.

Possible conversion strategy: gradually move to web UI

Instead of rewriting the UI layer in a one big project it might be a good idea to start moving to web era gradually. You should consider this kind of approach especially if you have a well designed “backend” layer and a large application.

You could start with screens that are most often needed on devices without managed software installations, like tablets, or home computers. Then proceed the conversion on more rarely used screens. On office computers you could keep using the existing software, with the full feature set, during the transition period.

Example app sources

The source code for the EJB CRUD example with both Swing and Vaadin UIs is available via GitHub.

Author
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies.

Leave a Reply

Be the First to Comment!

avatar
400
  Subscribe  
Notify of