Posts Tagged ‘template

19
Jun
12

Internationalizing a GWT Application

This page describes how to setup internationalisation in your GWT application. The example on this page builds from the page listed in the requirements section.

Requirements

Project Configuration

In order to enable internationalisation support you need to add the following “goal” and “i18nMessagesBundle” elements inside “gwt-maven-plugin”:

vi pom.xml

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>gwt-maven-plugin</artifactId>
        <version>2.4.0</version>
        <executions>
          <execution>
            <goals>
            ...
            <goal>i18n</goal>
            ...
            </goals>
...

insert the “i18nMessagesBundle” element here:

        <configuration>
          ...
          <i18nMessagesBundles>
                    <i18nMessagesBundle>com.test.client.Messages</i18nMessagesBundle>
          </i18nMessagesBundles>
          ...
        <configuration>

Externalize the language strings to a property file.

The following message bundle is converted to a Java Class by Maven. In order to specify additional bundles just insert an additional “i18nMessagesBundle” tag in the pom.xml file.

Properties File

Create the directory that will hold the property file if not done so already:

mkdir -p src/main/resources/com/test/client

vi src/main/resources/com/test/client/Messages.properties

sendButton = Send
hello = Hello {0}!

Java code Change

Modify the java code to reference the property values instead of hard-coded strings.

--- matrix-blank/src/main/java/com/test/client/Matrix.java	
+++ matrix/src/main/java/com/test/client/Matrix.java	
@@ -10,10 +10,11 @@
 
 public class Matrix implements EntryPoint {
 
+	private final Messages messages = GWT.create(Messages.class);
 	public void onModuleLoad() {
-		Button button = new Button("Send", new ClickHandler() {
+		Button button = new Button(messages.sendButton(), new ClickHandler() {
 			public void onClick(ClickEvent event) {
-				Window.alert("Hello World!");
+				Window.alert(messages.hello("World"));
 			}
 		});
 		button.setStyleName("sendButton");

Test the Change

At this time you would want to verify that the Message.java class has been generated by the GWT framework. If this class is not found then try to mvn compile and refresh the eclipse project. You may also want to right click, update Maven project configuration if that does not work.

mvn compile gwt:run

The French Version

vi src/main/resources/com/test/client/Messages_fr.properties

sendButton = Envoyer
hello = bonjour {0}!

Configure

You can add the following line into the module element of your “gwt.xml” file for each locale you want to support:
vi src/main/java/com/test/Matrix.gwt.xml

<extend-property name="locale" values="fr"/>

Start the application

mvn compile gwt:run

Test the Change

At this point you have 2 options to see the French version of the site:

  1. You can put the following line in the host HTML page
    <meta name="gwt:property" content="locale=fr">
    
  2. Append the client property value to the query string of the URL: http://127.0.0.1:8888/Matrix.html?gwt.codesvr=127.0.0.1:9997?locale=fr

Either way you will see the French version of the site.

Reference

http://code.google.com/webtoolkit/doc/latest/tutorial/i18n.html

Appendix

Creating Keys for place holder parameters, the lines of the property file should look like this:

myString = First parm is {0}, second parm is {1}, third parm is {2}.

The key “myString” can be used in static HTML by wrapping the content with a html tag with an assigned id.

    <h1 id="myString"></h1>

The id attribute can be used as a handle to replace the text in Java code like this:

    RootPanel.get("appTitle").add(new Label(constants.myString("one","two","three")));

To get the list of locale’s supported by your JVM just run the following code:

	public static void main(String args[]) {
		Locale locales[] = SimpleDateFormat.getAvailableLocales();
		List arrayList = Arrays.asList(locales);
		Collections.sort(arrayList, new Comparator() {
			public int compare(Locale o1, Locale o2) {
				return o1.getDisplayName().compareTo(o2.getDisplayName());
			}
		});
		for (Locale locale : arrayList) {
			System.out.println(locale.toString() + "\t" + locale.getDisplayName());
		}
	}
18
Jun
12

Blank GWT Template Starter Application

This page describes the complete end-to-end process of creating and testing a blank “Hello World” type Google Web Tool kit (GWT) starter application using Maven. The page takes about 10-15 minutes to complete and have a working GWT application.

Full downloadable source for this page is available here. Corrections and enhancements are welcome, fork, change and push back to GitHub.

The application described on this page displays a Send Button on the page. It displays a JavaScript alert() message when the button is clicked.

Background

The GWT SDK allows you to generate an application using their generation tool. However I never liked using this tool because the application it generated is useless to me unless I understand how the application is working. The following page breaks down a simple Hello World GWT application step by step and allows the reader to follow along. Once the application is complete the user can import it into eclipse and use the GWT tool to modify the application using the Screen Design Tools.

Requirements

  • Maven
  • M2 Eclipse plugin
  • Eclipse GWT plugin

This page covers GWT version 2.4.0.

First step is to create a simple maven project in eclipse.

Modify the pom.xml to look like this…

vi pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test</groupId>
	<artifactId>gwt-hello</artifactId>
	<packaging>war</packaging>
	<version>20140429</version>

	<pluginRepositories>
		<pluginRepository> <!-- Ignore this repository. Its only used for document publication. -->
			<id>numberformat-releases</id>
			<url>https://raw.github.com/numberformat/20130213/master/repo</url>
		</pluginRepository>
	</pluginRepositories>

	<properties>
		<!-- Convenience property to set the GWT version -->
		<gwtVersion>2.4.0</gwtVersion>
		<!-- GWT needs at least java 1.5 -->
		<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.google.gwt</groupId>
			<artifactId>gwt-servlet</artifactId>
			<version>${gwtVersion}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.google.gwt</groupId>
			<artifactId>gwt-user</artifactId>
			<version>${gwtVersion}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.0.0.GA</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<!-- Generate compiled stuff in the folder used for developing mode -->
		<outputDirectory>${webappDirectory}/WEB-INF/classes</outputDirectory>
		<plugins>
			<!-- GWT Maven Plugin -->
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>gwt-maven-plugin</artifactId>
				<version>2.4.0</version>
				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
							<goal>test</goal>
							<goal>generateAsync</goal>
						</goals>
					</execution>
				</executions>
				<!-- Plugin configuration. There are many available options, see gwt-maven-plugin 
					documentation at codehaus.org -->
				<configuration>
					<runTarget>Matrix.html</runTarget>
					<hostedWebapp>${webappDirectory}</hostedWebapp>
				</configuration>
			</plugin>

			<!-- Copy static web files before executing gwt:run -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<executions>
					<execution>
						<phase>compile</phase>
						<goals>
							<goal>exploded</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<webappDirectory>${webappDirectory}</webappDirectory>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			
			<plugin> <!-- Ignore this plugin. Its only used for document publication. -->
				<groupId>github.numberformat</groupId>
				<artifactId>blog-plugin</artifactId>
				<version>1.0-SNAPSHOT</version>
				<configuration>
					<gitUrl>https://github.com/numberformat/wordpress/tree/master/${project.version}/${project.artifactId}</gitUrl>
				</configuration>
				<executions>
					<execution>
						<id>1</id>
						<phase>site</phase>
						<goals>
							<goal>generate</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
					
		</plugins>
		<pluginManagement>
			<plugins>
				<!--This plugin's configuration is used to store Eclipse m2e settings 
					only. It has no influence on the Maven build itself. -->
				<plugin>
					<groupId>org.eclipse.m2e</groupId>
					<artifactId>lifecycle-mapping</artifactId>
					<version>1.0.0</version>
					<configuration>
						<lifecycleMappingMetadata>
							<pluginExecutions>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>
											org.apache.maven.plugins
										</groupId>
										<artifactId>
											maven-war-plugin
										</artifactId>
										<versionRange>
											[2.1.1,)
										</versionRange>
										<goals>
											<goal>exploded</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore></ignore>
									</action>
								</pluginExecution>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>org.codehaus.mojo</groupId>
										<artifactId>
											gwt-maven-plugin
										</artifactId>
										<versionRange>
											[2.4.0,)
										</versionRange>
										<goals>
											<goal>generateAsync</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore></ignore>
									</action>
								</pluginExecution>
							</pluginExecutions>
						</lifecycleMappingMetadata>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>

</project>

Host HTML Page

The following is the Host HTML Page. The page imports the generated Javascript and starts the Javascript application. Similar to the “Entry Point” main() method of many other programming languages.

vi src/main/webapp/Matrix.html

<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="Matrix.css">
<script language="javascript" src="test.Matrix/test.Matrix.nocache.js"></script>
  </head>
  <body>
    <noscript>
      <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
        Your web browser must have JavaScript enabled
        in order for this application to display correctly.
      </div>
    </noscript>
    <div id="sendButtonContainer"></div>
  </body>
</html>

CSS Styles

GWT components are highly customizable. It makes sense to define sizes, colors, alighment, images, and other visual aspects of the component in CSS.

vi src/main/webapp/Matrix.css

.sendButton {
  display: block;
  font-size: 12pt;
}

Web Application Descriptor

The following is a basic web.xml file for the application.

vi src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
 
<web-app>
 
  <!-- Servlets -->
  <!-- Servlet-Mapping -->
 
  <!-- Default page to serve -->
  <welcome-file-list>
    <welcome-file>Matrix.html</welcome-file>
  </welcome-file-list>
</web-app>

vi src/main/java/com/test/Matrix.gwt.xml

<module>
  <inherits name='com.google.gwt.user.User' />
  <inherits name='com.google.gwt.user.theme.standard.Standard' />
  <entry-point class='test.client.Matrix' />
</module>

vi src/main/java/test/client/Matrix.java

package test.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
 
public class Matrix implements EntryPoint {
 
    public void onModuleLoad() {
        Button button = new Button("Send", new ClickHandler() {
            public void onClick(ClickEvent event) {
                Window.alert("Hello World!");
            }
        });
        button.setStyleName("sendButton");
        RootPanel.get("sendButtonContainer").add(button);
    }
}

Run the project

mvn clean compile gwt:run

Click on Launch Default Browser button. You should see a page with a button on the top left.

Import into Eclipse and Edit in Design View

The following procedure allows you to open the screen above in the “GWT Design View”.

  1. Right click -> Properties -> Google -> Web Toolkit.
  2. Add the Entry point Module Matrix to the list if not already there by clicking on the “Add” button.
  3. Right click on the Matrix.java File and choose Open With -> WindowBuilder Editor.
  4. The source file will open and allow you to click on the Design Tab.
  5. Change the button name to Send2.

Test the change by typing:

mvn clean compile gwt:run

Might need to click on Launch Default Browser button twice. You should see a page with a button titled “Send2” on the top left.

What’s Next?

16
Jan
12

Invoke Server Side Code Using GWT

This page describes how to Invoke Server Side Code to retrieve data from the server side and display the results in a JavaScript pop-up.

Background

GWT generates JavaScript code that makes a call to server side components thru the Servlet Interface. The Service Implementation class extends the “RemoteServiceServlet” class. This allows GWT to respond to requests made from the GWT generated Javascript.

Requirements

Procedure

Before we begin we need to create directories.

mkdir -p src/main/java/com/test/server

Create the Interface

First you create a an interface that can be used by the client. Maven generates a client side Interface based this. The interface class should be in the module’s client package.

vi src/main/java/com/test/client/GreetingService.java

package com.test.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
  String greetServer(String input) throws IllegalArgumentException;
}

Create the Implementation

The implementation class should be in the module’s server package.

vi src/main/java/com/test/server/GreetingServiceImpl.java

package com.test.server;

import com.test.client.GreetingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
    GreetingService {

  public String greetServer(String input) throws IllegalArgumentException {
    String serverInfo = getServletContext().getServerInfo();
    String userAgent = getThreadLocalRequest().getHeader("User-Agent");

    return "Hello, " + input + "! I am running " + serverInfo
        + ".It looks like you are using:" + userAgent;
  }
}

Define the Servlet

Add the servlet to the web.xml.

vi src/main/webapp/WEB-INF/web.xml

  <!-- Servlets -->
  <servlet>
    <servlet-name>greetServlet</servlet-name>
    <servlet-class>com.test.server.GreetingServiceImpl</servlet-class>
  </servlet>

  <!-- Servlet-Mapping -->
  <servlet-mapping>
    <servlet-name>greetServlet</servlet-name>
    <url-pattern>com.test.Matrix/greet</url-pattern>
  </servlet-mapping>

Change the EntryPoint

Make the changes described in the following patch file by hand to the existing file.

vi src/main/java/com/test/client/Matrix.java

--- src/main/java/com/test/client/Matrix.java
+++ src/main/java/com/test/client/Matrix.java	
@@ -5,15 +5,26 @@

+import com.google.gwt.core.client.GWT;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.RootPanel;
 
 public class Matrix implements EntryPoint {
-
+	private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
+	
 	public void onModuleLoad() {
 		Button button = new Button("Send", new ClickHandler() {
 			public void onClick(ClickEvent event) {
-				Window.alert("Hello World!");
+		        greetingService.greetServer("World", new AsyncCallback<String>() {
+		            public void onFailure(Throwable caught) {
+		              // Show the RPC error message to the user
+		              Window.alert("Remote Procedure Call - Failure");
+		            }
+
+		            public void onSuccess(String result) {
+		                Window.alert(result);
+		            }
+		          });
 			}
 		});
 		button.setStyleName("sendButton");

Test the application

  1. Right click on the project in Eclipse and Refresh.
  2. right click on the project -> Maven -> Update Project Configuration.

Everything should compile fine in eclipse.

Next go to the command prompt and type the following in the project’s base folder.

mvn compile gwt:run

After clicking the button on the screen a JavaScript alert box will open returning text from the server side. You can use Firefox FireBug plugin to verify the server side communication.

Troubleshooting

  • Is the Service interface in the client package of the module’s package?
  • Is the service implementation in the server package of the module’s package?
  • Does the web.xml file specify the servlet class implementaion?
  • Does the web.xml specify the url-pattern that points to the gwt.xml file name/[remoteServiceRelativePath]. (without gwt.xml extension)
    For Example: com/test/AlbumSearch.gwt.xml and a @RemoteServiceRelativePath(“musicsearch”) on the interface will translate to:
    <url-pattern>com.test.AlbumSearch/musicsearch</url-pattern>
    



Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 78 other followers

July 2017
S M T W T F S
« Mar    
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Blog Stats

  • 822,606 hits