Edwin's GWT weblog

Tips and Tricks about using Ext-Gwt (GXT)

GWT 2.1

I haven’t posted on this site for a year. That’s because I stopped using Ext-GWT.
One of the reasons is that the project I intended to use Ext-GWT for was stopped.
I have been busy building stuff with other java frameworks. Currently I am building a mobile HTML5/jquery/CSS website without GWT.
Now that GWT 2.1 is out, I plan to use (Google) GWT more.

GUI Designer for Ext-Gwt

Last week Instantations announced that their GWT Designer now supports Ext-GWT components like Panels, Layouts, Widgets, Forms, Menus and Toolbars. For more information see:
GWT Designer v7.2 With Support for Ext GWT
This designer can be used as a plug-in in Eclipse.

Update okt 15:
At first I did not see any Ext-GWT widgets and it looked like it did not support Ext-GWT.
Turns ook that you need to right-click the module file and then choose:
Google Web Toolkit – Configure for using Ext GWT(GXT).
For me this did not work directly. I had to do this also for the package of this module.
and then still: when I go into Design mode I see the message:
Make sure that you configured correctly. Use Configure for using GWT-Ext action in contect menu of your module.
Very strange…. In the end I added support for GWT-Ext, but I only want Ext-GWT!

After that I was starting up hosted mode, …. but ended up with an initialize time-out.
After a retry it seemed to work.

Type [MyClass] was not serializable and has no concrete serializable subtypes

Today I got a strange error-message in GWT. In an RPC call I passed a parameter that extended the BaseModel.
But when running I got the error-message:
Type [MyClass] was not serializable and has no concrete serializable subtypes.

In Ext-Gwt the Class com.extjs.gxt.ui.client.data.BaseModel implements java.io.Serializable, so this is a strange error-message.
Even defining it as public class MyClass extends BaseModel implements Serializable gave the not serializable error-message.

It turns out that this message was caused because I did not define an empty constructor in MyClass (only a constructor with parameters).

Some performance tips for Ext-Gwt

- When changing style use CSS (method .addStyle) a much as possible.

- In RPC-call only transfer data that is used in the screen. Do not transfer your whole domain-model!

- Try to use as much asynchonous calls as possible.

- When your back-end services are slow: use a stub to provide data to your GUI when you are working in hosted-mode.

- If a user has to wait more than 1 second, give feedback (for example a wait box) so the user knows that the system is responding.

- When compiling for development, add a hint that only for your browser will be compiled.
For example, I use Internet Explorer 6 and Firefox 3, then I add the following line to my module-xml:

with possible values: gecko,gecko1_8,ie6,opera,safari,ie8

Increase the memory in your Run Configuration, tab Arguments.
Set the VM argument to:
-Xmx256M

- A button in Ext-Js is quite a complex html-widget. When using a lot of buttons, use an IconButton and change the style to a simple style.

Using Stubs in Ext-Gwt development mode

Based on this article: http://code.google.com/docreader/#p=google-web-toolkit-incubator&s=google-web-toolkit-incubator&t=StubbingRPC

I created a stub that will be used for RPC calls in hosted mode. This way you do not have to wait for back-end processes (for example access to webservices/database) to be completed during build, and you do not have to wait the time that is needed to complete the webservice request. This can speed up development.

You can do this the following way:

In onModuleLoad:

String moduleRelativeURL = GWT.getModuleBaseURL() + "yourService";

if(!GWT.isScript()) {
// hosted mode
moduleRelativeURL = moduleRelativeURL +"Stub";
}
endpoint.setServiceEntryPoint(moduleRelativeURL);

Note: Since GWT 1.6 the does not work any more, you have to define this in the WEB-INF/web.xml.

In the web.xml we add:
<servlet>
<servlet-name>yourService</servlet-name>
<servlet-class>com.tutorialsjava.server.CustomerServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>yourServiceStub</servlet-name>
<servlet-class>com.tutorialsjava.server.CustomerServiceStubImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>yourServiceStub</servlet-name>
<url-pattern>/yourServiceStub</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>yourService</servlet-name>
<url-pattern>/yourService</url-pattern>
</servlet-mapping>

And besides the standard Servlet
public class YourServiceImpl extends RemoteServiceServlet implements
YourService {

a Stub servlet is created that extends this servlet:
public class YourServiceStubImpl extends YourServiceImpl{

Draggable and resizable components in Ext-Gwt

In Ext-Gwt you can make a component draggable and a box component resizable very easy.
Just add code like this:
Component c = ...;
Draggable draggable = new Draggable(c);
BoxComponent bc = ...;
Resizable resizable = new Resizable(bc);

The following classes are BoxComponents:
Button, ColumnHeader, ColumnHeader.GridSplitBar, ColumnHeader.Group, ColumnHeader.Head, Composite, Container, DatePicker, Editor, Field, FlashComponent, Grid, Html, IconButton, Insert, LabelToolItem, ListView, ModalPanel, ProgressBar, Slider, SplitBar, Status, StatusProxy, TableColumnUI, TableHeader, Text, TreePanel, WidgetComponent

The following classes are Components:
All BoxComponent (see above), ColorPalette, DataListItem, DataViewItem, Document, FillToolItem, FramePanel, Header,
Item, MenuBarItem, SeparatorToolItem, Shortcut, TabItem.HeaderItem, TableItem, TreeItem

Sample code:
Viewport viewport = new Viewport();
viewport.setWidth(600);
viewport.setHeight(1000);
viewport.setLayout(new RowLayout(Orientation.HORIZONTAL));
viewport.setBorders(false);
PaymentPanel p = new PaymentPanel();
viewport.add(p, new RowData(350, 200));
Draggable draggable = new Draggable(p);
Resizable resizable = new Resizable(p);

You can see a running demo here

Call REST webservice directly from Ext-Gwt

Today I build a small proof of concept where I called a rest-service directly from the (ext-)gwt client.
I did this by using the RequestBuilder and HttpProxy objects.

Because browsers have a same Origin Policy (browser is not allowed to call Rest service if that is not on the same domain), I will try to build a proxy on the server for that.

Other option, is to use JSON, there seems to be a work-around for calling external JSon, see

How can I dynamically fetch JSON feeds from other web domains?

A sample of the work up-to now you can find here

I am going to look at this project: gwt-rest
That might have some code ready to call REST.

Read only form field

When you set a form-field readonly with .setReadOnly(true), the font and background-color stay the same in Ext-gwt 2.0.1.
I believe it was changed in the repository, but with 2.0.1 it does not work.
disabling the field, makes the text not very readable (it is light-grey), so I want to change the background-color.

Eventually I created a helper-class with the following methods:

public static void setReadOnly(Field field){
field..setReadOnly(true);
field.addStyleName("read-only");
field.addInputStyleName("read-only");
}

public static void setReadWrite(Field field){
field.setReadOnly(false);
field.removeStyleName("read-only");
field.removeInputStyleName("read-only");
}

This works for all form-fields when using the following css:


.read-only{
background-color:#DFE8F6 !important;
background-image: none !important;
}

Changing the Theme of an Ext-Gwt application.

I have an application with the Entrypoint:
public class Appname implements EntryPoint {
public void onModuleLoad() {
GXT.setDefaultTheme(Theme.BLUE, true);
...

I wanted to change this to another theme (SLATE), so I changed the code to:
public class Appname implements EntryPoint {
public void onModuleLoad() {
ThemeManager.register(Slate.SLATE);
GXT.setDefaultTheme(Slate.SLATE, true);

This did not work. I still saw the default Blue theme.
Turns out, that I also needed to add the stylesheet like this (in the HTML-page):
<link rel="stylesheet" type="text/css" href="themes/slate/css/xtheme-slate.css" />