SlideShare ist ein Scribd-Unternehmen logo
1 von 43
Downloaden Sie, um offline zu lesen
Architecting your GWT
       application with GWT-
              Platform


Juan Manuel Rojas R.
http://rhemsolutions.com/   Lima, Perú 26/10/2012
Architecting your GWT application
Google found that a Model-view-presenter
(MVP) architecture works best when
developing GWT apps
https://developers.google.com/web-toolkit/articles/mvp-
architecture


Model View Presenter Frameworks
Mvp4g
gwt-dispatch
gwt-platform
GWT-Platform
It's an open source MVP framework, that
supports many nice features of GWT, including
code splitting and history management, with a
simple annotation-based API.
A highly productive app stack

 UI (MVP)
                   gwt-platform (GWTP)


       RPC
                   GWT RequestFactory



 PostgreSQL
                   JPA 2.0 - PostgreSQL

http://www.youtube.com/watch?
feature=player_detailpage&v=imiquTOLl64#t=200s
Google Plugin for Eclipse
Update sites

Eclipse 4.2 (Juno)
http://dl.google.com/eclipse/plugin/4.2
GWTP Eclipse Plugin
To install the GWTP Eclipse Plugin, from
Eclipse go to Help > Install New Software

Click on Add...
Name: GWTP
Location: http://plugin.gwt-platform.googlecode.com/hg/update
Clean example code
1. Delete theme lines from Module.gwt.xml
2. Delete files from
                                     Entry point
   client package
    GreetingService                  package com.example.client;
    GreetingServiceAsync
   server package,                   import com.google.gwt.core.client.EntryPoint;
                                     import com.google.gwt.user.client.Window;
    GreetingServiceImpl
   shared packaged                   public class FirstProject implements EntryPoint {
    FieldVerifier
   src/test/java                       public void onModuleLoad() {
    GwtTestFirstProject                  Window.alert("empty project");
                                       }
   src/test/resources
                                     }
    FirstProjectJUnit.gwt.xml
3. Clean Css file and html table code src/main/webapp
4. Delete servlet definition from web.xml src/main/webapp/WEB-INF
Dependency injection (DI)
Separate behavior from dependency resolution.

Injects the dependent element (object or value
etc) to the destination automatically.

Reduction of boilerplate code in the application
objects since all work to initialize or set up
dependencies is handled by a provider
component.
http://en.wikipedia.org/wiki/Dependency_injection
Dependency injection for GWT
google-gin
GIN is built on top of Guice and uses (a subset
of) Guice's binding language.

  <!-- google-gin -->
   <dependency>
  <groupId>com.google.gwt.inject</groupId>
  <artifactId>gin</artifactId>
  <version>2.0.0</version>
  <exclusions>
   <exclusion>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-servlet</artifactId>
   </exclusion>
  </exclusions>
   </dependency>
Dependency injection for Java 5
google-guice
Think of Guice's @Inject as the new new.
Guice embraces Java's type safe nature using
generics and annotations.
 <!-- google guice -->
 <dependency>
  <groupId>com.google.inject</groupId>
  <artifactId>guice</artifactId>
  <version>3.0</version>
 </dependency>
Dependency injection GIN

    Constructor injection                                 Field injection

public class ClientPlaceManager {                         public class ColaboradorPresenter {

     @Inject                                                   @Inject Messages messages;
     public ClientPlaceManager(final EventBus eventBus,
                final TokenFormatter tokenFormatter) {         public ColaboradorPresenter() {
      //eventBus and tokenFormatter are not null               //messages is null
                                                               }
     }
}                                                              protected void onBind() {
                                                               //messages is not null
                                                               }
                                                          }
Dependency injection GIN (Continuation)
 @Provides Methods
 When you need create and initialize an object.
 public class ClientModule extends AbstractPresenterModule {

    @Provides
    @Singleton
    public AppRequestFactory createRequestFactory(EventBus eventBus, MyDefaultRequestTransport
 requestTransport) {

      AppRequestFactory factory = GWT.create(AppRequestFactory.class);
      factory.initialize(eventBus, requestTransport);
      return factory;
     }
 }

                           public class ColaboradorPresenter {

                            private final AppRequestFactory factory;
How to inject               @Inject
                            public ColaboradorPresenter(Provider<AppRequestFactory> provider){
                             factory = provider.get();
                            }
                           }
Setting GWTP and GXT3
                                             <properties>
Add to your Module.gwt.xml                     ...
                                               <gwtp.version>0.7</gwtp.version>
                                               ...
<inherits name='com.sencha.gxt.ui.GXT'/>     </properties>
<inherits name='com.gwtplatform.mvp.Mvp'/>
                                             <!-- MVP component -->
                                             <dependency>

Add to your POM.xml                           <groupId>com.gwtplatform</groupId>
                                              <artifactId>gwtp-mvp-client</artifactId>
                                              <version>${gwtp.version}</version>
                                              <scope>provided</scope>
    <!-- sencha gxt3 -->                     </dependency>
    <dependency>
                                             <!-- Annotation component -->
    <groupId>com.sencha.gxt</groupId>
                                             <dependency>
      <artifactId>gxt</artifactId>            <groupId>com.gwtplatform</groupId>
      <version>3.0.1</version>                <artifactId>gwtp-processors</artifactId>
    </dependency>                             <version>${gwtp.version}</version>
                                              <scope>provided</scope>
                                             </dependency>
Setting GWTP                                                 Create the directories
                                                                  com.example.client
import   static   java.lang.annotation.ElementType.FIELD;
import   static   java.lang.annotation.ElementType.PARAMETER;                |--presenter
import   static   java.lang.annotation.ElementType.METHOD;
import   static   java.lang.annotation.RetentionPolicy.RUNTIME;
                                                                             |--view
                                                                             |--place
@BindingAnnotation
@Target({ FIELD, PARAMETER, METHOD })                                                   public class NameTokens {
@Retention(RUNTIME)
public @interface DefaultPlace {                                                        }
}

                                import com.google.web.bindery.event.shared.EventBus;

                                public class ClientPlaceManager extends PlaceManagerImpl {

                                      private final PlaceRequest defaultPlaceRequest;

                                      @Inject
                                      public ClientPlaceManager(final EventBus eventBus,
                                                 final TokenFormatter tokenFormatter,
                                                 @DefaultPlace final String defaultPlaceNameToken) {
                                           super(eventBus, tokenFormatter);
                                           this.defaultPlaceRequest = new PlaceRequest(defaultPlaceNameToken);
                                      }

                                      public void revealDefaultPlace() {
                                           revealPlace(defaultPlaceRequest, false);
                                      }
Setting GIN for GWTP
Inheriting the GIN module
<inherits name="com.google.gwt.inject.Inject"/>


Create a gin package in the client side
public class ClientModule extends AbstractPresenterModule {
                                                                      Define objects
     @Override                                                        available for
     protected void configure() {                                     injection
      install(new DefaultModule(ClientPlaceManager.class));
     }
}


import com.google.web.bindery.event.shared.EventBus;                 Getters methods
@GinModules(ClientModule.class)
public interface ClientGinjector extends Ginjector {
                                                                     for get objects
 EventBus getEventBus();
 PlaceManager getPlaceManager();
}
If GIN can't find a binding for a class, it falls back to calling GWT.create() on that
class.
Setting GIN for GWTP(Continuation)
Configure your EntryPoint
public class FirstProject implements EntryPoint {

 private final ClientGinjector ginjector = GWT.create(ClientGinjector.class);

 public void onModuleLoad() {

     // This is required for Gwt-Platform proxy's generator
     DelayedBindRegistry.bind(ginjector);

     ginjector.getPlaceManager().revealCurrentPlace();
 }
}

 Add the next properties to your Module.gwt.xml
 <module>
  ...
  <define-configuration-property name='gin.ginjector' is-multi-valued='false' />
  <set-configuration-property name='gin.ginjector' value='com.example.client.gin.ClientGinjector' />

 </module>
GWT-Platform and GXT3
Structure your views




A place represent a url of a program
GWT-Platform and GXT3(Continuation)

Tokens
Most presenters have a token so the user can navigate.




When there is not token the default presenter is shown.
You can navigate from one presenter to another by:
● Typing another url          PlaceRequest request = new PlaceRequest("inicio");

● Using a Hyperlink Widget    placeManager.revealPlace(request);

● Using a PlaceRequest
GWT-Platform and GXT3(Continuation)
Nested Presenters
Your header, footer and menu are in one
presenter the "parent presenter".
GWT-Platform and GXT3(Continuation)

Presenter Widget
Is for reusable graphical and logical code.
GWT-Platform and GXT3(Continuation)

Popup Presenters
Is a presenter widget
that is shown inside
a popup dialog.




 For create Popup Presenters with GXT Window you need
 the following classes
 GXTPopupViewImpl.java
 GXTPopupViewWithUiHandlers.java
GWT-Platform and GXT3(Continuation)
All presenters are composed of three files if you will use
UIBinder




All presenters have a inner interface that view implements.
GWT-Platform and GXT3(Continuation)




Presenter lifecycle
GWT-Platform and GXT3(Continuation)

Presenter lifecycle

1. Presenters are Singleton so it is instantiated once.
2. prepareFromRequest(): Is where you can get url
   parameters.
3. onBind(): Is called when the presenter is instantiated.
4. onReveal(): Is called whenever the Presenter was not
   visible on screen and becomes visible.
5. onHide(): Is called whenever the Presenter was visible
   on screen and is being hidden.
6. onReset(): Is called whenever the user navigates to a
   page that shows the presenter, whether it was visible or
   not.
Create Presenter
using GWTP Eclipse Plugin
First Presenter
LayoutPresenter
Options
 ● Use UiBinder
 ● RevealRootContentEvent
 ● Is Not a Place


Ordering
Move to view package
LayoutView.java
LayoutView.ui.xml
First Presenter LayoutPresenter
(Continuation)
Deprecated shared.EventBus

GWTP Eclipse Plugin use EventBus from event.shared
next this package was deprecated and change to web.
bindery.event.shared.

* Is important to do the next in every presenter you create
with GWTP Eclipse Plugin

Delete
import com.google.gwt.event.shared.EventBus
Replace by
import com.google.web.bindery.event.shared.EventBus;
First Presenter LayoutPresenter
(Continuation)
Add the next field to LayoutPresenter
 import com.google.gwt.event.shared.GwtEvent.Type;
 //for nested presenters
 @ContentSlot public static final Type<RevealContentHandler<?>> SLOT_content =
 new Type<RevealContentHandler<?>>();

Modify LayoutView.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'
    xmlns:gxt= "urn:import:com.sencha.gxt.widget.core.client"
    xmlns:container= "urn:import:com.sencha.gxt.widget.core.client.
container" >
    <container:Viewport>
      <!--for nested presenter -->
      <gxt:ContentPanel ui:field="contentPanel" borders="false"
headerVisible= "false" bodyBorder= "false" />
    </container:Viewport>
</ui:UiBinder>
First Presenter LayoutPresenter
     (Continuation)
     Setting Vertical Layout (LayoutView.ui.xml)
<ui:UiBinder>
 ...

<ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData"
field="minVerticalLayoutData" >
   <ui:attributes width="1" height="-1" />
 </ui:with>

 <ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData"
field="maxVerticalLayoutData" >
   <ui:attributes width="1" height="1" />
 </ui:with>

     <container:Viewport>
        ...
     </container:Viewport>
</ui:UiBinder>
First Presenter LayoutPresenter
     (Continuation)
     Using Vertical Layout (LayoutView.ui.xml)

<ui:UiBinder>
    ...
     <container:Viewport>
        <container:VerticalLayoutContainer>
          <container:child layoutData="{minVerticalLayoutData}">
          <g:HTMLPanel>
            <div>
              <div>First Project</div>
            </div>
          </g:HTMLPanel>
          </container:child>
          <container:child layoutData="{maxVerticalLayoutData}">
            <!--for nested presenter -->
            <gxt:ContentPanel ui:field="contentPanel" borders="false" headerVisible="false"
bodyBorder="false" />
          </container:child>
        </container:VerticalLayoutContainer>
     </container:Viewport>
</ui:UiBinder>
First Presenter LayoutPresenter
(Continuation)

Add the next field to LayoutView
@UiField ContentPanel contentPanel;//for nested presenter



Add the next method to LayoutView
 @Override
    public void setInSlot(Object slot, Widget content) {
          if(slot == LayoutPresenter.SLOT_content){
                contentPanel.clear();
                if(content != null){
                     contentPanel.add(content);
                     contentPanel.forceLayout();
                }
                return;
          }
          super.setInSlot(slot, content);
    }
Default Presenter
WelcomePresenter
Options
 ● Use UiBinder
 ● RevealContentEvent
 ● Content Slot
    (from parent presenter)
 ● Is a Place
 ● CodeSplit (recommended)
 ● Token: #welcome
 ● DefaultPlace
Default Presenter WelcomePresenter
(Continuation)

Modify WelcomeView.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'
    xmlns:gxt= "urn:import:com.sencha.gxt.widget.core.client"
    xmlns:container= "urn:import:com.sencha.gxt.widget.core.client.container"
>

    <gxt:ContentPanel headingText= "Welcome" >
      <container:CenterLayoutContainer>
        <g:HTMLPanel><h2> Welcome User </h2></g:HTMLPanel>
      </container:CenterLayoutContainer>
    </gxt:ContentPanel>

</ui:UiBinder>
reset.css
Download reset.css
put this css in your HTML header
<head>
...
<link type="text/css" rel="stylesheet" href="reset.css">
...
</head>

In your Module.css file
*{
 font-family: arial, helvetica, tahoma, sans-serif;
}
mvn gwt:run
Styling our application
GWT provides ClientBundle for styling in an
optimised way.
              client.resources
                     |- add.png
                     |- delete.png
                     |- cancel.png
                     |- edit.png
                     |- save.png
                     |- exit.png
                     |- bg.gif
Styling our application(Continuation)
public interface Resources extends ClientBundle {

     @Source("add.png")
     ImageResource add();

     @Source("delete.png")                          client.resources
     ImageResource delete();                               |- Resources.java

    @Source("cancel.png")
    ImageResource cancel();

     @Source("edit.png")
     ImageResource edit();

     @Source("save.png")
     ImageResource save();

     @Source("exit.png")
     ImageResource exit();
}
Styling our application(Continuation)
public interface CommonsCss extends CssResource   {

    @ClassName("layout-header")
    String layout_header();
                                     client.resources
                                            |- CommonsCss.java
    @ClassName("layout-title")
                                            |- Commons.css
    String layout_title();

    String logout();

    @ClassName("underline")
    String underline();

    @ClassName("button")
    String button();

    String exit();
}
Styling our application(Continuation)
Add to your ClientBundle

public interface Resources extends ClientBundle {

     ...

     @Source("bg.gif")
     ImageResource bg();

     @Source("Commons.css")
     CommonsCss commonsCss();

}
Styling our application(Continuation)
Modify LayoutView.ui.xml
<ui:UiBinder>

    <ui:with type="com.example.client.resources.Resources" field="resources" />

        ...

         <container:child layoutData="{minVerticalLayoutData}">
         <g:HTMLPanel styleName="{resources.commonsCss.layout_header}">
           <div class="{resources.commonsCss.layout_title}">
             First Project
           </div>
           <div class="{resources.commonsCss.logout}">
             <span class="{resources.commonsCss.underline}">
               <a class="{resources.commonsCss.button}" href="/logout" >
                  <span class="{resources.commonsCss.exit}">Logout</span>
               </a>
             </span>
           </div>
         </g:HTMLPanel>
         </container:child>
         ...
</ui:UiBinder>
Styling our application(Continuation)
Modify LayoutView.java
public class LayoutView extends ViewImpl implements LayoutPresenter .
MyView {

    ...

    @Inject
    public LayoutView(final Binder binder , final Resources resources ) {

          resources.commonsCss ().ensureInjected ();//load css

          widget = binder.createAndBindUi (this);
    }


}
mvn gwt:run




              Thanks
References
http://www.youtube.com/playlist?
list=PL29DDDC847F63AF82
http://code.google.com/p/google-gin/wiki/GinTutorial
http://code.google.com/p/google-guice/

http://www.youtube.com/watch?
v=1iLg_qWTrXY&feature=relmfu
http://www.sencha.com/examples/#ExamplePlace:
centerlayout(uibinder)
http://code.google.com/p/google-web-
toolkit/wiki/CssResource#Image_Sprites

Weitere ähnliche Inhalte

Was ist angesagt?

Study HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdf
Study HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdfStudy HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdf
Study HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdfTakayuki Kabu
 
Flutter 踩雷心得
Flutter 踩雷心得Flutter 踩雷心得
Flutter 踩雷心得Weizhong Yang
 
XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...
XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...
XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...Kousuke Ebihara
 
ひとりドキュメント担当の仕事を楽しむ
ひとりドキュメント担当の仕事を楽しむひとりドキュメント担当の仕事を楽しむ
ひとりドキュメント担当の仕事を楽しむsoishino
 
画面状態を抽象化してテスタブル設計ライフを送ろう
画面状態を抽象化してテスタブル設計ライフを送ろう画面状態を抽象化してテスタブル設計ライフを送ろう
画面状態を抽象化してテスタブル設計ライフを送ろうHiroshi Kikuchi
 
Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発m ishizaki
 
はじめてのWallaby.js
はじめてのWallaby.jsはじめてのWallaby.js
はじめてのWallaby.jsShunta Saito
 
導入 Flutter 前你應該知道的事
導入 Flutter 前你應該知道的事導入 Flutter 前你應該知道的事
導入 Flutter 前你應該知道的事Weizhong Yang
 
Goの時刻に関するテスト
Goの時刻に関するテストGoの時刻に関するテスト
Goの時刻に関するテストKentaro Kawano
 
Google flutter the easy and practical way
Google flutter the easy and practical wayGoogle flutter the easy and practical way
Google flutter the easy and practical wayAhmed Abu Eldahab
 
はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)
はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)
はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)虎の穴 開発室
 
モダナイゼーションがもたらす未来
モダナイゼーションがもたらす未来モダナイゼーションがもたらす未来
モダナイゼーションがもたらす未来Hiromasa Oka
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門Shohei Arai
 
計算量のはなし(Redisを使うなら必読!O(logN)など)
計算量のはなし(Redisを使うなら必読!O(logN)など)計算量のはなし(Redisを使うなら必読!O(logN)など)
計算量のはなし(Redisを使うなら必読!O(logN)など)Makoto SAKAI
 
Building beautiful apps using google flutter
Building beautiful apps using google flutterBuilding beautiful apps using google flutter
Building beautiful apps using google flutterAhmed Abu Eldahab
 
Memory Management of C# with Unity Native Collections
Memory Management of C# with Unity Native CollectionsMemory Management of C# with Unity Native Collections
Memory Management of C# with Unity Native CollectionsYoshifumi Kawai
 
ドキュメントの継続的改善―Sphinxを使いながら
ドキュメントの継続的改善―Sphinxを使いながらドキュメントの継続的改善―Sphinxを使いながら
ドキュメントの継続的改善―Sphinxを使いながらsoishino
 

Was ist angesagt? (20)

Study HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdf
Study HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdfStudy HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdf
Study HashiCorp Products - Terraform 実行環境の決定版、Terraform Cloudの機能全部見せます_.pdf
 
Flutter 踩雷心得
Flutter 踩雷心得Flutter 踩雷心得
Flutter 踩雷心得
 
XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...
XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...
XML と PHP のイケナイ関係 (セキュリティ的な意味で) -Introduction of XXE attack and XML Bomb with...
 
ひとりドキュメント担当の仕事を楽しむ
ひとりドキュメント担当の仕事を楽しむひとりドキュメント担当の仕事を楽しむ
ひとりドキュメント担当の仕事を楽しむ
 
画面状態を抽象化してテスタブル設計ライフを送ろう
画面状態を抽象化してテスタブル設計ライフを送ろう画面状態を抽象化してテスタブル設計ライフを送ろう
画面状態を抽象化してテスタブル設計ライフを送ろう
 
Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発Visual Studio Code で C# でのアプリ開発
Visual Studio Code で C# でのアプリ開発
 
はじめてのWallaby.js
はじめてのWallaby.jsはじめてのWallaby.js
はじめてのWallaby.js
 
導入 Flutter 前你應該知道的事
導入 Flutter 前你應該知道的事導入 Flutter 前你應該知道的事
導入 Flutter 前你應該知道的事
 
Flutter
FlutterFlutter
Flutter
 
Goの時刻に関するテスト
Goの時刻に関するテストGoの時刻に関するテスト
Goの時刻に関するテスト
 
Google flutter the easy and practical way
Google flutter the easy and practical wayGoogle flutter the easy and practical way
Google flutter the easy and practical way
 
はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)
はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)
はじめようVue3!とらのあなラボのフロントエンドを学ぶ(藤原)
 
モダナイゼーションがもたらす未来
モダナイゼーションがもたらす未来モダナイゼーションがもたらす未来
モダナイゼーションがもたらす未来
 
DevOpsって何?
DevOpsって何?DevOpsって何?
DevOpsって何?
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門
 
計算量のはなし(Redisを使うなら必読!O(logN)など)
計算量のはなし(Redisを使うなら必読!O(logN)など)計算量のはなし(Redisを使うなら必読!O(logN)など)
計算量のはなし(Redisを使うなら必読!O(logN)など)
 
Building beautiful apps using google flutter
Building beautiful apps using google flutterBuilding beautiful apps using google flutter
Building beautiful apps using google flutter
 
Memory Management of C# with Unity Native Collections
Memory Management of C# with Unity Native CollectionsMemory Management of C# with Unity Native Collections
Memory Management of C# with Unity Native Collections
 
一度死んだ話
一度死んだ話一度死んだ話
一度死んだ話
 
ドキュメントの継続的改善―Sphinxを使いながら
ドキュメントの継続的改善―Sphinxを使いながらドキュメントの継続的改善―Sphinxを使いながら
ドキュメントの継続的改善―Sphinxを使いながら
 

Ähnlich wie Architecting your GWT applications with GWT-Platform - Lesson 02

Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejugrobbiev
 
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFPierre-Yves Ricau
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EEAlexis Hassler
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Michael Plöd
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatissimonetripodi
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Chris Ramsdale
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023Johnny Sung
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6William Marques
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo Ali Parmaksiz
 
Vaadin 7 Today and Tomorrow
Vaadin 7 Today and TomorrowVaadin 7 Today and Tomorrow
Vaadin 7 Today and TomorrowJoonas Lehtinen
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 

Ähnlich wie Architecting your GWT applications with GWT-Platform - Lesson 02 (20)

Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejug
 
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
 
Gwt RPC
Gwt RPCGwt RPC
Gwt RPC
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EE
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6Integrating Wicket with Java EE 6
Integrating Wicket with Java EE 6
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Vaadin 7 Today and Tomorrow
Vaadin 7 Today and TomorrowVaadin 7 Today and Tomorrow
Vaadin 7 Today and Tomorrow
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 

Mehr von rhemsolutions

Mehr von rhemsolutions (7)

Introduction maven3 and gwt2.5 rc2 - Lesson 01
Introduction maven3 and gwt2.5 rc2 - Lesson 01Introduction maven3 and gwt2.5 rc2 - Lesson 01
Introduction maven3 and gwt2.5 rc2 - Lesson 01
 
Ireport
IreportIreport
Ireport
 
Zend_Acl
Zend_AclZend_Acl
Zend_Acl
 
instalar postgresql php
instalar postgresql phpinstalar postgresql php
instalar postgresql php
 
Hibernate
HibernateHibernate
Hibernate
 
Diagramas De Flujo
Diagramas De FlujoDiagramas De Flujo
Diagramas De Flujo
 
Introducción Php
Introducción PhpIntroducción Php
Introducción Php
 

Architecting your GWT applications with GWT-Platform - Lesson 02

  • 1. Architecting your GWT application with GWT- Platform Juan Manuel Rojas R. http://rhemsolutions.com/ Lima, Perú 26/10/2012
  • 2. Architecting your GWT application Google found that a Model-view-presenter (MVP) architecture works best when developing GWT apps https://developers.google.com/web-toolkit/articles/mvp- architecture Model View Presenter Frameworks Mvp4g gwt-dispatch gwt-platform
  • 3. GWT-Platform It's an open source MVP framework, that supports many nice features of GWT, including code splitting and history management, with a simple annotation-based API.
  • 4. A highly productive app stack UI (MVP) gwt-platform (GWTP) RPC GWT RequestFactory PostgreSQL JPA 2.0 - PostgreSQL http://www.youtube.com/watch? feature=player_detailpage&v=imiquTOLl64#t=200s
  • 5. Google Plugin for Eclipse Update sites Eclipse 4.2 (Juno) http://dl.google.com/eclipse/plugin/4.2
  • 6. GWTP Eclipse Plugin To install the GWTP Eclipse Plugin, from Eclipse go to Help > Install New Software Click on Add... Name: GWTP Location: http://plugin.gwt-platform.googlecode.com/hg/update
  • 7. Clean example code 1. Delete theme lines from Module.gwt.xml 2. Delete files from Entry point client package GreetingService package com.example.client; GreetingServiceAsync server package, import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.Window; GreetingServiceImpl shared packaged public class FirstProject implements EntryPoint { FieldVerifier src/test/java public void onModuleLoad() { GwtTestFirstProject Window.alert("empty project"); } src/test/resources } FirstProjectJUnit.gwt.xml 3. Clean Css file and html table code src/main/webapp 4. Delete servlet definition from web.xml src/main/webapp/WEB-INF
  • 8. Dependency injection (DI) Separate behavior from dependency resolution. Injects the dependent element (object or value etc) to the destination automatically. Reduction of boilerplate code in the application objects since all work to initialize or set up dependencies is handled by a provider component. http://en.wikipedia.org/wiki/Dependency_injection
  • 9. Dependency injection for GWT google-gin GIN is built on top of Guice and uses (a subset of) Guice's binding language. <!-- google-gin --> <dependency> <groupId>com.google.gwt.inject</groupId> <artifactId>gin</artifactId> <version>2.0.0</version> <exclusions> <exclusion> <groupId>com.google.gwt</groupId> <artifactId>gwt-servlet</artifactId> </exclusion> </exclusions> </dependency>
  • 10. Dependency injection for Java 5 google-guice Think of Guice's @Inject as the new new. Guice embraces Java's type safe nature using generics and annotations. <!-- google guice --> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>3.0</version> </dependency>
  • 11. Dependency injection GIN Constructor injection Field injection public class ClientPlaceManager { public class ColaboradorPresenter { @Inject @Inject Messages messages; public ClientPlaceManager(final EventBus eventBus, final TokenFormatter tokenFormatter) { public ColaboradorPresenter() { //eventBus and tokenFormatter are not null //messages is null } } } protected void onBind() { //messages is not null } }
  • 12. Dependency injection GIN (Continuation) @Provides Methods When you need create and initialize an object. public class ClientModule extends AbstractPresenterModule { @Provides @Singleton public AppRequestFactory createRequestFactory(EventBus eventBus, MyDefaultRequestTransport requestTransport) { AppRequestFactory factory = GWT.create(AppRequestFactory.class); factory.initialize(eventBus, requestTransport); return factory; } } public class ColaboradorPresenter { private final AppRequestFactory factory; How to inject @Inject public ColaboradorPresenter(Provider<AppRequestFactory> provider){ factory = provider.get(); } }
  • 13. Setting GWTP and GXT3 <properties> Add to your Module.gwt.xml ... <gwtp.version>0.7</gwtp.version> ... <inherits name='com.sencha.gxt.ui.GXT'/> </properties> <inherits name='com.gwtplatform.mvp.Mvp'/> <!-- MVP component --> <dependency> Add to your POM.xml <groupId>com.gwtplatform</groupId> <artifactId>gwtp-mvp-client</artifactId> <version>${gwtp.version}</version> <scope>provided</scope> <!-- sencha gxt3 --> </dependency> <dependency> <!-- Annotation component --> <groupId>com.sencha.gxt</groupId> <dependency> <artifactId>gxt</artifactId> <groupId>com.gwtplatform</groupId> <version>3.0.1</version> <artifactId>gwtp-processors</artifactId> </dependency> <version>${gwtp.version}</version> <scope>provided</scope> </dependency>
  • 14. Setting GWTP Create the directories com.example.client import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; |--presenter import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; |--view |--place @BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) public class NameTokens { @Retention(RUNTIME) public @interface DefaultPlace { } } import com.google.web.bindery.event.shared.EventBus; public class ClientPlaceManager extends PlaceManagerImpl { private final PlaceRequest defaultPlaceRequest; @Inject public ClientPlaceManager(final EventBus eventBus, final TokenFormatter tokenFormatter, @DefaultPlace final String defaultPlaceNameToken) { super(eventBus, tokenFormatter); this.defaultPlaceRequest = new PlaceRequest(defaultPlaceNameToken); } public void revealDefaultPlace() { revealPlace(defaultPlaceRequest, false); }
  • 15. Setting GIN for GWTP Inheriting the GIN module <inherits name="com.google.gwt.inject.Inject"/> Create a gin package in the client side public class ClientModule extends AbstractPresenterModule { Define objects @Override available for protected void configure() { injection install(new DefaultModule(ClientPlaceManager.class)); } } import com.google.web.bindery.event.shared.EventBus; Getters methods @GinModules(ClientModule.class) public interface ClientGinjector extends Ginjector { for get objects EventBus getEventBus(); PlaceManager getPlaceManager(); } If GIN can't find a binding for a class, it falls back to calling GWT.create() on that class.
  • 16. Setting GIN for GWTP(Continuation) Configure your EntryPoint public class FirstProject implements EntryPoint { private final ClientGinjector ginjector = GWT.create(ClientGinjector.class); public void onModuleLoad() { // This is required for Gwt-Platform proxy's generator DelayedBindRegistry.bind(ginjector); ginjector.getPlaceManager().revealCurrentPlace(); } } Add the next properties to your Module.gwt.xml <module> ... <define-configuration-property name='gin.ginjector' is-multi-valued='false' /> <set-configuration-property name='gin.ginjector' value='com.example.client.gin.ClientGinjector' /> </module>
  • 17. GWT-Platform and GXT3 Structure your views A place represent a url of a program
  • 18. GWT-Platform and GXT3(Continuation) Tokens Most presenters have a token so the user can navigate. When there is not token the default presenter is shown. You can navigate from one presenter to another by: ● Typing another url PlaceRequest request = new PlaceRequest("inicio"); ● Using a Hyperlink Widget placeManager.revealPlace(request); ● Using a PlaceRequest
  • 19. GWT-Platform and GXT3(Continuation) Nested Presenters Your header, footer and menu are in one presenter the "parent presenter".
  • 20. GWT-Platform and GXT3(Continuation) Presenter Widget Is for reusable graphical and logical code.
  • 21. GWT-Platform and GXT3(Continuation) Popup Presenters Is a presenter widget that is shown inside a popup dialog. For create Popup Presenters with GXT Window you need the following classes GXTPopupViewImpl.java GXTPopupViewWithUiHandlers.java
  • 22. GWT-Platform and GXT3(Continuation) All presenters are composed of three files if you will use UIBinder All presenters have a inner interface that view implements.
  • 24. GWT-Platform and GXT3(Continuation) Presenter lifecycle 1. Presenters are Singleton so it is instantiated once. 2. prepareFromRequest(): Is where you can get url parameters. 3. onBind(): Is called when the presenter is instantiated. 4. onReveal(): Is called whenever the Presenter was not visible on screen and becomes visible. 5. onHide(): Is called whenever the Presenter was visible on screen and is being hidden. 6. onReset(): Is called whenever the user navigates to a page that shows the presenter, whether it was visible or not.
  • 25. Create Presenter using GWTP Eclipse Plugin
  • 26. First Presenter LayoutPresenter Options ● Use UiBinder ● RevealRootContentEvent ● Is Not a Place Ordering Move to view package LayoutView.java LayoutView.ui.xml
  • 27. First Presenter LayoutPresenter (Continuation) Deprecated shared.EventBus GWTP Eclipse Plugin use EventBus from event.shared next this package was deprecated and change to web. bindery.event.shared. * Is important to do the next in every presenter you create with GWTP Eclipse Plugin Delete import com.google.gwt.event.shared.EventBus Replace by import com.google.web.bindery.event.shared.EventBus;
  • 28. First Presenter LayoutPresenter (Continuation) Add the next field to LayoutPresenter import com.google.gwt.event.shared.GwtEvent.Type; //for nested presenters @ContentSlot public static final Type<RevealContentHandler<?>> SLOT_content = new Type<RevealContentHandler<?>>(); Modify LayoutView.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' xmlns:gxt= "urn:import:com.sencha.gxt.widget.core.client" xmlns:container= "urn:import:com.sencha.gxt.widget.core.client. container" > <container:Viewport> <!--for nested presenter --> <gxt:ContentPanel ui:field="contentPanel" borders="false" headerVisible= "false" bodyBorder= "false" /> </container:Viewport> </ui:UiBinder>
  • 29. First Presenter LayoutPresenter (Continuation) Setting Vertical Layout (LayoutView.ui.xml) <ui:UiBinder> ... <ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="minVerticalLayoutData" > <ui:attributes width="1" height="-1" /> </ui:with> <ui:with type="com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData" field="maxVerticalLayoutData" > <ui:attributes width="1" height="1" /> </ui:with> <container:Viewport> ... </container:Viewport> </ui:UiBinder>
  • 30. First Presenter LayoutPresenter (Continuation) Using Vertical Layout (LayoutView.ui.xml) <ui:UiBinder> ... <container:Viewport> <container:VerticalLayoutContainer> <container:child layoutData="{minVerticalLayoutData}"> <g:HTMLPanel> <div> <div>First Project</div> </div> </g:HTMLPanel> </container:child> <container:child layoutData="{maxVerticalLayoutData}"> <!--for nested presenter --> <gxt:ContentPanel ui:field="contentPanel" borders="false" headerVisible="false" bodyBorder="false" /> </container:child> </container:VerticalLayoutContainer> </container:Viewport> </ui:UiBinder>
  • 31. First Presenter LayoutPresenter (Continuation) Add the next field to LayoutView @UiField ContentPanel contentPanel;//for nested presenter Add the next method to LayoutView @Override public void setInSlot(Object slot, Widget content) { if(slot == LayoutPresenter.SLOT_content){ contentPanel.clear(); if(content != null){ contentPanel.add(content); contentPanel.forceLayout(); } return; } super.setInSlot(slot, content); }
  • 32. Default Presenter WelcomePresenter Options ● Use UiBinder ● RevealContentEvent ● Content Slot (from parent presenter) ● Is a Place ● CodeSplit (recommended) ● Token: #welcome ● DefaultPlace
  • 33. Default Presenter WelcomePresenter (Continuation) Modify WelcomeView.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' xmlns:gxt= "urn:import:com.sencha.gxt.widget.core.client" xmlns:container= "urn:import:com.sencha.gxt.widget.core.client.container" > <gxt:ContentPanel headingText= "Welcome" > <container:CenterLayoutContainer> <g:HTMLPanel><h2> Welcome User </h2></g:HTMLPanel> </container:CenterLayoutContainer> </gxt:ContentPanel> </ui:UiBinder>
  • 34. reset.css Download reset.css put this css in your HTML header <head> ... <link type="text/css" rel="stylesheet" href="reset.css"> ... </head> In your Module.css file *{ font-family: arial, helvetica, tahoma, sans-serif; }
  • 36. Styling our application GWT provides ClientBundle for styling in an optimised way. client.resources |- add.png |- delete.png |- cancel.png |- edit.png |- save.png |- exit.png |- bg.gif
  • 37. Styling our application(Continuation) public interface Resources extends ClientBundle { @Source("add.png") ImageResource add(); @Source("delete.png") client.resources ImageResource delete(); |- Resources.java @Source("cancel.png") ImageResource cancel(); @Source("edit.png") ImageResource edit(); @Source("save.png") ImageResource save(); @Source("exit.png") ImageResource exit(); }
  • 38. Styling our application(Continuation) public interface CommonsCss extends CssResource { @ClassName("layout-header") String layout_header(); client.resources |- CommonsCss.java @ClassName("layout-title") |- Commons.css String layout_title(); String logout(); @ClassName("underline") String underline(); @ClassName("button") String button(); String exit(); }
  • 39. Styling our application(Continuation) Add to your ClientBundle public interface Resources extends ClientBundle { ... @Source("bg.gif") ImageResource bg(); @Source("Commons.css") CommonsCss commonsCss(); }
  • 40. Styling our application(Continuation) Modify LayoutView.ui.xml <ui:UiBinder> <ui:with type="com.example.client.resources.Resources" field="resources" /> ... <container:child layoutData="{minVerticalLayoutData}"> <g:HTMLPanel styleName="{resources.commonsCss.layout_header}"> <div class="{resources.commonsCss.layout_title}"> First Project </div> <div class="{resources.commonsCss.logout}"> <span class="{resources.commonsCss.underline}"> <a class="{resources.commonsCss.button}" href="/logout" > <span class="{resources.commonsCss.exit}">Logout</span> </a> </span> </div> </g:HTMLPanel> </container:child> ... </ui:UiBinder>
  • 41. Styling our application(Continuation) Modify LayoutView.java public class LayoutView extends ViewImpl implements LayoutPresenter . MyView { ... @Inject public LayoutView(final Binder binder , final Resources resources ) { resources.commonsCss ().ensureInjected ();//load css widget = binder.createAndBindUi (this); } }
  • 42. mvn gwt:run Thanks