Serendipity - working with gwt-platform and smartGWT
In the previous post, we created a GWT starter project and refactored it in order to take advantage of the best practices supported by gwt-platform. Now, we're ready to move from a starter project to a sample application (called Serendipity) so that we can learn more about how to work with gwt-platform and smartGWT.
In this post, we'll:
- Create a GWTP starter project
- Update the starter project so that it uses smartGWT
- Create a Sign In page that uses GWT widgets
- Create an Error dialog box that uses GWT widgets
- Create a Main page using smartGWT widgets
- Create an Activities page (nested Presenter and View) that uses smartGWT widgets
- Test the application in development mode
Note: You can download the sample application from the crmdipity (Se-r-en-dipity) project's download page.
1. Create a GWTP starter project
Follow the steps in this post to create a GWTP starter project.

2. Update the starter project so that it uses smartGWT
Add the following libraries to the project:
- smartgwt.jar
- smartgwt-skins.jar
Add the libraries to your build path by right-clicking on each of the jar files and selecting "Build Path -> Add to Build Path".

We also need to update the project's module definition file:
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='serendipity'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<inherits name='com.google.gwt.inject.Inject'/>
<inherits name="com.google.gwt.uibinder.UiBinder" />
<!-- Inherit the default GWT style sheet. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- Other module inherits -->
<inherits name='com.gwtplatform.mvp.Mvp' />
<inherits name='com.gwtplatform.dispatch.Dispatch' />
<inherits name="com.smartgwt.SmartGwtNoTheme"/>
<inherits name="com.smartclient.theme.enterpriseblue.EnterpriseBlue"/>
<inherits name="com.smartclient.theme.enterpriseblue.EnterpriseBlueResources"/>
<!-- Specify the app entry point class. -->
<entry-point class='au.com.uptick.serendipity.client.Serendipity'/>
<!-- Specify the paths for translatable code -->
<source path='client'/>
<source path='shared'/>
<!-- Set user agents -->
<set-property name="user.agent" value="gecko1_8"/>
<!-- In any real-world application, you will define at least -->
<!-- one locale in addition to the default locale. -->
<extend-property name="locale" values="en"/>
<!-- Add German language support -->
<!-- <extend-property name="locale" values="de"/> -->
<define-configuration-property name="gin.ginjector"
is-multi-valued="false" />
<set-configuration-property name="gin.ginjector"
value="au.com.uptick.serendipity.client.gin.SerendipityGinjector" />
</module>
And, the application's host file:
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="gwt:property" content="locale=en">
<link type="text/css" rel="stylesheet" href="Serendipity.css">
<title>Serendipity</title>
<!-- You must set the variable isomorphicDir to [MODULE_NAME]/sc/ -->
<!-- so that the SmartGWT resources are correctly resolved -->
<script> var isomorphicDir = "serendipity/sc/"; </script>
<script type="text/javascript" language="javascript"
src="serendipity/serendipity.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>
Your web browser must have JavaScript enabled
in order for this application to display correctly.
</div>
</noscript>
</body>
</html>
3. Create a Sign In page that uses GWT widgets
The first page we want to create is the Sign In page, so we need to create a new View (ViewWithUIHandlers) class, SignInPageView:
...
public class SignInPageView extends ViewWithUiHandlers<SignInPageUiHandlers> implements
SignInPagePresenter.MyView {
private static String html = "<div>\n"
+ "<table align=\"center\">\n"
+ " <tr>\n" + "<td> </td>\n" + "<td> </td>\n" + "</tr>\n"
+ " <tr>\n" + "<td> </td>\n" + "<td> </td>\n" + "</tr>\n"
+ " <tr>\n" + "<td> </td>\n" + "<td> </td>\n" + "</tr>\n"
+ " <tr>\n"
+ " <td colspan=\"2\" style=\"font-weight:bold;\">Sign In</td>\n"
+ " </tr>\n"
+ " <tr>\n"
+ " <td>User name</td>\n"
+ " <td id=\"userNameFieldContainer\"></td>\n"
+ " </tr>\n"
+ " <tr>\n"
+ " <td>Password</td>\n"
+ " <td id=\"passwordFieldContainer\"></td>\n"
+ " </tr>\n"
+ " <tr>\n"
+ " <td></td>\n"
+ " <td id=\"signInButtonContainer\"></td>\n"
+ " </tr>\n"
+ " <tr>\n" + "<td> </td>\n" + "<td> </td>\n" + "</tr>\n"
+ " <tr>\n"
+ " <td colspan=\"2\">Forget your password?</td>\n"
+ " </tr>\n"
+ " <tr>\n"
+ " <td colspan=\"2\">Contact your Serendipity administrator.</td>\n"
+ " </tr>\n"
+ "</table>\n"
+ "</div>\n";
HTMLPanel panel = new HTMLPanel(html);
private final TextBox userNameField;
private final PasswordTextBox passwordField;
private final Button signInButton;
@Inject
public SignInPageView() {
userNameField = new TextBox();
passwordField = new PasswordTextBox();
signInButton = new Button("Sign in");
userNameField.setText("administrator");
panel.add(userNameField, "userNameFieldContainer");
panel.add(passwordField, "passwordFieldContainer");
panel.add(signInButton, "signInButtonContainer");
}
@Override
public Widget asWidget() {
return panel;
}
@Override
public String getUserName() {
return userNameField.getText();
}
@Override
public String getPassword() {
return passwordField.getText();
}
@Override
public Button getSignInButton() {
return signInButton;
}
@Override
public void resetAndFocus() {
userNameField.setFocus(true);
userNameField.selectAll();
}
}
The corresponding Presenter class, SignInPagePresenter:
...
public class SignInPagePresenter extends
Presenter<SignInPagePresenter.MyView, SignInPagePresenter.MyProxy> implements
SignInPageUiHandlers {
private final PlaceManager placeManager;
private final ErrorDialogPresenterWidget errorDialog;
@ProxyStandard
@NameToken(NameTokens.signInPage)
public interface MyProxy extends Proxy<SignInPagePresenter>, Place {
}
public interface MyView extends View, HasUiHandlers<SignInPageUiHandlers> {
String getUserName();
String getPassword();
Button getSignInButton();
void resetAndFocus();
}
@Inject
public SignInPagePresenter(EventBus eventBus, MyView view, MyProxy proxy,
PlaceManager placeManager, ErrorDialogPresenterWidget errorDialog) {
super(eventBus, view, proxy);
this.placeManager = placeManager;
this.errorDialog = errorDialog;
getView().setUiHandlers(this);
}
@Override
protected void onBind() {
super.onBind();
registerHandler(getView().getSignInButton().addClickHandler(
new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
sendCredentialsToServer();
}
}));
}
@Override
protected void onReset() {
super.onReset();
getView().resetAndFocus();
}
@Override
protected void revealInParent() {
RevealRootLayoutContentEvent.fire(this, this);
}
private void sendCredentialsToServer() {
String userName = getView().getUserName();
String password = getView().getPassword();
if (FieldVerifier.isValidUserName(userName) && (FieldVerifier.isValidPassword(password))) {
PlaceRequest myRequest = new PlaceRequest(NameTokens.mainSmartGwtPage);
// If needed, add URL parameters in this way:
// myRequest = myRequest.with( "key1", "param1" ).with( "key2", "param2" );
placeManager.revealPlace(myRequest);
}
else {
showErrorDialog();
}
}
@Override
public void showErrorDialog() {
addToPopupSlot(errorDialog);
}
}
And the UiHandlers class, SignInPageUiHandlers:
...
package au.com.uptick.serendipity.client.view;
import com.gwtplatform.mvp.client.UiHandlers;
public interface SignInPageUiHandlers extends UiHandlers {
void showErrorDialog();
}
The Sign In page:

4. Create an Error dialog box that uses GWT widgets
We also need to create an Error dialog box, so we need to create a new View (PopupViewImpl) class, ErrorDialogPopupView:
...
public class ErrorDialogPopupView extends PopupViewImpl implements MyView {
interface ErrorDialogPopupViewUiBinder extends
UiBinder<PopupPanel, ErrorDialogPopupView> {
}
private static ErrorDialogPopupViewUiBinder uiBinder = GWT.create(ErrorDialogPopupViewUiBinder.class);
@UiField
Button okButton;
private final PopupPanel widget;
@Inject
public ErrorDialogPopupView(EventBus eventBus) {
super(eventBus);
widget = uiBinder.createAndBindUi(this);
}
@Override
public Widget asWidget() {
return widget;
}
@UiHandler("okButton")
void okButtonClicked(ClickEvent event) {
widget.hide();
}
}
The corresponding Presenter (PresenterWidget) class, ErrorDialogPresenterWidget:
...
public class ErrorDialogPresenterWidget extends
PresenterWidget<ErrorDialogPresenterWidget.MyView> {
public interface MyView extends PopupView {
}
@Inject
public ErrorDialogPresenterWidget(final EventBus eventBus, final MyView view) {
super(eventBus, view);
}
}
And the UiBinder template, ErrorDialogPopupView.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <g:DialogBox modal="false" > <g:caption> <b>Error</b> </g:caption> <g:HTMLPanel> <p>Invalid User name or Password.<br /></p> <g:Button ui:field="okButton">Ok</g:Button> </g:HTMLPanel> </g:DialogBox> </ui:UiBinder>
The Error dialog box:

5. Create a Main page using smartGWT widgets
The second page we want to create is the Main page, so we need to create a new View class, MainPageSmartGwtView:
...
public class MainPageSmartGwtView extends ViewImpl implements MainPageSmartGwtPresenter.MyView {
// NORTH_HEIGHT = MASTHEAD_HEIGHT + APPLICATION_MENU_HEIGHT + NAVIGATION_PANE_HEADER_HEIGHT
private static final int NORTH_HEIGHT = 85;
private static final int DEFAULT_MENU_WIDTH = 70;
private static final String DEFAULT_MARGIN = "0px";
private final Masthead masthead;
private final ApplicationMenu applicationMenu;
private final NavigationPaneHeader navigationPaneHeader;
private final NavigationPane navigationPane;
private VLayout panel;
private HLayout northLayout;
private HLayout southLayout;
private VLayout westLayout;
@Inject
public MainPageSmartGwtView(Masthead masthead, ApplicationMenu applicationMenu,
NavigationPaneHeader navigationPaneHeader, NavigationPane navigationPane) {
this.masthead = masthead;
this.applicationMenu = applicationMenu;
this.navigationPaneHeader = navigationPaneHeader;
this.navigationPane = navigationPane;
// get rid of scroll bars, and clear out the window's built-in margin,
// because we want to take advantage of the entire client area
Window.enableScrolling(false);
Window.setMargin(DEFAULT_MARGIN);
// initialise the main layout container
panel = new VLayout();
panel.setWidth100();
panel.setHeight100();
// initialise the North layout container
northLayout = new HLayout();
northLayout.setHeight(NORTH_HEIGHT);
initApplicationMenu();
// initialise the nested layout container
VLayout vLayout = new VLayout();
vLayout.addMember(this.masthead);
vLayout.addMember(this.applicationMenu);
vLayout.addMember(this.navigationPaneHeader);
// add the nested layout container to the North layout container
northLayout.addMember(vLayout);
initNavigationPane();
// initialise the West layout container
westLayout = this.navigationPane;
// initialise the South layout container
southLayout = new HLayout();
// add the North and South layout containers to the main layout container
panel.addMember(northLayout);
panel.addMember(southLayout);
}
@Override
public Widget asWidget() {
return panel;
}
@Override
public void setInSlot(Object slot, Widget content) {
GWT.log("MainPageSmartGwtView.setInSlot()... ", null);
if (slot == MainPageSmartGwtPresenter.TYPE_SetContextAreaContent) {
if (content != null) {
southLayout.setMembers(westLayout, (VLayout)content);
}
} else {
super.setInSlot(slot, content);
}
}
private void initApplicationMenu() {
applicationMenu.addMenu(Serendipity.getConstants().NewActivityMenuName(),
DEFAULT_MENU_WIDTH, Serendipity.getConstants().NewActivityMenuItemNames(),
null);
applicationMenu.addMenu(Serendipity.getConstants().NewRecordMenuName(),
DEFAULT_MENU_WIDTH, Serendipity.getConstants().NewRecordMenuItemNames(),
null);
Menu goToMenu = applicationMenu.addMenu(Serendipity.getConstants().GoToMenuName(),
DEFAULT_MENU_WIDTH - 30 );
applicationMenu.addSubMenu(goToMenu, Serendipity.getConstants().SalesMenuItemName(),
Serendipity.getConstants().SalesMenuItemNames(),
null);
applicationMenu.addSubMenu(goToMenu, Serendipity.getConstants().SettingsMenuItemName(),
Serendipity.getConstants().SettingsMenuItemNames(),
null);
applicationMenu.addSubMenu(goToMenu, Serendipity.getConstants().ResourceCentreMenuItemName(),
Serendipity.getConstants().ResourceCentreMenuItemNames(),
null);
applicationMenu.addMenu(Serendipity.getConstants().ToolsMenuName(),
DEFAULT_MENU_WIDTH - 30, Serendipity.getConstants().ToolsMenuItemNames(),
null);
applicationMenu.addMenu(Serendipity.getConstants().HelpMenuName(),
DEFAULT_MENU_WIDTH - 30, Serendipity.getConstants().HelpMenuItemNames(),
null);
}
private void initNavigationPane() {
navigationPane.add(Serendipity.getConstants().SalesStackSectionName(),
SalesNavigationPaneSectionData.getRecords(),
SalesDataSource.getInstance());
navigationPane.add(Serendipity.getConstants().SettingsStackSectionName(),
SettingsNavigationPaneSectionData.getRecords(),
SettingsDataSource.getInstance());
navigationPane.add(Serendipity.getConstants().ResourceCentreStackSectionName(),
ResourceCentreNavigationPaneSectionData.getRecords(),
ResourceCentreDataSource.getInstance());
}
public NavigationPaneHeader getNavigationPaneHeader() {
return navigationPaneHeader;
}
public NavigationPane getNavigationPane() {
return navigationPane;
}
}
The corresponding Presenter class, MainPageSmartGwtPresenter:
...
public class MainPageSmartGwtPresenter extends
Presenter<MainPageSmartGwtPresenter.MyView, MainPageSmartGwtPresenter.MyProxy> {
private final PlaceManager placeManager;
@ProxyCodeSplit
@NameToken(NameTokens.mainSmartGwtPage)
public interface MyProxy extends Proxy<MainPageSmartGwtPresenter>, Place {
}
public interface MyView extends View {
NavigationPaneHeader getNavigationPaneHeader();
NavigationPane getNavigationPane();
}
/**
* Use this in leaf presenters, inside their {@link #revealInParent} method.
*/
@ContentSlot
public static final Type<RevealContentHandler<?>> TYPE_SetContextAreaContent = new Type<RevealContentHandler<?>>();
@Inject
public MainPageSmartGwtPresenter(EventBus eventBus, MyView view, MyProxy proxy,
PlaceManager placeManager) {
super(eventBus, view, proxy);
this.placeManager = placeManager;
}
@Override
protected void onBind() {
super.onBind();
GWT.log("MainPageSmartGwtPresenter.onBind()... ", null);
// register Handler's
getView().getNavigationPane().addRecordClickHandler("Sales", new NavigationPaneClickHandler() );
PlaceRequest myRequest = new PlaceRequest(NameTokens.activities);
placeManager.revealPlace(myRequest);
getView().getNavigationPane().selectRecord(NameTokens.activities);
}
@Override
protected void onReveal() {
super.onReveal();
// getView().getNavigationPane().selectRecord(NameTokens.activities);
}
@Override
protected void onReset() {
super.onReset();
}
@Override
protected void revealInParent() {
RevealRootLayoutContentEvent.fire(this, this);
}
public class NavigationPaneClickHandler implements RecordClickHandler {
@Override
public void onRecordClick(RecordClickEvent event) {
Record record = event.getRecord();
String name = record.getAttributeAsString("name");
GWT.log("NavigationPaneClickHandler.onRecordClick() - " + name, null);
PlaceRequest myRequest = new PlaceRequest(name);
placeManager.revealPlace(myRequest);
getView().getNavigationPaneHeader().setContextAreaHeaderLabelContents(name);
}
}
}
And the PlaceManger class, SerendipityPlaceManager:
...
public class SerendipityPlaceManager extends PlaceManagerImpl {
private final PlaceRequest defaultPlaceRequest;
@Inject
public SerendipityPlaceManager(EventBus eventBus, TokenFormatter tokenFormatter,
@DefaultPlace String defaultNameToken) {
super(eventBus, tokenFormatter);
this.defaultPlaceRequest = new PlaceRequest(defaultNameToken);
}
@Override
public void revealDefaultPlace() {
revealPlace(defaultPlaceRequest);
}
@Override
public void revealErrorPlace(String invalidHistoryToken) {
PlaceRequest myRequest = new PlaceRequest(NameTokens.errorPage);
revealPlace(myRequest);
}
}
6. Create an Activities page (nested Presenter and View) that uses smartGWT widgets
The third page we want to create is the Activities page, so we need to create a new View class, ActivitiesView:
...
public class ActivitiesView extends ViewImpl implements ActivitiesPresenter.MyView {
private static final String CONTEXT_AREA_WIDTH = "*";
private final ToolBar toolbar;
private final ActivitiesContextAreaListGrid listGrid;
private final StatusBar statusBar;
private VLayout panel;
@Inject
public ActivitiesView(ToolBar toolbar, ActivitiesContextAreaListGrid listGrid,
StatusBar statusBar) {
GWT.log("init ActivitiesView()...", null);
this.toolbar = toolbar;
this.listGrid = listGrid;
this.statusBar = statusBar;
panel = new VLayout();
// initialise the Activities View layout container
panel.addStyleName("crm-ContextArea");
panel.setWidth(CONTEXT_AREA_WIDTH);
// add the Tool Bar, List Grid, and Status Bar to the Activities View layout container
panel.addMember(this.toolbar);
panel.addMember(this.listGrid);
panel.addMember(this.statusBar);
// this.addMember(this.jumpBar);
}
@Override
public Widget asWidget() {
return panel;
}
}
And the corresponding Presenter class, ActivitiesPresenter:
...
public class ActivitiesPresenter extends
Presenter<ActivitiesPresenter.MyView, ActivitiesPresenter.MyProxy> {
private final PlaceManager placeManager;
@ProxyCodeSplit
@NameToken(NameTokens.activities)
public interface MyProxy extends Proxy<ActivitiesPresenter>, Place {
}
public interface MyView extends View {
}
@Inject
public ActivitiesPresenter(EventBus eventBus, MyView view, MyProxy proxy,
PlaceManager placeManager) {
super(eventBus, view, proxy);
this.placeManager = placeManager;
}
@Override
protected void onBind() {
super.onBind();
}
@Override
protected void onReset() {
super.onReset();
}
@Override
protected void revealInParent() {
RevealContentEvent.fire(this, MainPageSmartGwtPresenter.TYPE_SetContextAreaContent,
this);
}
}
The Main page (and the nested Activities presenter and view):

The Main page (and the nested Calendar presenter and view):

The Main page (and the nested Accounts presenter and view):

You may recall from the previous post that GIN requires us to create a method for each object type we want to create and then an implementation of the interface will be generated for us at compile time. So, we need to update the Ginjector class, SerendipityGinjector:
...
@GinModules({DispatchAsyncModule.class, ClientModule.class})
public interface SerendipityGinjector extends Ginjector {
EventBus getEventBus();
PlaceManager getPlaceManager();
Provider<SignInPagePresenter> getSignInPagePresenter();
AsyncProvider<ErrorPagePresenter> getErrorPagePresenter();
AsyncProvider<MainPagePresenter> getMainPagePresenter();
AsyncProvider<MainPageSmartGwtPresenter> getMainPageSmartGwtPresenter();
AsyncProvider<ActivitiesPresenter> getActivitiesPresenter();
AsyncProvider<CalendarPresenter> getCalendarPresenter();
AsyncProvider<AccountsPresenter> getAccountsPresenter();
ProxyFailureHandler getProxyFailureHandler();
}
We also need to bind the various classes and providers using a module. The AbstractPresenterModule class, ClientModule:
...
public class ClientModule extends AbstractPresenterModule {
@Override
protected void configure() {
bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
bind(PlaceManager.class).to(SerendipityPlaceManager.class).in(Singleton.class);
bind(TokenFormatter.class).to(ParameterTokenFormatter.class).in(
Singleton.class);
bind(RootPresenter.class).asEagerSingleton();
bind(ProxyFailureHandler.class).to(DefaultProxyFailureHandler.class).in(
Singleton.class);
// Constants
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.signInPage);
// Presenters
bindPresenter(ErrorPagePresenter.class, ErrorPagePresenter.MyView.class,
ErrorPageView.class, ErrorPagePresenter.MyProxy.class);
bindPresenter(SignInPagePresenter.class, SignInPagePresenter.MyView.class,
SignInPageView.class, SignInPagePresenter.MyProxy.class);
bindSingletonPresenterWidget(ErrorDialogPresenterWidget.class,
ErrorDialogPresenterWidget.MyView.class, ErrorDialogPopupView.class);
bindPresenter(MainPagePresenter.class, MainPagePresenter.MyView.class,
MainPageView.class, MainPagePresenter.MyProxy.class);
bindPresenter(MainPageSmartGwtPresenter.class, MainPageSmartGwtPresenter.MyView.class,
MainPageSmartGwtView.class, MainPageSmartGwtPresenter.MyProxy.class);
// Sales
bindPresenter(ActivitiesPresenter.class, ActivitiesPresenter.MyView.class,
ActivitiesView.class, ActivitiesPresenter.MyProxy.class);
bindPresenter(CalendarPresenter.class, CalendarPresenter.MyView.class,
CalendarView.class, CalendarPresenter.MyProxy.class);
bindPresenter(AccountsPresenter.class, AccountsPresenter.MyView.class,
AccountsView.class, AccountsPresenter.MyProxy.class);
}
}
The application's entry point
In the application's entry point class we need to create the ginjector, ensure everything is bound correctly, and reveal the current place in the URL:
...
public class Serendipity implements EntryPoint {
interface GlobalResources extends ClientBundle {
@NotStrict
@Source("Serendipity.css")
CssResource css();
}
private static SerendipityConstants constants;
public final SerendipityGinjector ginjector = GWT.create(SerendipityGinjector.class);
public void onModuleLoad() {
GWT.log("init OnLoadModule()...", null);
// inject global styles
GWT.<GlobalResources>create(GlobalResources.class).css().ensureInjected();
// load constants
constants = (SerendipityConstants) GWT.create(SerendipityConstants.class);
// this is required by gwt-platform proxy's generator
DelayedBindRegistry.bind(ginjector);
ginjector.getPlaceManager().revealCurrentPlace();
}
public static SerendipityConstants getConstants() {
return constants;
}
}
6. Test the application in development mode
At this point, you should be able to compile the new sample application and launch it from within Eclipse:

Note: You can download the sample application from the crmdipity (Se-r-en-dipity) project's download page.
What's Next
At this point, we've created a sample application so that we could learn more about gwt-platform and smartGWT. Next we'll add a few more features to our sample application, Serendipity.
- Tags:

Comments
Great tutorial
Thanks for posting!
:)
Great posts
Hi,
Thanks for the posts re gwt-platform and SmartGwt.
Keep up the good work :-)
Regards
Chris
Loading
hello thanks for sharing, i have a bug when i try to run the serendipity, the page only stay in the loading and the following errors display the development mode, i download the source code from the google code page v. 0.3.0
00:00:29.908 [ERROR] Errors in 'file:/E:/Programacion/java/codigo/Serendipity/src/au/com/uptick/serendipity/client/sales/account/presenter/AccountInformationPresenter.java'
00:00:29.908 [ERROR] Line 77: No source code is available for type au.com.uptick.serendipity.shared.action.RetrieveAccountAction; did you forget to inherit a required module?
00:00:29.908 [ERROR] Line 78: No source code is available for type au.com.uptick.serendipity.shared.action.RetrieveAccountResult; did you forget to inherit a required module?
00:00:29.908 [ERROR] Errors in 'file:/E:/Programacion/java/codigo/Serendipity/src/au/com/uptick/serendipity/client/sales/presenter/AccountsPresenter.java'
00:00:29.908 [ERROR] Line 83: No source code is available for type au.com.uptick.serendipity.shared.action.RetrieveAccountsAction; did you forget to inherit a required module?
00:00:29.908 [ERROR] Line 84: No source code is available for type au.com.uptick.serendipity.shared.action.RetrieveAccountsResult; did you forget to inherit a required module?
Loading Serendipity
Hi,
Is there an issue with the setup of your environment?
Within Eclipse you should be able to right-click on Serendipity in the Package Explorer and then choose Run As -> Web Application.
Then choose "Serendipity.html" when prompted for the HTML Page Selection.
If you are still having problems please raise an issue -> http://code.google.com/p/crmdipity/issues/list
Cheers
Rob
GWT 2.4, GWTP 0.6 and smartGWT 2.5
Thanks a lot for these tutorials which have helped me to learn about gwt-platform.
What do I need to do in order to migrate Serendipity to GWT 2.4, GWTP 0.6 and smartGWT 2.5?
Re: GWT 2.4, GWTP 0.6 and smartGWT 2.5
Hi,
Take a look at the GWTP porting page:
-> http://code.google.com/p/gwt-platform/wiki/PortingV1
and the gwt-cx pom.xml's:
-> http://code.google.com/p/gwt-cx/source/browse/trunk/gwtcx/pom.xml
Cheers
Rob