web-development using gwt + mvp4g

305
GWT + mvp4g Anthony Kotenko, iPark ventures™ 2011 © web-development using

Upload: ulric-wilfred

Post on 29-Nov-2014

714 views

Category:

Documents


3 download

DESCRIPTION

Slides for the lecture at ADDConf (http://addconf.ru) 2011

TRANSCRIPT

Page 1: Web-Development Using GWT + mvp4g

GWT + mvp4g

Anthony Kotenko, iPark ventures™2011 ©

web-development using

Page 2: Web-Development Using GWT + mvp4g

This presentation was specially prepared forApplication Developer Days 2011

Saint-Petersburg, Russia

Page 3: Web-Development Using GWT + mvp4g

goo.gl/4GgnS

Slides — there

[ PDF, ~2MB ]

Page 4: Web-Development Using GWT + mvp4g

Anthony Kotenko6 years in Java EE development

6 years in UI development

Sex: male

Page 5: Web-Development Using GWT + mvp4g

Anthony Kotenko6 years in Java EE development

6 years in UI development

Sex: male

http://shamansir.madfire.net

http://zokotuhaFly.habrahabr.ru

http://twitter.com/shaman_sir

http://profiles.google.com/shaman.sir

Page 6: Web-Development Using GWT + mvp4g
Page 7: Web-Development Using GWT + mvp4g

Schedule

Page 8: Web-Development Using GWT + mvp4g

1. Introduction. A brief history and examples of GWT usage

2. A brief introduction to concepts: - MVP / Reverse MVP - EventBus - Dependency Injection

3. Description of mvp4g framework - differences in RMVP implementation from GWT - difference in implementation of EventBus - multimoduleness - HistoryConverter conception - advantages / disadvantages

Page 9: Web-Development Using GWT + mvp4g

6. Working with non-Java Server-Side-API (versus RPC-services) - making call chains - callback vs. GwtEvent - advantages / disadvantages

4. Components in GWT - UiBinder, standard components - custom widgets development

7. i18n in GWT

5. Our layouting system development

8. Conclusion. Links to the examples

Page 10: Web-Development Using GWT + mvp4g

Your questions may (and must be) asked during the lecture:to let reporter know about you having question regarding the theme or not,

just raise your hand (any of them).

Like so:

Discussion is important

I have a question!

Page 11: Web-Development Using GWT + mvp4g
Page 12: Web-Development Using GWT + mvp4g

1. Briefly 'bout GWT

Page 13: Web-Development Using GWT + mvp4g

GWT

code.google.com/webtoolkit/

GoogleWebToolkit

/ˈɡwɪt/

Page 14: Web-Development Using GWT + mvp4g

GWT

/ˈɡwɪt/

Page 15: Web-Development Using GWT + mvp4g

/ˈɡwɪt/

Page 16: Web-Development Using GWT + mvp4g

Used in these projects:

Google Wave wave.google.com

Google Checkout checkout.google.com

Google Moderator google.com/moderator

Whirled whirled.com

Lombardi Blueprint blueprint.lombardi.com

ContactOffice beta.contactoffice.com

Page 17: Web-Development Using GWT + mvp4g

Used in these projects:

GoGrid gogrid.com

Curriki curriki.org

OpenKM openkm.com

Kdice kdice.com

SeeMap seemap.ru

Одноклассники odnoklassniki.ru

Page 18: Web-Development Using GWT + mvp4g

A box of useful tools

Page 19: Web-Development Using GWT + mvp4g

A box of useful toolsThe most complete

for web-developer

Page 20: Web-Development Using GWT + mvp4g

widgets

http://old.ongwt.com/public/WindowsLiveWriter_GWTMosaicnicewidgetlibrary_D777_image_2.png

Page 21: Web-Development Using GWT + mvp4g

widgetsoptimization

http://radar.oreilly.com/200912081729.jpg

Page 22: Web-Development Using GWT + mvp4g

widgets

cross-browserly!optimization

http://2.bp.blogspot.com/_VzXmgKXrn6Y/TKB2a3eZTBI/AAAAAAAAAaQ/mn7NmabwO8U/s1600/browsers%5Btsksoft.blogspot.com%5D.jpg

Page 23: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

on-the-fly development

optimization

http://lh4.ggpht.com/_a0imbbK4r5U/Sxwd1oVpXiI/AAAAAAAAAjc/gsRkQUn9kZI/gwt-dev-mode.png

Page 24: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

on-the-fly development

optimization

OOP benefits

Page 25: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

on-the-fly development

optimization

OOP benefits debug

http://www.ibm.com/developerworks/library/j-ajax4/eclipse-debug.jpg

Page 26: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

on-the-fly development

optimization

OOP benefits debug

RPCAPI/DB

Page 27: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

simple i18n

on-the-fly development

optimization

OOP benefits debug

RPC

http://test.ical.ly/wp-content/uploads/2010/04/i18n.png

Page 28: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

simple i18n

on-the-fly development

optimization

OOP benefits

Code Splitting

debug

RPC

Page 29: Web-Development Using GWT + mvp4g

widgets

cross-browserly!

simple i18n

on-the-fly development

optimization

OOP benefits

Code Splitting

debug

RPC

Page 30: Web-Development Using GWT + mvp4g

http://www.safetylca.org/images/toolbox.jpg

Page 31: Web-Development Using GWT + mvp4g

http://blog.ericlamb.net/wp-content/uploads/2009/08/toolbox.jpghttp://www.safetylca.org/images/toolbox.jpg

Page 32: Web-Development Using GWT + mvp4g

GWT is a box of useful tools/ˈɡwɪt/

Page 33: Web-Development Using GWT + mvp4g
Page 34: Web-Development Using GWT + mvp4g

History

Page 35: Web-Development Using GWT + mvp4g

Version 1.0was released in 2006

Page 36: Web-Development Using GWT + mvp4g

Version 1.0was released in 2006

Version 1.6Google Eclipse Plugin

Project structure matchesWeb Application specification

Page 37: Web-Development Using GWT + mvp4g

Version 2.0 - Development Mode - Code Splitting - Declarative UI - Client Bundle

Page 38: Web-Development Using GWT + mvp4g

Version 2.1 MVP-conception RequestFactory / Editors

Page 39: Web-Development Using GWT + mvp4g

Version 2.1 MVP-conception RequestFactory / Editors

Version 2.2 UI Designer HTML5 Canvas support only Java 1.6 was left

Page 40: Web-Development Using GWT + mvp4g

Quake 2 in browser

https://y2mzuw.blu.livefilestore.com/y1m9Pc7Xi6qtMdKU_hGCv7VZrEKiIZTYqDIC5laL9A0LxracK6AN8EAet90MRtWlBJISphNp_Y8QCxpb0p9v1ylTCdwATCweUs9496DC14_ijBjhnpj2oRWme9B1SC2C0t9HJ1wX8RTsVQAhyDYCsqfeg/quake-html5-04-02-2010.jpg

quake2-gwt-port.appspot.com

Page 41: Web-Development Using GWT + mvp4g

Quake 2 in browserquake2-gwt-port.appspot.com

Page 42: Web-Development Using GWT + mvp4g

TrendyYouth

Modern

Page 43: Web-Development Using GWT + mvp4g

GWT is actively developing project, however it already contains everything you need

/ˈɡwɪt/

Page 44: Web-Development Using GWT + mvp4g
Page 45: Web-Development Using GWT + mvp4g

2. GWT Conceptions

Page 46: Web-Development Using GWT + mvp4g

almaer.com/blog/rotating-java-and-javascript-on-the-server

Page 47: Web-Development Using GWT + mvp4g

Any GWT-project starts from entry point

EntryPoint

Page 48: Web-Development Using GWT + mvp4g

● Java → JavaScript, JSNI● Development Mode● Code Splitting●<Module>.gwt.xml● MVC, MVP, RMVP, EventBus● Deferred Binding● Dependency Injection● Remote Service● JUnit● Disadvantages and remarks

Page 49: Web-Development Using GWT + mvp4g

JavaScript Logo is from marakana.com

Page 50: Web-Development Using GWT + mvp4g

JSNI

JavaScript Native Interface

Page 51: Web-Development Using GWT + mvp4g

JSNI

public native static void <functionName>(<parameters>) /*-{ . . . @<path.to.the.package>.<ClassName>::<methodName>( /L<param-type>;/L<param-type>;...)(<arguments>);

. . .

}-*/;

Page 52: Web-Development Using GWT + mvp4g

JSNI

public native static void getJson(int requestId, String url, StockWatcher handler) /*-{ var callback = "callback" + requestId; var script = document.createElement("script"); script.setAttribute("src", url+callback); script.setAttribute("type", "text/javascript");

window[callback] = function(jsonObj) { [email protected] .client.StockWatcher::handleJsonResponse( Lcom/google/gwt/core/client/JavaScriptObject;)(jsonObj); window[callback + "done"] = true; } setTimeout(function() { if (!window[callback + "done"]) { [email protected] .client.StockWatcher::handleJsonResponse( Lcom/google/gwt/core/client/JavaScriptObject;)(null); }

document.body.removeChild(script); delete window[callback]; delete window[callback + "done"]; }, 1000); document.body.appendChild(script);}-*/;

Page 53: Web-Development Using GWT + mvp4g

JSNI

You can wrap native JavaScript widgets with JSNI.For example, Google Maps or any WYSIWYG-editor

Page 54: Web-Development Using GWT + mvp4g

JSNI

WYSIWYG-widget,written in Closure

and integrated with the help of JSNIGoogle Maps widget,

integrated with the help of JSNI

Flash-objectusing JavaScript-callbacks,

which are called through JSNI

Page 55: Web-Development Using GWT + mvp4g

You can use JSNI tomake third-party components

written in JavaScriptbecome GWT-widgets

Page 56: Web-Development Using GWT + mvp4g
Page 57: Web-Development Using GWT + mvp4g

Development Mode

Page 58: Web-Development Using GWT + mvp4g

Development Modehttp://lc:8080/ui/?gwt.codesvr=lc:9997#!job/start

Page 59: Web-Development Using GWT + mvp4g

Development Modehttp://lc:8080/ui/?gwt.codesvr=lc:9997#!job/start

(but not for Opera)the plugin for your lovely browser

the plugin for your lovely IDE

Page 60: Web-Development Using GWT + mvp4g

Development Modehttp://lc:8080/ui/?gwt.codesvr=lc:9997#!job/start

http://lh4.ggpht.com/_a0imbbK4r5U/Sxwd1oVpXiI/AAAAAAAAAjc/gsRkQUn9kZI/gwt-dev-mode.png

Page 61: Web-Development Using GWT + mvp4g

Development Modehttp://lc:8080/ui/?gwt.codesvr=lc:9997#!job/start

http://lh4.ggpht.com/_a0imbbK4r5U/Sxwd1oVpXiI/AAAAAAAAAjc/gsRkQUn9kZI/gwt-dev-mode.png

Page 62: Web-Development Using GWT + mvp4g

Development Mode helps in debugging your project: when you change your Java-code

just press Ctrl+F5 in your browser — and your changes will come into force! Mrrwah!

Page 63: Web-Development Using GWT + mvp4g
Page 64: Web-Development Using GWT + mvp4g

Code Splitting

when the neccessary code was loaded

Page 65: Web-Development Using GWT + mvp4g

Code Splitting Spell isoid createAsync(final MClient client) {

    GWT.runAsync(...)      public void onFailure(Throwable err) {        . . .      }

      public void onSuccess() {        if (instance == null) {        . . .  instance = new Module();        . . .        client.onSuccess(instance);      }    });} when the neccessary code was loaded

Page 66: Web-Development Using GWT + mvp4g

Code Splitting Spell isSp createAsync(final MClient client) {

    GWT.runAsync(new RunAsyncCallback() {      public void onFailure(Throwable err) {        . . .      }

      public void onSuccess() {        if (instance == null) {        . . .  instance = new Module();        . . .        client.onSuccess(instance);      }    });} when the neccessary code was loaded

Page 67: Web-Development Using GWT + mvp4g

Code Splittingpublic static void createAsync(final MClient client) {

    GWT.runAsync(new RunAsyncCallback() {      public void onFailure(Throwable err) {        client.onUnavailable();      }

      public void onSuccess() {        if (instance == null) {          instance = new Module();        }        client.onSuccess(instance);      }    });} when the neccessary code was loaded

Page 68: Web-Development Using GWT + mvp4g

Code Splitting lets you specify separate parts of your project to load:

so you can split your project in large modules — and your users will feel themselves happy! Brrlyawrr!

Page 69: Web-Development Using GWT + mvp4g
Page 70: Web-Development Using GWT + mvp4g

<Module>.gwt.xml

Page 71: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

a list of code components you use

Page 72: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

a list of code components you use

⁕ Browsers

a list of browsers to be a target of project compilation

Page 73: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

a list of code components you use

⁕ Browsers

a list of browsers to be a target of project compilation

⁕ Locales

a list of locales supported in your project

Page 74: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

a list of code components you use

⁕ Browsers

a list of browsers to be a target of project compilation

⁕ Locales

a list of locales supported in your project

⁕ Debug

turning debug information output on/off

Page 75: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

<inherits name="com.google.gwt.user.User"/>

⁕ Browsers

⁕ Locales

⁕ Debug

Page 76: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

<inherits name="com.google.gwt.user.User"/>

⁕ Browsers

<set-property name="user.agent" value="ie6,gecko1_8,safari" />

⁕ Locales

⁕ Debug

Page 77: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

<inherits name="com.google.gwt.user.User"/>

⁕ Browsers

<set-property name="user.agent" value="ie6,gecko1_8,safari" />

⁕ Locales

<extend-property name="locale" values="fr_CA,de" /> <set-property-fallback name="locale" value="fr_CA" />

⁕ Debug

Page 78: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

<inherits name="com.google.gwt.user.User"/>

⁕ Browsers

<set-property name="user.agent" value="ie6,gecko1_8,safari" />

⁕ Locales

<extend-property name="locale" values="fr_CA,de" /> <set-property-fallback name="locale" value="fr_CA" />

⁕ Debug [<Module>Debug.gwt.xml]

Page 79: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

<inherits name="com.google.gwt.user.User"/>

⁕ Browsers

<set-property name="user.agent" value="ie6,gecko1_8,safari" />

⁕ Locales

<extend-property name="locale" values="fr_CA,de" /> <set-property-fallback name="locale" value="fr_CA" />

⁕ Debug [<Module>Debug.gwt.xml]

<inherits name="com.example.MainModule" /> <set-property name="log_level" value="DEBUG" />

Page 80: Web-Development Using GWT + mvp4g

<Module>.gwt.xml⁕ Components

<inherits name="com.google.gwt.user.User" />

⁕ Browsers

<set-property name="user.agent" value="ie6,gecko1_8,safari" />

⁕ Locales

<extend-property name="locale" values="fr_CA,de" /> <set-property-fallback name="locale" value="fr_CA" />

⁕ Debug [<Module>Debug.gwt.xml]

<inherits name="com.example.MainModule" /> <set-property name="log_level" value="DEBUG" />

Page 81: Web-Development Using GWT + mvp4g

.gwt.xml file — is almost the same thing as web.xml file for web application:

here lies all of the project configuration

Page 82: Web-Development Using GWT + mvp4g
Page 83: Web-Development Using GWT + mvp4g

MVP

R

Page 84: Web-Development Using GWT + mvp4g

ModelViewController

Page 85: Web-Development Using GWT + mvp4g

ModelViewController

API/DB

Page 86: Web-Development Using GWT + mvp4g

ModelViewController

calls

Page 87: Web-Development Using GWT + mvp4g

ModelViewPresenter

Page 88: Web-Development Using GWT + mvp4g

ModelViewPresenter

events

upda

te

Page 89: Web-Development Using GWT + mvp4g

ModelViewPresenter

Reverse

Page 90: Web-Development Using GWT + mvp4g

ModelViewPresenter

Reverse

Page 91: Web-Development Using GWT + mvp4g

PresenterEvent Bus

Page 92: Web-Development Using GWT + mvp4g

PresenterEvent Bus

PresenterPresenter

Page 93: Web-Development Using GWT + mvp4g

PEB

PP P P P P

Page 94: Web-Development Using GWT + mvp4g

Hmmm... To be honest, seems I did not understand the difference

between all those mah-fah-am-wee-pee...

Page 95: Web-Development Using GWT + mvp4g

geekswithblogs.net/kobush/archive/2006/01/09/65305.aspx

Difference between MVC and MVP

Page 96: Web-Development Using GWT + mvp4g

geekswithblogs.net/kobush/archive/2006/01/09/65305.aspx

The article about MVC/MVP difference

Page 97: Web-Development Using GWT + mvp4g

tv.jetbrains.net/videocontent/gwt-event-bus-basics

The video with the example of EventBus in work

Page 98: Web-Development Using GWT + mvp4g

tv.jetbrains.net/videocontent/gwt-event-bus-basics

The video with the example of EventBus in work

Page 99: Web-Development Using GWT + mvp4g

EventBus is the central communication channel

Page 100: Web-Development Using GWT + mvp4g
Page 101: Web-Development Using GWT + mvp4g

Deferred Binding

Page 102: Web-Development Using GWT + mvp4g

Deferred Binding

In response to the lack of Reflection

Page 103: Web-Development Using GWT + mvp4g

Deferred Binding

Dynamic implementation of any interface (and just in case if it is actually required)

In response to the lack of Reflection

Page 104: Web-Development Using GWT + mvp4g

Deferred Binding

GWT.create(....class) spell

Dynamic implementation of any interface (and just in case if it is actually required)

In response to the lack of Reflection

Page 105: Web-Development Using GWT + mvp4g

Deferred Binding

GWT.create(....class) spell

Dynamic implementation of any interface (and just in case if it is actually required)

CompileTime-binding

In response to the lack of Reflection

Page 106: Web-Development Using GWT + mvp4g

Deferred Binding

GWT.create(....class) spell

Dynamic implementation of any interface (and just in case if is actually required)

CompileTime-binding

In response to the lack of Reflection

Page 107: Web-Development Using GWT + mvp4g

Deferred Binding

PopupImpl: public void setVisible(boolean visible) { // ... common code for all implementations of PopupPanel ...

// If the PopupImpl creates an iframe shim, it's also // necessary to hide it as well. impl.setVisible(getElement(), visible);}

Page 108: Web-Development Using GWT + mvp4g

Deferred Binding

PopupImpl: public void setVisible(boolean visible) { // ... common code for all implementations of PopupPanel ...

// If the PopupImpl creates an iframe shim, it's also // necessary to hide it as well. impl.setVisible(getElement(), visible);}

PopupImplIE6: public native void setVisible(Element popup, boolean visible) /*-{ if (popup.__frame) { popup.__frame.style.visibility = visible ? 'visible' : 'hidden'; } }-*/;

Page 109: Web-Development Using GWT + mvp4g

Deferred Binding

<replace-with class="com.google.gwt...PopupImplIE6"> <when-type-is class="com.google.gwt...PopupImpl" /> <any> <when-property-is name="user.agent" value="ie6" /> <when-property-is name="user.agent" value="ie6_1" /> </any></replace-with>

Page 110: Web-Development Using GWT + mvp4g

Deferred Binding

<replace-with class="com.google.gwt...PopupImplIE6"> <when-type-is class="com.google.gwt...PopupImpl" /> <any> <when-property-is name="user.agent" value="ie6" /> <when-property-is name="user.agent" value="ie6_1" /> </any></replace-with>

private static final PopupImpl impl = GWT.create(PopupImpl.class);

Page 111: Web-Development Using GWT + mvp4g

www.docstoc.com/docs/53396874/Deferred-Binding-The-Magic-of-GWT

Slides on Deferred Binding

Page 112: Web-Development Using GWT + mvp4g

www.docstoc.com/docs/53396874/Deferred-Binding-The-Magic-of-GWT

Slides on Deferred Binding

Page 113: Web-Development Using GWT + mvp4g

Deferred Binding is a tool to create cross-browserand translingual implementations.

Namely for techniques that will differ betweencontexts of project usage.

Page 114: Web-Development Using GWT + mvp4g
Page 115: Web-Development Using GWT + mvp4g

★ Attention ★Attention!

Page 116: Web-Development Using GWT + mvp4g

Dependency Injection

Page 117: Web-Development Using GWT + mvp4g

Dependency Injection

Using GWT INjection / Guice frameworks

Page 118: Web-Development Using GWT + mvp4g

Dependency Injection

Binding instances to interfaces at one point (thus we achieve separation of behaviorfrom implementing solution)

Using GWT INjection / Guice frameworks

Page 119: Web-Development Using GWT + mvp4g

Dependency Injection

Lets you forget about XML-settings andfactories

Binding instances to interfaces at one point(thus we achieve separation of behaviorfrom implementing solution)

Using GWT INjection / Guice frameworks

Page 120: Web-Development Using GWT + mvp4g

Dependency Injection

Lets you forget about XML-settings andfactories

Binding instances to interfaces at one point(thus we achieve separation of behaviorfrom implementing solution)

Runtime-binding

Using GWT INjection / Guice frameworks

Page 121: Web-Development Using GWT + mvp4g

Dependency Injection

Lets you forget about XML-settings andfactories

Binding instances to interfaces at one point (thus we achieve separation of behaviorfrom implementing solution)

Runtime-binding

Using GWT INjection / Guice frameworks

Page 122: Web-Development Using GWT + mvp4g

Dependency Injectionclass MyModule extends AbstractGinModule { @Override protected void configure() { bind(Something.class).toProvider(SomethingProvider.class); bind(Any.class).in(Singleton.class); bind(Foo.class).to(SomeFooImpl.class); }}

class Bar { @Inject private Any any; private final Something something; private final Foo foo;

@Inject public Bar(Something something, Foo foo) { }}

Page 123: Web-Development Using GWT + mvp4g

Dependency Injection

@GinModules(MyModule.class)interface class MyGinjector extends Ginjector { public Something getSomething(); public Foo getFoo();

}

Page 124: Web-Development Using GWT + mvp4g

code.google.com/p/google-guice/wiki/Motivation?tm=6

Guice wiki-pages

Page 125: Web-Development Using GWT + mvp4g

Dependency Injection lets you easily manage your logical implementations.

Even when your project is running.

For example, you can switch database drivers or

service implementations.

These are the things you've doneusing application-context.xml

in Spring, but much better.

Annotations are wonderrrful!

Page 126: Web-Development Using GWT + mvp4g
Page 127: Web-Development Using GWT + mvp4g

Remote Service

Page 128: Web-Development Using GWT + mvp4g

Remote Service

public interface StringReverserService extends RemoteService { public String reverseString(String stringToReverse);}

Page 129: Web-Development Using GWT + mvp4g

Remote Service

public interface StringReverserService extends RemoteService { public String reverseString(String stringToReverse);}

public interface StringReverserServiceAsync { void reverseString(String stringToReverse, AsyncCallback async);}

Page 130: Web-Development Using GWT + mvp4g

Remote Service

public interface StringReverserService extends RemoteService { public String reverseString(String stringToReverse);}

public interface StringReverserServiceAsync { void reverseString(String stringToReverse, AsyncCallback async);}

public class StringReverserServiceImpl extends RemoteServiceServlet implements StringReverserService { . . . }

Page 131: Web-Development Using GWT + mvp4g

Remote Service

public interface StringReverserService extends RemoteService { public String reverseString(String stringToReverse);}

public interface StringReverserServiceAsync { void reverseString(String stringToReverse, AsyncCallback async);}

public class StringReverserServiceImpl extends RemoteServiceServlet implements StringReverserService { . . . }

StringReverserServiceAsync reverserService = (StringReverserServiceAsync) GWT.create(StringReverserService.class);

Page 132: Web-Development Using GWT + mvp4g

developerlife.com/tutorials/?p=125

Tutorial on creating Remote Services

Page 133: Web-Development Using GWT + mvp4g

Remote Services is server-side APIbuilt using Java interfaces

Page 134: Web-Development Using GWT + mvp4g
Page 135: Web-Development Using GWT + mvp4g

JUnit

Page 136: Web-Development Using GWT + mvp4g

JUnitpublic class StockWatcherTest extends GWTTestCase {

public String getModuleName() { return "com.google.gwt.sample.stockwatcher.StockWatcher"; } . . .

}

Page 137: Web-Development Using GWT + mvp4g

JUnitpublic class StockWatcherTest extends GWTTestCase {

. . .

FooPresenter.IFooView fooView = Mockito.mock(FooPresenter.IFooView.class); ... = new FooPresenter(..., fooView); Mockito.verify(fooView).someViewMethod(...);}

Page 138: Web-Development Using GWT + mvp4g

GWT-code is easy to testbecause of JUnit support

Page 139: Web-Development Using GWT + mvp4g
Page 140: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScript

Page 141: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

Page 142: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibility

Page 143: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portals

Page 144: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concern

Page 145: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

Page 146: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

No guidance at non-Java Server-Side (Python & GAE, for example)

Page 147: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

Page 148: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole application

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

Page 149: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

Page 150: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

JavaScript-errors provide little information

Page 151: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

JavaScript-errors provide little informationAlthough, they are for sure much easier to understand when debug info is on

Page 152: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

Development Mode works slower than real code: so you may encounter problems in events succession

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

JavaScript-errors provide little informationAlthough, they are for sure much easier to understand when debug info is on

Page 153: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

Development Mode works slower than real code: so you may encounter problems in events successionНey, you say you've never debugged code using alerts?!

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

JavaScript-errors provide little informationAlthough, they are for sure much easier to understand when debug info is on

Page 154: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

Development Mode works slower than real code: so you may encounter problems in events successionНey, you say you've never debugged code using alerts?!

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

JavaScript-errors provide little informationAlthough, they are for sure much easier to understand when debug info is on

Regu

lar

expr

essi

ons

a re

just

a w

rapp

e r f

or Ja

vaSc

r ipt

RegExp

Page 155: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScript

One JS-error crashes the whole application

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibility

Development Mode works slower than real code: so you may encounter problems in events succession

No guidance at non-Java Server-Side (Python & GAE, for example)

JavaScript-errors provide little information

Regu

lar

expr

essi

ons

a re

just

a w

rapp

e r f

or Ja

vaSc

r ipt

RegExp

Page 156: Web-Development Using GWT + mvp4g

Deficiencies and observations

Anyway, you need good skills in JavaScriptEspecially when using external JS-libraries

One JS-error crashes the whole applicationHowever, we have GWT.setUncaughtExceptionHandler

«Manual» makeup (HTMLPanel) becomes not sustainable and has no cross-browser compatibilityGWT is for web-applications, but not pretentious portalsYou can write your own (or extend existing) components, but then thinking about cross-browser compatibility is your concernAnd you'll need to make a detailed lecture about GWT components system for your makeup men, by the way

Development Mode works slower than real code: so you may encounter problems in events successionНey, you say you've never debugged code using alerts?!

No guidance at non-Java Server-Side (Python & GAE, for example)Well, let's buid it on top of RequestBuilder

JavaScript-errors provide little informationAlthough, they are for sure much easier to understand when debug info is on

Regu

lar

expr

essi

ons

a re

just

a w

rapp

e r f

or Ja

vaSc

r ipt

RegExp

Page 157: Web-Development Using GWT + mvp4g

www.linux.org.ru/forum/talks/4497412

Here GWT drawbacks are discussed

Page 158: Web-Development Using GWT + mvp4g

Every reasoned weakness in GWT have a rational solution.

Page 159: Web-Development Using GWT + mvp4g

galak-sandbox.blogspot.com/2010/10/gwt.html

Summary on GWT-code optimization

Page 160: Web-Development Using GWT + mvp4g

And I would ask for a beer now!

Page 161: Web-Development Using GWT + mvp4g
Page 162: Web-Development Using GWT + mvp4g

3. mvp4g

Page 163: Web-Development Using GWT + mvp4g
Page 164: Web-Development Using GWT + mvp4g

code.google.com/p/mvp4g/

mvp4g framework web-page

Page 165: Web-Development Using GWT + mvp4g

● What helps?● Annotation system● RMVP realization● EventBus realization● URL, HistoryConverters, #!● Multimodularity● PlaceService● Remarks

Page 166: Web-Development Using GWT + mvp4g

mvp4g framework helps to

Page 167: Web-Development Using GWT + mvp4g

work with (R)MVP

mvp4g framework helps to

Page 168: Web-Development Using GWT + mvp4g

work with (R)MVP

organize multi-modular applications

mvp4g framework helps to

Page 169: Web-Development Using GWT + mvp4g

work with (R)MVP

organize multi-modular applications

design and develop events buses

mvp4g framework helps to

Page 170: Web-Development Using GWT + mvp4g

work with (R)MVP

organize multi-modular applications

design and develop events buses

work with history (incl. hashbangs #!)

mvp4g framework helps to

Page 171: Web-Development Using GWT + mvp4g

work with (R)MVP

organize multi-modular applications

design and develop events buses

work with history (incl. hashbangs #!)

... also constantly being improved

mvp4g framework helps to

Page 172: Web-Development Using GWT + mvp4g

work with (R)MVP

organize multi-modular applications

design and develop events buses

work with history (incl. hashbangs #!)

... also constantly being improved

mvp4g framework helps to

Page 173: Web-Development Using GWT + mvp4g

mvp4gshowcase.appspot.com

mvp4g framework showcase

Page 174: Web-Development Using GWT + mvp4g

mvp4gshowcase.appspot.com

mvp4g framework showcase

Page 175: Web-Development Using GWT + mvp4g

code.google.com/p/mvp4g/wiki/Mvp4g_vs_GWTP

Comparison of code written with mvp4g or native GWT

Page 176: Web-Development Using GWT + mvp4g

code.google.com/p/mvp4g/wiki/Mvp4g_vs_GWTP

Comparison of code written with mvp4g or native GWT

Page 178: Web-Development Using GWT + mvp4g

Pierre-Laurent [email protected](meet him at Google I/O '11)

Page 179: Web-Development Using GWT + mvp4g

The code you write using mvp4gframework is much simpler thanGWT-code without its usage.

It is achieved by Pierre correct use of annotations.

Code is written by human. It is better to help him sometimes.

Code is written by human. It is better to help him sometimes.

Page 180: Web-Development Using GWT + mvp4g
Page 181: Web-Development Using GWT + mvp4g

Annotations

Page 182: Web-Development Using GWT + mvp4g

Annotations

@Debug@Event@EventHandler@Events@Filters@Forward@History@InitHistory@InjectService@NotFoundHistory@PlaceService@Presenter@Service@Start

Page 183: Web-Development Using GWT + mvp4g

Annotations

There is Annotation Processor Factory(annotation validator that applies

just when you edit the source code)

Page 184: Web-Development Using GWT + mvp4g

Annotations — the power of mvp4g!Annotations — the power of mvp4g!

Page 185: Web-Development Using GWT + mvp4g
Page 186: Web-Development Using GWT + mvp4g

RMVP

Page 187: Web-Development Using GWT + mvp4g

RMVPannotations

@Debug@Event@EventHandler@Events@Filters@Forward@History@InitHistory@InjectService@NotFoundHistory@PlaceService@Presenter@Service@Start

Page 188: Web-Development Using GWT + mvp4g

RMVPpresenter

@Presenter(view=OneView.class)public class OnePresenter extends BasePresenter<IOneView, OneEventBus> { @Inject private ServiceAsync service; }

Page 189: Web-Development Using GWT + mvp4g

RMVPview

@Presenter(view=OneView.class)public class OnePresenter extends BasePresenter<IOneView, OneEventBus> { @Inject private ServiceAsync service; }

class OneView extends Composite implements IOneView { . . .}

Page 190: Web-Development Using GWT + mvp4g

RMVPreverse

@Presenter(view=OneView.class)public class OnePresenter extends BasePresenter<IOneView, OneEventBus> { @Inject private ServiceAsync service; }

class OneView extends Composite implements IOneView, ReverseViewInterface<OnePresenter> { . . .}

Page 191: Web-Development Using GWT + mvp4g
Page 192: Web-Development Using GWT + mvp4g

EventBus

Page 193: Web-Development Using GWT + mvp4g

EventBusannotations

@Debug@Event@EventHandler@Events@Filters@Forward@History@InitHistory@InjectService@NotFoundHistory@PlaceService@Presenter@Service@Start

Page 194: Web-Development Using GWT + mvp4g

EventBusevents

@Events(startView = StartView.class)public interface OneEventBus extends EventBus {

@Event public void fooEvent(...);

@Event public void barEvent(...);

}

Page 195: Web-Development Using GWT + mvp4g

EventBushandlers

@Events(startView = StartView.class)public interface OneEventBus extends EventBus {

@Event(handlers={FooPresenter.class, AcmePresenter.class}) public void fooEvent(...);

@Event(handlers=BarPresenter.class) public void barEvent(...);

}

FooPresenter::onFooEvent(...) {...}FooPresenter::onFooEvent(...) {...}BarPresenter::onBarEvent(...) {...}

Page 196: Web-Development Using GWT + mvp4g

EventBusactivation

@Events(startView = StartView.class)public interface OneEventBus extends EventBus {

@Event(handlers={FooPresenter.class, AcmePresenter.class}, activate={FooPresenter.class, AcmePresener.class}, deactivate={BarPresenter.class}) public void fooEvent(...);

@Event(handlers=BarPresenter.class, activate={BarPresenter.class}, deactivate={FooPresenter.class, AcmePresener.class}) public void barEvent(...);

}

Page 197: Web-Development Using GWT + mvp4g

EventBusbroadcast

@Events(startView = StartView.class)public interface OneEventBus extends EventBus {

@Event(broadcastTo=IBroadcast.class, calledMethod="boo") public void broadcastEvent(...);

}

public class Foo implements IBroadcast { public void boo(...) {...};}

Page 198: Web-Development Using GWT + mvp4g

EventBusfilters and stuff

@Filters(filterClasses={FilterOne.class, FilterTwo.class})@Debug(logger=CustomLogger.class)@Events(startView = StartView.class)public interface OneEventBus extends EventBus {

. . .

}

class FilterOne implements EventFilter<OneEventBus> {

@Override public boolean filterEvent(...) { return ...; }

}

Page 199: Web-Development Using GWT + mvp4g
Page 200: Web-Development Using GWT + mvp4g

History

Page 201: Web-Development Using GWT + mvp4g

Historyannotations

@Debug@Event@EventHandler@Events@Filters@Forward@History@InitHistory@InjectService@NotFoundHistory@PlaceService@Presenter@Service@Start

Page 202: Web-Development Using GWT + mvp4g

Historyhandling

@Events(..., historyOnStart = true)public interface OneEventBus extends EventBus {

@Start @InitHistory public void start();

@Event(handlers=..., navigationEvent=true, historyName="foo", historyConverter=OneHC.class) public void fooEvent(...);

@NotFoundHistory public void show404();

}

Page 203: Web-Development Using GWT + mvp4g

@Events(..., historyOnStart = true)public interface OneEventBus extends EventBus {

@Start @InitHistory public void start();

@Event(handlers=..., navigationEvent=true, historyName="foo", historyConverter=OneHC.class) public void fooEvent(...);

@NotFoundHistory public void show404();

}

/start

/foo

Historypassing

Page 204: Web-Development Using GWT + mvp4g

@Events(...)public interface OneEventBus ... {

@Event(..., navigationEvent=true, historyName="foo", historyConverter=OneHC.class) public void fooEvent(int id, Filter filter);

}

@History public class OneHC implements HistoryConverter<OneEventBus> {

@Inject private TokenGenerator tokens;

public void convertFromToken(...) { if ("foo".equals(event))

eventBus.fooEvent( Integer.parseInt(params[0]), Filter.parse(params[1])); } public String fooEvent(...) { return tokens.fooEvent(id, filter); }

}

/foo?26;all

Historyparameters

Page 205: Web-Development Using GWT + mvp4g

Historyhashbang

@Events(...)public interface OneEventBus ... {

@Event(...) public void fooEvent(int id, Filter filter);

}

@History public class OneHC implements HistoryConverter<OneEventBus> {

...

public boolean isCrawable() { return true; }

}

/#!foo?26;all

Page 206: Web-Development Using GWT + mvp4g

History and event buses are the skeletonof your site navigation system

History and event buses are the skeletonof your site navigation system

Page 207: Web-Development Using GWT + mvp4g
Page 208: Web-Development Using GWT + mvp4g

Multi-modularity

Page 209: Web-Development Using GWT + mvp4g

Multi-modularityannotations

@AfterLoadChildModule@BeforeLoadChildModule@ChildModule@ChildModules@DisplayChildModuleView@HistoryName@LoadChildModuleErrors

Page 210: Web-Development Using GWT + mvp4g

Multi-modularityURLs

company/listcompany/addcompany/edit?123user/listuser/adduser/edit?39

object/action[?parameters]

REST

Page 211: Web-Development Using GWT + mvp4g

Multi-modularitymodules

public interface CompanyModule extends Mvp4gModule {}

@Events(..., module=CompanyModule.class)public interface CompanyEventBus extends EventBus {...}

public interface UserModule extends Mvp4gModule {}

@Events(..., module=UserModule.class)public interface UserEventBus extends EventBus {...}

Page 212: Web-Development Using GWT + mvp4g

@Events(..., module=UserModule.class)public interface UserEventBus extends EventBus {

@Event(..., handlers=UserListPresenter.class, historyName="list") public void usersList(); . . .}

@Events(...)@ChildModules( @ChildModule(moduleClass=UserModule.class) @ChildModule(moduleClass=CompanyModule.class))public interface ParentEventBus extends EventBus{

@Event(modulesToLoad=UserModule.class) public void usersList();

@Event(modulesToLoad=CompanyModule.class) public void companiesList();

}Multi-modularityevent buses

Page 213: Web-Development Using GWT + mvp4g

@Events(...)@ChildModules( @ChildModule(moduleClass= UserModule.class, runAsync=true) @ChildModule(moduleClass= CompanyModule.class, runAsync=true))public interface ParentEventBus extends EventBus {

. . .

}

Multi-modularityasynchronousloading

Page 214: Web-Development Using GWT + mvp4g

History, event buses and modules are the skeletonof your site navigation system

History, event buses and modules are the skeletonof your site navigation system

You can load modules asynchronously!So user will not get the kilobyteshe needs not, if he will not visitspecified sections of your site.

You can load modules asynchronously!So user will not get the kilobyteshe needs not, if he will not visitspecified sections of your site.

Page 215: Web-Development Using GWT + mvp4g
Page 216: Web-Development Using GWT + mvp4g

PlaceService

Page 217: Web-Development Using GWT + mvp4g

PlaceServiceannotations

@Debug@Event@EventHandler@Events@Filters@Forward@History@InitHistory@InjectService@NotFoundHistory@PlaceService@Presenter@Service@Start

Page 218: Web-Development Using GWT + mvp4g

PlaceServiceoverriding

@PlaceService(CustomPlaceService.class)@Events(...)public interface MainEventBus extends EventBusWithLookup { . . .}

public class CustomPlaceService extends PlaceService { protected void convertToken(String token) { ... } protected String[] parseToken(String token) { ... } public String tokenize(String eventName, String param) { ... } . . .}

Page 219: Web-Development Using GWT + mvp4g
Page 220: Web-Development Using GWT + mvp4g

Remarks

Page 221: Web-Development Using GWT + mvp4g

Remarks

There is no layouting-system yet

Page 222: Web-Development Using GWT + mvp4g

Remarks

There is no layouting-system yet

Multimodularity is aimedat object → action principle

Page 223: Web-Development Using GWT + mvp4g

Remarks

There is no layouting-system yet

Multimodularity is aimedat object → action principle

GIN/Guice are supported

Page 224: Web-Development Using GWT + mvp4g

Remarks

There is no layouting-system yet

Multimodularity is aimedat object → action principle

When using custom GwtEvents, you should keep an eye on presenters activation. Callbacks — easier.

GIN/Guice are supported

Page 225: Web-Development Using GWT + mvp4g

Remarks

There is no layouting-system yet

Multimodularity is aimedat object → action principle

When using custom GwtEvents, you should keep an eye on presenters activation. Callbacks — easier.

There are LazyView & LazyPresenter

GIN/Guice are supported

Page 226: Web-Development Using GWT + mvp4g

mvp4g — is what Zoidberg has prescribed!

Page 227: Web-Development Using GWT + mvp4g
Page 228: Web-Development Using GWT + mvp4g

4. UI components

Page 229: Web-Development Using GWT + mvp4g

ButtonPushButtonRadioButtonCheckBoxDatePickerToggleButtonTextBoxPasswordTextBoxTextAreaHyperlink / AnchorListBoxCellListMenuBarTree, CellTreeSuggestBoxRichTextAreaFlexTable, Grid, CellTableCellBrowserTabBarDialogBox

PopupPanelStackPanel, StackLayoutPanelHorizontalPanelVerticalPanelFlowPanelVerticalSplitPanelHorizontalSplitPanelSplitLayoutPanelDockPanel, DockLayoutPanelTabPanel, TabLayoutPanelDisclosurePanel

Page 230: Web-Development Using GWT + mvp4g
Page 231: Web-Development Using GWT + mvp4g
Page 232: Web-Development Using GWT + mvp4g

code.google.com/webtoolkit/doc/latest/RefWidgetGallery.html

GWT components library

Page 233: Web-Development Using GWT + mvp4g

UiBinder: .ui.xml<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"

xmlns:g="urn:import:com.google.gwt.user.client.ui"><g:VerticalPanel styleName="my-css-style">

<g:HorizontalPanel><g:Label>Name</g:Label><g:TextBox ui:field="nameBox">Babylen</g:TextBox>

</g:HorizontalPanel>

<g:HorizontalPanel><g:Label>Family name</g:Label><g:TextBox ui:field="fnameBox">Tatarsky</g:TextBox>

</g:HorizontalPanel>

<g:ListBox ui:field="namesLst" visibleItemCount="1" />

<g:Button ui:field="submit">Submit</g:Button></g:VerticalPanel>

</ui:UiBinder>

Page 234: Web-Development Using GWT + mvp4g

UiBinder: .javapublic class SettingsForm extends Composite { interface SFormBinder extends UiBinder<Widget, SettingsForm> {} private static FormBinder uiBinder = GWT.create(SFormBinder.class);

@UiField TextBox nameBox; @UiField TextBox fnameBox; @UiField ListBox namesLst;

public HelloWorld(String... names) { initWidget(uiBinder.createAndBindUi(this)); for (String name : names) { namesLst.addItem(name); } }

@UiHandler("submit") public onSubmit(ClickEvent e) { ... }

}

Page 235: Web-Development Using GWT + mvp4g

HTMLPanel

<g:HTMLPanel><div>Some div</div>

<div> <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> </div> <p> <span>Some span</span> </p></g:HTMLPanel>

Page 236: Web-Development Using GWT + mvp4g

Manual make-up vs. Cross-browser support

.gwt-Button { font-size: 150%; }

.b-popup { position: absolute; }

Attention!

Page 237: Web-Development Using GWT + mvp4g

In GWT, there is an entire vast library of components

and an armory of layouts.

Though, the fact of developing a site withits own unique style is fraught with

cross-browser compatibility problems.

Page 238: Web-Development Using GWT + mvp4g
Page 239: Web-Development Using GWT + mvp4g

Custom components

Page 240: Web-Development Using GWT + mvp4g

Custom components

Do not inherit, but delegate

Page 241: Web-Development Using GWT + mvp4g

Custom components

Do not inherit, but delegate

@UiConstructorpublic MyCustomWidget(String defaultText) { . . .}

public void setMaxLength(int maxLength) { ... }

Page 242: Web-Development Using GWT + mvp4g

Custom components

Do not inherit, but delegate

@UiConstructorpublic MyCustomWidget(String defaultText) { initWidget(uiBinder.createAndBindUi(this));}

public void setMaxLength(int maxLength) { ... }

Page 243: Web-Development Using GWT + mvp4g

Customization vs. Cross-browser support

Attention!

Page 244: Web-Development Using GWT + mvp4g

So it is better either to keep your site design as simple as possible...

...either to allocatea significant amount of time

for UI designers and programmers to work through your own

component library.

...either to allocatea significant amount of time

for UI designers and programmers to work through your own

component library.

Page 245: Web-Development Using GWT + mvp4g
Page 246: Web-Development Using GWT + mvp4g

The lack of UI Designerwas a drawback

for someone

Page 247: Web-Development Using GWT + mvp4g

The lack of UI Designerwas a drawback

for someone

Page 248: Web-Development Using GWT + mvp4g
Page 249: Web-Development Using GWT + mvp4g

5. Layouting

Page 250: Web-Development Using GWT + mvp4g

Reasons?

Page 251: Web-Development Using GWT + mvp4g

Reasons?If your site is built with logical blockswhich are visually placed in different order,depending on context.

Page 252: Web-Development Using GWT + mvp4g

Reasons?If your site is built with logical blockswhich are visually placed in different order,depending on context.

For example, portlets or custom widgets

Page 253: Web-Development Using GWT + mvp4g

Reasons?If your site is built with logical blockswhich are visually placed in different order,depending on context.

For example, portlets or custom widgets

Means, when it is a flexible site.

Page 254: Web-Development Using GWT + mvp4g

Reasons?If your site is built with logical blockswhich are visually placed in different order,depending on context.

For example, portlets or custom widgets

Means, when it is a flexible site.

These mechanics are not yet implemented in mvp4g

Page 255: Web-Development Using GWT + mvp4g
Page 256: Web-Development Using GWT + mvp4g

Layouts

LIST ITEM EDIT

B

B

B

CA

A

C

A

C

D

Page 257: Web-Development Using GWT + mvp4g

public class LayoutList implements Layout { }

LayoutList.ui.xml:<FlowPanel ui:field="a"/><FlowPanel ui:field="b"/><FlowPanel ui:field="c"/>

Layouts

LIST ITEM EDIT

public enum Place { A, B, C, D};

public interface Layout { public LayoutId id(); public HasWidgets place(Place place); Map<Place, HasWidgets> places();}

public class LayoutItem implements Layout { }

LayoutItem.ui.xml:<FlowPanel ui:field="a"/><FlowPanel ui:field="b"/><FlowPanel ui:field="c"/>

public class LayoutEdit implements Layout { }

LayoutEdit.ui.xml:<FlowPanel ui:field="a"/><FlowPanel ui:field="b"/><FlowPanel ui:field="c"/><FlowPanel ui:field="d"/>

Page 258: Web-Development Using GWT + mvp4g

Layouts

LIST ITEM EDIT

B

B

B

CA

A

C

A

C

D

Page 259: Web-Development Using GWT + mvp4g

Base page

BasePage.ui.xml:<FlowPanel ui:field="toolbar"/><FlowPanel ui:field="layout"/><FlowPanel ui:field="footer"/><FlowPanel ui:field="copy"/>

toolbar

layout

footercopy

Page 260: Web-Development Using GWT + mvp4g
Page 261: Web-Development Using GWT + mvp4g

public enum Portal implements MakesLink {

NEWS_LIST(LayoutId.LIST, <event-spec>, <options>), NEWS_EDIT(LayoutId.EDIT, <event-spec>, <options>), NEWS_VIEW(LayoutId.ITEM, <event-spec>, <options>), NEWS_DELETE(LayoutId.ITEM, <event-spec>, <options>) USER_LIST(LayoutId.LIST, <event-spec>, <options>), USER_EDIT(LayoutId.EDIT, <event-spec>, <options>), USER_VIEW(LayoutId.ITEM, <event-spec>, <options>), USER_DELETE(LayoutId.ITEM, <event-spec>, <options>), . . . @Override public String makeLink() { . . . }

}

Page / Portal

Page 262: Web-Development Using GWT + mvp4g

public enum Portal implements MakesLink {

. . .

public class PortalUrl implements MakesLink {

PortalUrl(Portal portal[, <params>]) { ... }

public PortalUrl addParam(...) { ... } public PortalUrl fromEvent(String module, String event, String params) { ... } @Override public String makeLink() { ... }

}

}

Link

Page 263: Web-Development Using GWT + mvp4g

public enum Portal implements MakesLink {

. . .

public class PortalUrl implements MakesLink {

PortalUrl(Portal portal[, <params>]) { ... }

public PortalUrl addParam(...) { ... } public PortalUrl fromEvent(String module, String event, String params) { ... } @Override public String makeLink() { ... }

}

}

Link

History.newItem(Portal.USER_LIST.makeLink());History.newItem(new PortalUrl(Portal.USER_EDIT, uid).makeLink());History.newItem(userTokenGenerator.edit(uid));

Page 264: Web-Development Using GWT + mvp4g

public abstract class LayoutBuilder<E extends ChildEventBus> {

public CanBuildLayout prepareFor(final Portal page) { return new CanBuildLayout { public Layout build(State state) { layout(page, state, LayoutFactory.get(page.layout).places()); } } } public abstract void layout(Portal page, State state, Map<Place, HasWidgets> places);

}

Layout builder

Page 265: Web-Development Using GWT + mvp4g

public class UserHistoryConverter implements HistoryConverter<UserEventBus> { public void convertFromToken(String evt, String param) { // можно использовать tokenGenerator PortalUrl curUrl = PortalUrl.fromToken("user",evt,param); Portal portal = curUrl.portal; eventBus.newPage(portal, layoutBuilder.prepareFor(portal)); eventBus.dispatch(curUrl);

}

}

Switching layouts

Page 266: Web-Development Using GWT + mvp4g

public class UserLayoutBuilder implements LayoutBuilder<UserEventBus> { public void layout(Portal page, State state, Map<Place, HasWidgets> places) switch (page) { case USER_ITEM: { eventBus.projectItem(places.get(Place.A)); eventBus.projectCalendar(places.get(Place.B)); eventBus.projectPreview(places.get(Place.C)); } break; case USER_LIST: switch (state) { ... } break; case USER_EDIT: ... break; }

}

}

Builder implementation

Page 267: Web-Development Using GWT + mvp4g

public interface ChildEventBus { @Event(forwardToParent=true) public void newPage(Portal page, CanBuildLayout builder);

@Event(forwardToParent=true) public void project(Widget what, HasWidgets where);

@Event(forwardToParent=true) public void updateState(State state) }

Event buses

[ forwarded to BaseEventBus ]

Page 268: Web-Development Using GWT + mvp4g

public interface UserEventBus extends ChildEventBus { // navigation @Event(navigationEvent=true, ...) public void list(); @Event(navigationEvent=true, handlers=UserShowPresenter.class, historyConverter=UserHistoryConverter.class) public void show(String uid); @Event(navigationEvent=true, ...) public void edit(String uid); . . .

// projection @Event(handlers=UserShowPresenter.class,calledMethod="prjItem") public void projectItem(HasWidgets where); @Event(handlers=UserShowPresenter.class,calledMethod="prjPrvw") public void projectPreview(HasWidgets where); @Event(handlers=CalendarPresenter.class,calledMethod="project") public void projectCalendar(HasWidgets where)

}

Event buses

Page 269: Web-Development Using GWT + mvp4g
Page 270: Web-Development Using GWT + mvp4g

Layouting helps us to build and to live!

Page 271: Web-Development Using GWT + mvp4g

github.com/shamansir/gwt-mvp4g-layouting-demo

I've wanted to make a demo for you, but had no time ;(

Page 272: Web-Development Using GWT + mvp4g

github.com/shamansir/gwt-mvp4g-layouting-demo

I've wanted to make a demo for you, but had no time ;(

Follow

Page 273: Web-Development Using GWT + mvp4g

github.com/shamansir/gwt-mvp4g-layouting-demo

I've wanted to make a demo for you, but had no time ;(

Page 274: Web-Development Using GWT + mvp4g

Фото gwt-mvp4g-layouting-demo.appspot.com

Page 275: Web-Development Using GWT + mvp4g

QRCode gwt-mvp4g-layouting-demo.appspot.com

Page 276: Web-Development Using GWT + mvp4g
Page 277: Web-Development Using GWT + mvp4g

6. Non-Java API

Page 278: Web-Development Using GWT + mvp4g

code.google.com/p/google-web-toolkit-doc-1-5/wiki/GettingStartedJSON

Accidentally, here is the main point

Page 279: Web-Development Using GWT + mvp4g

Possibility — exists

Page 280: Web-Development Using GWT + mvp4g

RequestBuilder

Page 281: Web-Development Using GWT + mvp4g

General context

Page 282: Web-Development Using GWT + mvp4g

Call chains

Page 283: Web-Development Using GWT + mvp4g

Insering JS-object into HTML-markup

(you can parse them using JSNI)

Page 284: Web-Development Using GWT + mvp4g

Advantage : Independence from serialization

Page 285: Web-Development Using GWT + mvp4g

Disadvantage : Unconventional approach with all the consequences

Page 286: Web-Development Using GWT + mvp4g

shamansir-ru.tumblr.com/post/1728720550/deferred-api-gwt-rpc

And here is the source code

Page 287: Web-Development Using GWT + mvp4g
Page 288: Web-Development Using GWT + mvp4g

7. i18n

Page 289: Web-Development Using GWT + mvp4g

Messages / Constants

public interface LoginMessages extends Messages { public String enterName(); public String emailExists(String email); public String emailInvalid(String email); public String loginFailed(String username); public String youFailedNTimes(@PluralCount int times);}

public interface MenuConstants extends Constants { public String login(); public String logout(); public String contacts(); public String settings();}

Page 290: Web-Development Using GWT + mvp4g

LoginMessages_ru.propertiesenterName = Введите имяemailExists = E-mail {0} зарегистрирован в системеemailInvalid = Некорректный e-mail {0}loginFailed = Не удалось зайти пользователем {0}youFailedNTimes = Кол-во неудачных попыток: {0,number}youFailedNTimes[one] = {0,number} неудачная попыткаyouFailedNTimes[few] = {0,number} неудачных попыток

MenuConstants_ru.propertieslogin= Войтиlogout = Выйтиcontacts = Контактыsettings = Настройки

Messages / Constants

Page 291: Web-Development Using GWT + mvp4g

<e:MyTextBox ui:field="box" defaultText="{messages.enterText}" />

LoginMessages messages = GWT.create(LoginMessages.class);MenuConstants constants = GWT.create(MenuConstants.class);

<ui:with type="....LoginMessages" field="messages" />

Messages / Constants

Page 292: Web-Development Using GWT + mvp4g

Messages / Constants

<txt:msg key="messageKey">Message</txt:msg>

<ui:UiBinder ... xmlns:txt="ui:with:...MyMessages" />

Page 293: Web-Development Using GWT + mvp4g

ErrorsConstants_ru.propertiesERR_101 = Ошибка авторизацииERR_102 = Неизвестная ошибкаERR_103 = Ресурс не найден

errors = ERR_101, ERR_102, ERR_103

public interface ErrorsConstants extends ConstantsWithLookup { Map<String, String> errors(); }

Messages / Constants

Page 294: Web-Development Using GWT + mvp4g

Mae'n hawdd iawn i gyfieithu prosiectau GWT...

Mae'n hawdd iawn i gyfieithu prosiectau GWT...

...if you'll teach yourtranslators to manage.properties-files or givethem PoEdit or Pootle

...if you'll teach yourtranslators to manage.properties-files or givethem PoEdit or Pootle

Page 295: Web-Development Using GWT + mvp4g

ResourceBundles

Позволяют использовать локализованные ресурсы

Page 296: Web-Development Using GWT + mvp4g
Page 297: Web-Development Using GWT + mvp4g

8. Conclusion

Page 298: Web-Development Using GWT + mvp4g

experika.com

We applied those techniques for Experika

Page 299: Web-Development Using GWT + mvp4g

experika.com

Welcome to Experika

Page 300: Web-Development Using GWT + mvp4g

Thanks toVitaly Gashock, for intoducing mvp4g to me and partnership

Mikhail Kashkin, for mentoring

http://www.vurt.ru

http://twitter.com/vgashock

Alexey Kakunin, for 道 and 先生

http://www.emdev.ru

Page 301: Web-Development Using GWT + mvp4g

profiles.google.com/shaman.sir

Anthony Kotenko

Page 302: Web-Development Using GWT + mvp4g

Thank you.

Made with LibreOffice 3.3.1 Impress

Page 303: Web-Development Using GWT + mvp4g

More questions?

Page 304: Web-Development Using GWT + mvp4g

GWT FTW!

Page 305: Web-Development Using GWT + mvp4g

Philip J. Fry, Dr. Zoidber, Nibbler and Hypnotoad are all the Futurama series characters

and all created by Matt Groening

Homer Simpson is the characterof The Simpsons series

and also created by Matt Groening

All the phrases they tellin this presentation have no relation

nor for these characters, nor for series noticed above,

nor for their creator