PermGen error

GWT 2.0 Declarative Interfaces

Ok so if you’ve followed the previous stage you’ll have a running web application that looks like the following:

GWT2Screen Full

This is the sample web application that GWT creates and it demonstrates some of the properties of GWT including Remote Procedure Calls (RPC). Clicking on the send button sends the name entered to the server and the server responds.

We’ll convert this example to use Declarative User Interfaces.

Editing the GWT Module defintion

Your application will have associated with it a gwt.xml module defintion we need to edit this to include the Ui Binder utilities

It can be found under the src directory and in the folder com/webapplication folder.

Simply add the following line

<inherits name="com.google.gwt.uibinder.UiBinder" />

Editing the application HTML

Using Eclipse expand the war folder and you should have a HTML file which will be the same name as you had entered when creating the project. In my case WebApplication.html

We’ll strip out most of the code on the HTML page as its not needed and we can simplify things

Make your HTML the same as the following:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="WebApplication.css">
    <title>Web Application Starter Project</title>
    <script type="text/javascript" language="javascript" src="webapplication/webapplication.nocache.js"></script>
  </head>
  <body>
 
    <!-- OPTIONAL: include this if you want history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
    <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
    <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>
 
    <h1>Web Application Starter Project</h1>
  </body>
</html>

So that simplifies the HTML of the application we can now simplify the code of the main application.

Editing the EntryPoint and binding Widgets

Depending on your chosen names when creating the project the GWT plugin will have created a package similar to com.webapplication.client. Under this package you should have a couple of Interfaces (they’re for the RPC calls) and a class which is the main application point. Using my package name as the example the class is called WebApplication.java

This class is the main entry point for the application. You can think of this as similar to the main method for a Java native application

There should be a method called

onModuleLoad

This is the Main method.

In this method right at the start we declare two interface objects – sendButton and nameField. We’re going to use declarative interfaces for these buttons so they can be removed from the module load. Remove the folllowing lines:

final Button sendButton = new Button("Send");
final TextBox nameField = new TextBox();
nameField.setText("GWT User");

We can now move those two objects and make them class variables. You’ll notice the declaration of the GreetingService. Under this add the following lines

@UiField Button sendButton;
@UiField TextBox nameField;

This will make sure your code compiles again. Notice the use of a new Java annotation @UiField. This is a key feature to UiBinding and GWT declarative interfaces.

Also notice we do not declare the variables as private to the class, they need to be visible so protected at a minimum

Any UI object that your declare can be bound in this way. When we create the declarative interface file for the application you will see where the UI objects are defined and how the bounding happens

Next we need to bind the template file to the class. Just under your class defintion add the following lines:

@UiTemplate("WebApplication.ui.xml")
interface Binder extends UiBinder<VerticalPanel, WebApplication> { }
private static final Binder binder = GWT.create(Binder.class);

In the above code we declare the template file we are going to use (This can be any name you like) and we bind a widget using the UiBinder. In my case I’m using a simple VerticalPanel for my layout

Now we need to get this VerticalPanel and add it to our layout

Within your onModuleLoad method add the following code as the first line of the method:

VerticalPanel vp = binder.createAndBindUi(this);

Below that you will have a lot of code that declares styles, click handlers, a dialog box and the adding of widgets to in layout. For now we’ll remove most of this code. We’ll reintroduce it when we need it

We’ll just add a line that adds our declared panel to the layout.

RootPanel.get().add(vp);

Your onModuleLoad method should now be simpler and look like the following:

/**
 * This is the entry point method.
 */
 public void onModuleLoad()
 {
     VerticalPanel vp = binder.createAndBindUi(this);
     // We can add style names to widgets
     sendButton.addStyleName("sendButton");
 
     // Focus the cursor on the name field when the app loads
     nameField.setFocus(true);
     nameField.selectAll();
 
     RootPanel.get().add(vp);
}

The whole class should look like this:

package com.WebApplication.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
 
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class WebApplication implements EntryPoint
{
	@UiTemplate("WebApplication.ui.xml")
	interface Binder extends UiBinder<VerticalPanel, WebApplication> { }
	private static final Binder binder = GWT.create(Binder.class);
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
						 + "attempting to contact the server. Please check your network "
						 + "connection and try again.";
 
	/**
	 * Create a remote service proxy to talk to the server-side Greeting
	 * service.
	 */
	private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
 
	@UiField Button sendButton;
	@UiField TextBox nameField;
 
 
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad()
	{
		VerticalPanel vp = binder.createAndBindUi(this);
		// We can add style names to widgets
		sendButton.addStyleName("sendButton");
 
		// Focus the cursor on the name field when the app loads
		nameField.setFocus(true);
		nameField.selectAll();
 
		RootPanel.get().add(vp);
	}
}

For now thats it on the Java side

Declaring the interface

Remember we added a line that used the @UiTemplate annotation and we declared a ui.xml template. (In my example WebApplication.ui.xml). We can now go ahead and create this file

In the same location as your Entry Point (WebApplication class) add a new file of the same name of your template. In my case I created a file called WebApplication.ui.xml

Add the following contents to your ui.xml file

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g='urn:import:com.google.gwt.user.client.ui'
             xmlns:webapplication='urn:import:com.WebApplication.client'>
 
 
 
</ui:UiBinder>

Notice we declare add the uiBinder tags with XML namespaces. The final namespace must match your client package name and application. If you are unsure of your application name you can check this in the GWT module definition file.(WebApplication.gwt.xml)

Within those tags we can add the declaration of our VerticalPanel

<g:VerticalPanel>
</g:VerticalPanel>

Ok now we can add in the contents of the VerticalPanel which include our sendButton and nameField that will be bound

Add the contents shown below to your VerticalPanel definition:

<g:VerticalPanel>
    <g:Label text="Please enter your name:" />
    <g:HorizontalPanel>
        <g:TextBox text='GWT User' ui:field='nameField' />
	<g:Button text='Send' ui:field='sendButton' />
    </g:HorizontalPanel>
</g:VerticalPanel>

The whole file should like similar to the following:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g='urn:import:com.google.gwt.user.client.ui'
             xmlns:webapplication='urn:import:com.WebApplication.client'>
 
	 <g:VerticalPanel>
	 	<g:Label text="Please enter your name:" />
	 	<g:HorizontalPanel>
	 		<g:TextBox text='GWT User' ui:field='nameField' />
	 		<g:Button text='Send' ui:field='sendButton' />
	 	</g:HorizontalPanel>
	 </g:VerticalPanel>
 
</ui:UiBinder>

At this stage you should be able to run the application

Coming next method binding…..


Categorised as: Google Web Toolkit


7 Comments

  1. Asterix says:

    Thanks a lot! At last I found useful tutorial. Thanks again!

  2. HappyCamper says:

    Great little tutorial. Thanks!

  3. daniel says:

    afaik you need the third namespace only to use custom widgets that are defined in the package the namespace points to.

    so in the example it should work without the third namespace, because only gwt-widgets are used (this is where xmlns:g points to)

    you need further namespaces for every package from your project where a widget is defined that you want to use in your template.

    ie you would write <webapplication:MyWidget/> to include ‘MyWidget’ from com.WebApplication.client

  4. Federico Kereki says:

    Hi! Thanks for your answer. I was curious, because I’ve been using UiBinder *without* the third definition (i.e., xmlns:webapplication) and it worked just fine.

  5. admin says:

    Hi there,

    The xmlns:webapplication defines the namespace for our web application. Notice in the java WebApplication class the package we’re working in is com.WebApplication.client – it is that package that is referenced in the xmlns:webapplication

    Hope that helps,

  6. Federico Kereki says:

    Nice description – but what is xmlns:webapplication used for?

  7. sandip says:

    Thanks for such nice step by step document.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">