Responsive web design with Google Web Toolkit

Patterns for building mobile-enabled web applications

Get started with using GWT-friendly CSS media queries and multi-device layout patterns to develop mobile-responsive web applications. Demonstrations are based on an open source code base that you can use as a foundation for your own responsive navigation menus, dialogs, and more.

Building a modern online application without mobile-platform support is like running a fast-food chain without the drive-thru. A web-only strategy will cost you half or more of your potential visitors. On the other hand, imagine building a drive-thru with an entrance for every kind of car. That scenario would be absurd in the brick-and-mortar world, but it is exactly what the native approach to mobile application development entails. Writing for multiple code bases and environments and providing relevant support, bug fixes, and releases for them all is a well-paved road to programmer hell.

That is why it's no surprise that responsive web design has emerged as a popular approach to supporting web applications on mobile devices. Responsive design frees you from worrying about how the application will run on a specific platform. Instead, the application is written to adapt to different environments by adjusting its layout for a given screen size.

In this article we introduce some techniques of web responsive design, using a live mobile-responsive web application as our proof of concept. The CuppaFame application was built using GWT (Google Web Toolkit). In addition we provide a dedicated collection of open source foundation libraries (gwt-responsive) that you can use to explore or build your own similarly responsive web project.

Simulating mobile environments in a web browser

Responsive web design starts in the application design and implementation phase, when we use tools to simulate different platforms and screen sizes. Some of these tools can be accessed from your browser. For instance, Firefox has a Responsive Design View tool that will simulate any screen size, as well as mobile-device operations like screen rotation and touch events. Chrome Developer Tools goes several steps further with its Toggle feature, which lets you play with views for most mobile devices in the browser.

Figure 1 demonstrates the front page of the original web version of CuppaFame. We are looking at it in full-screen mode. The header at the top of the page allows us to search for various types of documents. The menu panel on the right lets users save search queries, place documents in public or private folders, create and update a user profile, and interact through social networks.

gwt mobile fig1

This layout looks fine in a desktop browser but how will it look on a smartphone screen? We can use Firefox's Responsive Design View to see how the layout would look on a particular device. Open the SAVED FOLDERS tab in the topic menu on the left side of your Firefox Responsive Design View screen. Then open Folders Examples and choose the CuppaFame Collage folder. You are now looking at a screenshot of Thomas A. Edison's patent for the Electric Lamp! The screen captures below show the screen as the user would see it rendered for an iPhone 5 device.

gwt mobile fig2

This is responsive design in action. Since the application cannot display the whole screen on the iPhone 5 device, it instead lets the user toggle between two modes: Menu and Content. This is only one example of what we can do with responsive web design and development, but it's a place to start. Next we'll set up the project and look at some code.

Building and running a responsive web application

We're using an open source Maven project to illustrate our major points about responsive web design. You can also use this project as a foundation for your own applications. Because the project is pure Maven you will be spared from having to download and configure Google Plugin and other components.

The instructions below will guide you through setting up the project so that you can run it from your command-line or Eclipse environment, which allows debugging. Alternatively, you could access the project online to see the functionality as it is implemented live.

Maven setup

  1. Download Apache Maven from the Maven project page.
  2. Configure your system/user path to point to the maven home directory: *\apache-maven\bin.
  3. Make sure the JAVA_HOME environment variable points to your JDK (version 1.7x in our example).
  4. Download the open source foundation project, gwt-responsive, into a new project directory.
  5. From the command-line go to your new gwt-responsive project directory and run the command: mvn gwt:run. This will launch GWT Dev Mode:
    gwt mobile fig3
  6. Clicking Launch Default Browser will open the application in your web browser:
    gwt mobile fig4

Optional: Building and running a responsive example project in Eclipse

If you would like to build and run the project in Eclipse (and not just run it from the command-line), take the following steps:

  1. Download the gwt-responsive project source code from its GitHub repository:
    gwt mobile fig5
  2. Import this code into your Eclipse environment as an Existing Maven project:
    gwt mobile fig6
  3. Find the pom.xml file in your Eclipse project and right-click on it. Select the Run As and Maven Install menu items to install all the necessary project components. You will receive the console message "BUILD SUCCESS" when the application is ready to run:
    gwt mobile fig7

As our last step in the setup process, let's set up the application for debugging.

  1. Right-click on your pom.xml file again, then select Debug As followed by Maven Build.
  2. In the edit configuration and launch window set the goals value as gwt:debug and click the Debug button. You should be able to see the console message: "Listening for transport dt_socket at address: 8000":
    gwt mobile fig8
  3. Next we need to add a new remote Java application configuration. Right-click on the pom.xml, then select the following path: Debug As-->Debug Configurations-->Remote Java Application-->New Launch Configuration. You will see the console message “java application running on host: localhost port:8000".
  4. Once again you will see the GWT Development Mode screen. Click the Launch Default Browser button to run and debug the application in your browser.

Architecture of the example project

The CuppaFame example project is built using gwt-platform (GWTP), an open source model-view-presenter (MVP) framework for GWT.

The project has eight major modules. Each module is a classic MVP component responsible for a specific feature of the application's user interface (UI) functionality. MVP views are defined by view classes and corresponding UI binder files, which are designated *.ui.xml. The UI binders define the HTML layout for each module.

GWTP application modules

The application modules are as follows:

  1. Main client application (*.client.application) houses all of the application modules.
  2. Main menu (*.client.application) is in charge of menu items and their functionality.
  3. About (*.client.application.about) is responsible for displaying the application's About page.
  4. Home (*.client.application.home) is in charge of the application's homepage.
  5. Record View (*.client.application.complex) implements the record-view page.
  6. Login Dialog (*.client.application.login) demonstrates dialog usage.
  7. GIN (GWT INjection) (*.client.application.gin) is the project's dependency injection framework. We also use Guice (*.server.guice) to glue together the application components on the server side.
  8. Resources modules (*.client.resources.css and *client.resourses.css) house the responsive features of our application, enabling it to adjusts its layout for any mobile screen.

Now that we've set up the application and toured its basic components, we are ready to look at the implementation details of the toggle feature. Toggling between layouts is just one element of responsive design for smaller screens, but this example lets us explore various techniques and patterns of responsive design in GWT.

Loading and controlling mobile style sheets and resources in GWT

A major objective of this project is to avoid heavy JavaScript coding. We can achieve this goal quite gracefully by using resources and style sheets in GWT. Listing 1 shows the *.client.resources.MainResources.java interface, where we have defined two style-sheet resources.

Listing 1. MainResources.java


	@Source("css/Main.css") // css is a general stylesheet 
	MainStyles css();

	@Source("css/Mobile.css") // mobile stylesheet is in charge of mobile platform rendering 
	TextResource mobile();
Resource Loader class (*.client.gin.ResourceLoader.java) // is in charge of loading our resources as described above:
public class ResourceLoader {
	@Inject
	ResourceLoader(MainResources resources) {
		resources.css().ensureInjected();
		String mobileCss = resources.mobile().getText();
		StyleInjector.injectAtEnd(mobileCss); // inject css content at the end of head element
	}

GWT doesn't support media style sheets directly, so we need to find a way to bypass this restriction. In this case our workaround is to inject the string with media CSS content at the end of the head DOM element.

This approach uses main.css classes by default, replacing their properties with ones defined in mobile.css for screens of smaller dimensions. For our implementation we used CSS media queries. For example, mobile.css contains the media query: @media all and (max-width: 800px) {...}. When the device screen width is less than or equal to 800 pixels, the properties of the main CSS will be replaced with values defined by this query.

Note that in order for this technique to work, we need to make sure that GWT doesn't obfuscate the names of the CSS classes. You can turn off obfuscation by defining all CSS classes with the declaration @external in the main.css resource.

Responsive menu toggling

We have described the basic responsive behavior of enabling a user to switch between the Menu and Content modes on a mobile device screen. Now let's look at the implementation code that enables this behavior.

In Listing 2, the UI binder file ApplicationView.ui.xml manages our root layout panel. Note that there are three components mainMenuPanel, centerPanel, and northSlot but only northSlot contains a toggleMenu button.

Listing 2. ApplicationView.ui.xml


<g:FlowPanel ui:field="scrollPanel" addStyleNames="{res.css.mainScrollPanel}">
  <g:FlowPanel ui:field="mainMenuContainer" addStyleNames="{res.css.mainMenuContainer}">
    <g:FlowPanel ui:field="mainMenuPanel" addStyleNames="{res.css.mainMenu}" />
  </g:FlowPanel>
  <g:FlowPanel ui:field="centerContainer" addStyleNames="{res.css.mainPlaceContainer}">
    <g:SimplePanel ui:field="centerPanel" />
  </g:FlowPanel>
// contrary to intuition, northSlot should be after center because
the center will go under the north (fixed) while scrolled //
  <g:SimplePanel ui:field="northSlot" addStyleNames="{res.css.mainNorthPanel}">
    <g:HorizontalPanel>
      <g:cell horizontalAlignment="ALIGN_LEFT" width="24px">
        <g:ToggleButton ui:field="toggleMenu">
          <g:upFace image="{res.mainMenu24px}"/>
          <g:downFace image="{res.mainMenu24px}"/>
        </g:ToggleButton>
      </g:cell>
      <g:cell verticalAlignment="ALIGN_MIDDLE" horizontalAlignment="ALIGN_RIGHT" width="100%">
        <g:Anchor ui:field="login" text="{msg.login}" addStyleNames="{res.css.login}"/>
      </g:cell>
    </g:HorizontalPanel>
  </g:SimplePanel>
</g:FlowPanel>

Our objective is to display the toggleMenu button only on screens of 800 pixels or less. Clicking on this button should enable the user to toggle between the UI's Content and Menu modes by hiding and showing mainMenuPanel. The Toggle button in CSS is named mainMenuToggler; it is defined as invisible in the main.css class:


@external .mainMenuToggler ;
.mainMenuToggler {
	display: none;
	vertical-align: bottom;
}

The mobile.css stylesheet makes sure that this button is displayed on mobile screens of 800 pixels or less by replacing the value of the display property, as shown here:


@media all and (max-width: 800px) {
	.mainMenuToggler {
		display: inline-block;
	}

Using CSS selector for GWT interaction with the UI

Next we need to be able to intercept the click event associated with the Toggle button, instructing it to hide or show a given menu panel based on the button's state. For this to work, we first need to be able to save the current state of menu visibility, which could be on or off. The CSS selector technique fits this purpose perfectly. Listing 3 shows the relevant fragments from mobile.css.

Listing 3. CSS selector in mobile.css


@media all and (max-width: 800px) {
…
.mainRootPanel[menu="off"] .mainMenuContainer {
  margin-left: -100%;
}
.mainRootPanel[menu="on"] .mainMenuContainer {
  margin-left: 0px;
}

This code defines the layout of the mainMenuContainer that should be hidden or shown depending on the Toggle button's state. Note that the menu panel has a margin-left CSS property. It is set up dynamically depending on the attribute menu. If the value is off the panel is invisible. In a Java implementation we would set up this attribute to respond to the Toggle button's state. In the code below ApplicationView.java intercepts a click event:


toggleMenu.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
  @Override
  public void onValueChange(ValueChangeEvent<Boolean> event) {
  rootPanel.getElement().setAttribute("menu", event.getValue() ? "on" : "off");
  ...
}	

1 2 Page 1
Page 1 of 2
InfoWorld Technology of the Year Awards 2023. Now open for entries!