Page tree
Skip to end of metadata
Go to start of metadata

About this Tutorial

This tutorial will show you how to create master/detail screens with GWT. The list (master) screen will have the ability to sort columns, as well as page 25 records on the server at a time. The form (detail) screen will use an responsive CSS form layout (courtesy of Bootstrap). You will also configure client and server-side validation to improve your users' experience.

IntelliJ IDEA Rocks

Icon
We highly recommend using IntelliJ IDEA when developing web applications in Java. Not only is its Java and JUnit support fantastic, but it has excellent CSS and JavaScript support. Using JRebel with IDEA is likely to provide you with the most pleasant Java development experiences you've ever had.
Icon
This tutorial assumes you've created a project with the appfuse-basic-gwt archetype and have already completed the Persistence and Services tutorials. If you're using the appfuse-modular-gwt archetype, please morph your mind into using the web module as the root directory. If you created your project with a different web framework than GWT, you're likely to be confused and nothing will work in this tutorial. (wink)

Table of Contents

 

Source Code

Icon

The code for this tutorial is located in the "tutorial-gwt" module of the appfuse-demos project on GitHub. Use the following command to check it out from Subversion:

svn co https://github.com/appfuse/appfuse-demos/trunk/tutorial-gwt

Extend Persistence/Service Layers

Add methods to your PersonManager for Remote Pagination

We will add a couple of methods to PersonManager for server side remote pagination. This tutorial asumes you have followed the Persistence and Services tutorials so you can add these methods to your existing PersonManager and PersonManagerImpl classes:

PersonManager.java
PersonManagerImpl.java

Annotate your Person POJO for Validation

You can annotate your POJO entities with javax.validation annotations that GWT RequestFactory framework will automatically pick up for validating your entities before trying to persist them:

Person.java: javax.validation Annotations

Implement GWT RequestFactory data oriented Remote Services

We will be using GWT RequestFactory data oriented services for communication between server and client. You can find more information about RequestFactory here:

http://www.gwtproject.org/doc/latest/DevGuideRequestFactory.html

PersonLocator bean

Create a PersonLocator.java in src/main/java/**/webapp/server/locators. This component will instruct RequestFactory about how to perform CRUD operations on the Person entity.

PersonLocator.java

PersonProxy interface

Create a PersonProxy.java interface in src/main/java/**/webapp/client/proxies. PersonProxy interface is the client-side representation of a server-side Person entity, using @ProxyFor annotation to configure server side  mapped Entity and the Locator to find CRUD operations for that entity:

PersonProxy.java

PersonRequest interface for remote service

Create the PersonRequest.java interface in src/main/java/**/webapp/client/requests, This interface should match the PersonManager method you would like to expose to remote clients:

PersonRequest.java

 

Now add a PersonRequest entry to src/main/java/**/webapp/client/requests/ApplicationRequestFactory.java:

ApplicationRequestFactory.java (fragment)

I18n keys/values for Literal Externalization

GWT uses a generated java interface to access externalized literals so we will be adding those literals beforehand so we can use those methods in our view objects without compilation errors.

Open src/main/resources/**/webapp/client/application/ApplicationResources.properties and add i18n keys/values for the various "person" properties:

ApplicationResources.properties (fragment)

 

Use mvn gwt:i18n command to re-generate ApplicationResource.java methods for your newly added "person" properties.

Icon
Warning, this command will overwrite src/main/java/**/webapp/client/application/ApplicationResources.java so it's always a good idea to have a backup, or even better, to check you code into source control.

Search/List Person functionality

AppFuse follows GWT Model-View-Presenter(MVP) pattern, where the View interface is a central part of the pattern, gluing together Views and Activities:

  • exposes view properties via getters/setters
  • holds the Delegate interface which includes those methods that this view needs to delegate to its Presenter (Activity).

PersonSearchView interface

Create a ProxySearchView.java in src/main/java/**/webapp/client/ui/people/list extending ProxySearchView:

PeopleSearchView.java

 

ProxySearchView already contains methods that most search/list views would need. You don't need to create this interface.

ProxySearchView.java: Generic Interface

PersonSearchActivity

To implement PeopleSearchActivity we will be extending AbstractProxySearchActivity that require the following methods to be implemented:

PersonSearchActivity.java

 

Create a PersonSearchActivity.java in src/main/java/**/webapp/client/ui/people/list extending AbstractProxySearchActivity:

PersonSearchActivity.java

This example implements local client-side sorting, but also includes hints to implement remote server-side sorting.

PeopleSearchViewImpl.java and PeopleSearchViewImpl.ui.xml

Now create the view implementation (PeopleSearchViewImpl.java) and its associated template (PeopleSearchViewImpl.ui.xml) files in src/main/java/**/webapp/client/ui/people/list:

PeopleSearchViewImpl.java

The most interesting part of this file is the method createTableColumns() where you can define and customize data to show in the listing table.

 

PeopleSearchViewImpl.ui.xml

Configure Search/List View

To make this functionality available to the application you need to add the following configuration:

  • Add the activity to the ApplicationActivityMapper
  • Bind together View and View Implementation for ioc view injection
  • Add a new menu entry for 'View People'

ApplicationActivityMapper

Open src/main/java/**/webapp/client/ui/client/application/ApplicationActivityMapper.java and add your activity to the getActivity(..) method:

Configure View Injection: ClientGinModule

Open src/main/java/*/webapp/client/ui/client/application/ioc/ClientGinModule.java and bind togheter View and View Implementation inside configure() method

ClientGinModule.java (fragment)

ApplicationMenu

Open src/main/java/**/webapp/client/ui/client/application/ApplicationMenu.java to add a new menu entry:

ApplicationMenu.java (fragment)

Edit Person (Form Detail)

EditPersonView interface

Create an EditPersonView.java in src/main/java/**/webapp/client/ui/people/edit extending ProxyEditView:

EditPersonView.java

 

ProxyEditView already contains methods that most edit views would need. You don't need to create this interface.

ProxyEditView .java (fragment)

EditPersonActivity

To implement PeopleSearchActivity we will be extending AbstractProxySearchActivity that require the following methods to be implemented:

Required methods are:

  • createProxyRequest()
  • loadProxyRequest(RequestContext, EntityProxyId)
  • saveOrUpdateRequest(RequestContext, EntityProxy)
  • deleteRequest(RequestContext, EntityProxy)

Customization:

  • createProxy(RequestContext): instantiate a new Proxy for adding
  • getProxyClass(): determine Proxy class (which is lost at runtime), useful for reusing the same Activity with different Proxy subclases
  • loadProxyRequest(RequestContext, EntityProxyId): create a Request to load a persistent object
  • getSavedMessage(): customizes success messages
  • getDeletedMessage(): customizes success messages
  • nextPlace(boolean): customizes navigation
  • previousPlace(): customizes navigation

Create a EditPersonActivity.java in src/main/java/**/webapp/client/ui/people/edit extending AbstractProxyEditActivity:

EditPersonActivity.java

EditPersonViewImpl.java and EditPersonViewImpl.ui.xml

Create EditPersonViewImpl.java and EditPersonViewImpl.ui.xml in src/main/java/**/webapp/client/ui/people/edit

EditPersonViewImpl.java
EditPersonViewImpl.ui.xml

Configure EditPerson view

ApplicationActivityMapper

Open src/main/java/**/webapp/client/ui/client/application/ApplicationActivityMapper.java and add your activity to the getActivity(..) method:

ApplicationActivityMapper.java (fragment)

IOC View Injection: ClientGinModule

Open src/main/java/**/webapp/client/ui/client/application/ioc/ClientGinModule.java and bind togheter View and View implementation inside configure() method

ClientGinModule.java (fragment)

Annotate your PersonManager interface for security and access control

Project comes configured to honor Spring Security Access Control @PreAuthorize, @PostAuthorize and @Secured annotations so you can annotate your PersonManager interface for access control and security.

PersonManager.java (security annotations)

 

You can also enable 'javax.annotation.security'(jsr250) annotations or configure other security strategies editing src/main/webapp/WEB-INF/security.xml

 

Using jetty:run

Configuring jetty

Compiling gwt 'inplace'

  • No labels