SlideShare ist ein Scribd-Unternehmen logo
1 von 82
Downloaden Sie, um offline zu lesen
Flex for Java developers:
My quest for pain-free UI
       development
        Chris Richardson
   Author of POJOs in Action
    www.chrisrichardson.net
   chris@chrisrichardson.net
         @crichardson

     Cinco de Mayo 2009
About Chris
                                    Grew up in England and live in Oakland
                          •
                                    Over 20+ years of software
                          •
                                    development experience including 12
                                    years of Java
                                    Started Java architecture consulting
                          •
                                    company and sold it to BEA
                                    Speaker at JavaOne, SpringOne, etc.
                          •
                                    Java Champion
                          •
                                    Run a consulting and training company
                          •
                                    that helps organizations reduce
                                                 g
                                    development costs and i
                                    d    l                d increase
                                    effectiveness




 cloudtools.org

                                                            www.cloudfoundry.com



                                                                                   Slide 2
                  Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI
 development
 Overview of Flex
 Developing Flex Applications
 Pushing data to the client
        g
 Building and testing Flex applications




                                                                        Slide 3
            Copyright (c) 2009 Chris Richardson. All rights reserved.
Arms race: Frameworks vs. UI complexity
                                p     y


1998
1998-     2000
          2000-        2002
                       2002-                         2005
                                                     2005-
                                                                                2007      2008
1999      2002         2005                          2006

 Really   Really         More                          More                       More
 simply   Simple        Complex                       Complex                   complex   Rich UIs
 pages    Pages          Pages                         Pages                     pages


 Home                                                                                     Spring
                                                                                 Spring
 grown                                                                                     MVC
           Struts          Struts                        Spring
                                                                                MVC/Web
 frame      1.0             1.0                           MVC                             WebFlow
                                                                                  Flow
 work                                                                                      Dojo



                                                             /☺                   ☺

                                                                                             Slide 4
                    Copyright (c) 2009 Chris Richardson. All rights reserved.
Cloud Foundry
            y




    Slide 5
Cloud Foundry UI
            y
 Single page application
 Dojo toolkit
 Uses DWR to push events to browser
               p
 End result is quite nice
 But getting there was painful




                                                                       Slide 6
           Copyright (c) 2009 Chris Richardson. All rights reserved.
Why is building RIAs so painful?
  y           g         p
 Open-source JavaScript projects
   Variable quality
            q     y
   Some are poorly documented
   Built on a shaky foundation of web technologies
 JavaScript
         p
   Dynamic ⇒ limited IDE support
   Prototype-based ⇒ simulated classes
   No packages ⇒ build your own
   …
 CSS layout
   Difficult to learn
   Relies on “hacks” to accomplish basic layout tasks
   Lack of portability across browsers
   Easier to use tables?
 Numerous b
 N        browser incompatibilities
                  i      tibiliti

                                                                            Slide 7
                Copyright (c) 2009 Chris Richardson. All rights reserved.
Today's web = multi-layer hack
    y                 y
 Was – a straightforward                                                 Hacks to
                                                                       enable offline

 hypertext browsing system
                                                                        applications




 Now – an application                                                        …


 delivery platform                                                      Fake class
                                                                         system




  ⇒Time for a                                                           Javascript




    change                                                              Hypertext




                                                                                        Slide 8
           Copyright (c) 2009 Chris Richardson. All rights reserved.
GWT is an option
           p
 Treats JavaScript as the runtime
 environment
 Develop and debug in Java
 quot;Swing-stylequot; programming model

  But my social network liked Flex …




                                                                        Slide 9
            Copyright (c) 2009 Chris Richardson. All rights reserved.
So I downloaded Flex Builder




     and wrote some Flex code…
       d             l     d
                                                                      Slide 10
          Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Developing Flex Applications
        pg         pp
 Pushing data to the client
 Building and testing Flex applications




                                                                        Slide 11
            Copyright (c) 2009 Chris Richardson. All rights reserved.
What is Flex?
 Open-source framework for building
 Rich Internet Applications
 Current version is Flex 3 (Flex 4 in 4Q09)
 Flex apps run on the ubiquitous Flash
       pp                 q
 player
   In the browser
   On the desktop with Adobe AIR
 Excellent documentation
 Develop applications in
   MXML – declaratively define UI
   ActionScript 3 – handle events, invoke
   backend services, dynamically construct UI
                    ,y         y

                                                                          Slide 12
              Copyright (c) 2009 Chris Richardson. All rights reserved.
ActionScript 3 – the scripting
language for the Flash p y
   gg                   player
  Class-based, object-oriented language
  Compile-time type checking
  Packages
  Dynamic vs. sealed classes
    Dynamic – add properties/methods at
    runtime
       ti
  Method closures
  High
  Hi h performance AVM2 with JIT
           f                ith
  compiler
  Dialect
  Di le t of ECMAS ipt (like J
             ECMAScript      JavaScript)
                                 S ipt)
                                                                          Slide 13
              Copyright (c) 2009 Chris Richardson. All rights reserved.
ActionScript XML support (
             p        pp    (E4X)
                                )

var x : XML = <createAlbumRequest>
      <title>{title}</title>                                           var albums : XML = <albums>
                                                                        <album>
      <creationDate>
                                                                          <id>id1</id>
            {creationDate.time}                                           <title>t1</title>
                                                                                    /
       </creationDate>                                                    <thumbnail>xyz<thumbnail>
      <notes>{notes}</notes>                                            </album>
                                                                        <album>
   </createAlbumRequest>                                                  <id>id2</id>
                                                                          <title>t2</title>
                                                                          <thumbnail>abc</thumbnail>
var title : String = x.title;                                           </album>
var notes : String = x.notes;                                            …..
                                                                       </albums>


                                         var notes : XMLList = albums.album.notes

                                         var albums2: XMLList = ablums.album.(title = “t1”)



                                                                                              Slide 14
                          Copyright (c) 2009 Chris Richardson. All rights reserved.
Comprehensive component library
   p             p            y
 Components
   have properties and methods
   generate events
 Visual components
   Controls: Button, TextField, …
   Container: TabContainer, Form, Box, …
   Can be styled with CSS
 Non-Visual
   Data access components, e.g. HTTP, Web
   Services
   Validators
   Formatters

                                                                          Slide 15
              Copyright (c) 2009 Chris Richardson. All rights reserved.
Declaratively define UI in MXML
              y
<mx:Application >
  <mx:Form>
   <mx:FormItem label=quot;Symbolquot; fontWeight=quot;boldquot;>
                  label= Symbol fontWeight= bold >
    <mx:TextInput id=quot;symbolquot; text=quot;AAPLquot; fontWeight=quot;normalquot;/>
   </mx:FormItem>
   <mx:FormItem label=quot;quot;>
    <mx:Button label=quot;Get Quotequot; click=quot;handleClick(event)quot;/>
   </mx:FormItem>
    /
  </mx:Form>
   <mx:DataGrid dataProvider=quot;{quotes}quot; width=quot;100%quot;>
    <mx:columns>
      <mx:DataGridColumn headerText=quot;Symbolquot; dataField=quot;symbolquot;/>
      <mx:DataGridColumn headerText=quot;Pricequot; dataField=quot;pricequot;/>
    </mx:columns>
      /      l
   </mx:DataGrid>
</mx:Application>




  Equivalent to creating
   component tree in
       ActionScript

                                                                                            Slide 16
                                Copyright (c) 2009 Chris Richardson. All rights reserved.
Events
      Components generate events
      Handled by ActionScript code
<mx:Button l b l quot;G t Q t quot; click=quot;handleClick(event)quot;/>
<   B tt   label=quot;Get Quotequot; li k quot;h dl Cli k(     t)quot;/>




       private function handleClick(event :Event) : void {
         …
       }




                                                                                          Slide 17
                              Copyright (c) 2009 Chris Richardson. All rights reserved.
Data Binding
           g

 Control is updated whenever variable
 changes
                [Bindable]
                private var quotes : Array = [];




 <mx:DataGrid dataProvider=quot;{quotes}quot; width=quot;100%quot;>
              dataProvider= {quotes} width= 100% >
     <mx:columns>
      <mx:DataGridColumn headerText=quot;Symbolquot; dataField=quot;symbolquot;/>
      <mx:DataGridColumn headerText=quot;Pricequot; dataField=quot;pricequot;/>
     </mx:columns>
 </mx:DataGrid>


                                                                                  Slide 18
                      Copyright (c) 2009 Chris Richardson. All rights reserved.
Custom components
          p

                                                                                       Define
<mx:GridItem >
                          AlbumThumbnail.mxml
  <mx:Script>

                                                                                       subclasses in
  <![CDATA[
   [Bindable]

                                                                                       MXML or
   public var album : XML;

   p
   public function viewAlbum() : void { ….}
                            ()            }
                                                                                       ActionScript
                                                                                       A ti S i t
  ]]>
  </mx:Script>
                                                                                       Use to
  <mx:VBox width=quot;100quot; height=quot;125quot;>

                                                                                       modularize
                                                                                           dl i
   <mx:Image id quot;i
       I       id=quot;imgquot; click=quot;viewAlbum()quot;
                      quot; li k quot; i Alb    ()quot;
              source=quot;{album.thumbnail}quot; />
  </mx:Box>
                                                                                       application
  <mx:Text width=quot;100quot; height=quot;25quot;
           text=quot;{album.title}quot;/>

                                                                                       3rd party
                                                                                         d
 </mx:VBox>


                                                                                       components
</mx:GridItem>

         <components:AlbumThumbnail
                 album=quot;{rp.currentItem}quot;/>


                                                                                                 Slide 19
                                 Copyright (c) 2009 Chris Richardson. All rights reserved.
Flex security sandbox
            y
 Uses the Flash Player security model
 By default, a Flex application can only
 access resources on the site that it
 was downloaded from
 Cross-domain policy files on remote
 server grants access to Flex
 applications from other domains




                                                                        Slide 20
            Copyright (c) 2009 Chris Richardson. All rights reserved.
Flex Tools from Adobe
 Flex SDK
   Free, open-source
   F
   Compilers and command-line debugger
 FlexBuilder –
   Cheap ($249) Eclipse-based IDE
   For Mac and Windows
   MXML and ActionScript editors –
   completion, renaming and validation
   Drag and drop UI builder
   Good debugging: breakpoints,
   Comprehensive h l
   C      h    i  help
                                                                        Slide 21
            Copyright (c) 2009 Chris Richardson. All rights reserved.
Flex Stock Quote Demo
           Q




                                                                     Slide 22
         Copyright (c) 2009 Chris Richardson. All rights reserved.
Flex back-end integration
                  g
 BlazeDS
   Open-source project
   O                 j
   Allows Flex clients to talk to server-side
   Java applications
   RPC
   Server-push over HTTP
          p
 LiveCycle Data Services ES
   Commercial
   Superset of BlazeDS
   More scalable
   Client/Server d t synchronization
   Cli t/S       data    h   i ti
                                                                          Slide 23
              Copyright (c) 2009 Chris Richardson. All rights reserved.
Flex Application Architecture
      pp



                                                                  Blaze
                                                                   DS




  SOFEA = Service-Oriented Front-End Architecture
          Service Oriented Front End

                                                                            Slide 24
                Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Building Flex Applications
   The Cairngorm framework
   Cloud Photos Example Application
   Scenario: displaying albums
   S     i di l i        lb
   Scenario: creating a new album
   Scenario: copying photos between albums
 Pushing data to the client
 Building and testing Flex applications
                                                                         Slide 25
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Tangled code
   g
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;
 layout=quot;absolutequot;
 implements=quot;mx.rpc.IResponderquot;
 backgroundColor=quot;#ffffffquot;>
 <mx:Script>
                                                                                                   Data
 [Bindable]
 private var quote : String;

 private function handleClick(event :Event) : void {
     var service : HTTPService = new HTTPService();
                                                                                                 Data
 …
                                                                                                 Access
 }
                                                                                                 Logic
 public function result(data:Object):void { …. }
 p
 public function fault(info:Object):void { }
                      (       j   )
 ]]>
 </mx:Script>
    <mx:VDividedBox width=quot;414quot; height=quot;217quot;
                                                                                      Presentation logic
       ….
    </mx:VDividedBox>

</mx:Application>
                                                                                                    Slide 26
                          Copyright (c) 2009 Chris Richardson. All rights reserved.
Cairngorm framework
     g
 MVC framework for Flex
   Model – data
   View – Flex components that display the
   model (through binding)
   Controller – implements quot;business logicquot;
                                      logicquot;,
   i.e. accessing backend services and update
   the model
 Encourages:
   Separation of concerns
   Separation of development roles: front-end
   and b k
     d back-endd
 Avoids big ball of mud
 An alternative is PureMVC
                                                                         Slide 27
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Cairngorm classes and roles
     g
 Views
     Display the model                                                       The code has a cookie-
 ModelLocator                                                                cutter feel to it but I
     Provides access to the model
                                                                             like the structure
 “Business” Events
     Generated by Views
 Front Controller
     Routes events to Commands
 Commands
     Handle events
     Contain quot;business logicquot;/data access logic
                         g/                 g
     Invoke delegates
 Delegates
     Proxy for remote services
     Contract between front-end and back-end team
     Calls b k t
     C ll back to command d
 ServiceLocator
     Centralized registry of (supposedly) all data access components
     Used by delegates




                                                                                               Slide 28
                         Copyright (c) 2009 Chris Richardson. All rights reserved.
Cairngorm flow
     g




                                                                     Slide 29
         Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Building Flex Applications
   The Cairngorm framework
   Cloud Photos Example Application
   Scenario: displaying albums
   S     i di l i        lb
   Scenario: creating a new album
   Scenario: copying photos between albums
 Pushing data to the client
 Building and testing Flex applications
                                                                         Slide 30
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Cloud Photos Application
              pp
                                                         Tomcat
               RESTful web services
 Flex Client
                                                            Scala/Spring MVC
                                                                 /p g
               Events


                                                            Java/Spring/JMS

  Manage your
  photos online
      Upload and
        p
      view photos                                                                               Simple DB

      Organize                                                                S3
      photos into                                                         Amazon Web Services


      albums
      …

                                                                                                    Slide 31
                  Copyright (c) 2009 Chris Richardson. All rights reserved.
Cloud Photos – screenshots




                                                                      Slide 32
          Copyright (c) 2009 Chris Richardson. All rights reserved.
Cloud Photo – web services
        http://localhost:8080/webapp/api/album




<albums>
 <album>
  <id>e778769a-8432-46ca-b0f1-5c92f33a8710</id>
  <title>Pictures of kids</title>
  <thumbnail>https://s3.amazonaws.com/…</thumbnail>
 </album>
   /
 <album>
  <id>1ff7528a-65aa-4300-a5bb-c5b7e6eba985</id>
  <title>Some birds</title>
  <thumbnail>https://s3.amazonaws.com…</thumbnail>
                  p //                  /
 </album>
  …..
</albums>




                                                                                   Slide 33
                       Copyright (c) 2009 Chris Richardson. All rights reserved.
Application structure
 pp




                                                                       Slide 34
           Copyright (c) 2009 Chris Richardson. All rights reserved.
Model – a Singleton
             g
package net.chrisrichardson.cloudphotos.ui.model {
  import com.adobe.cairngorm.model.IModelLocator;
                                                                                Metadata tag enables binding for all
                                                                                public properties
    [Bindable]
    public class CloudPhotosModelLocator implements IModelLocator {

      private static var modelLocator:CloudPhotosModelLocator;

      public var viewState : String = quot;displayAlbumsquot;;

      public var albums : XMLList;
      public var currentAlbum : XML
        bli            tAlb     XML;

     public static function getInstance():CloudPhotosModelLocator{
        if (modelLocator == null) {                                                                         Singleton
            modelLocator = new CloudPhotosModelLocator();();
        }
        return modelLocator;
      }

}

}
                                                                                                                   Slide 35
                             Copyright (c) 2009 Chris Richardson. All rights reserved.
View - Main application
             pp
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:Application layout=quot;verticalquot;
                  layout vertical
 xmlns:ns1=quot;net.chrisrichardson.cloudphotos.ui.components.*quot;
 xmlns:control=quot;net.chrisrichardson.cloudphotos.ui.control.*quot;
 xmlns:business=quot;net.chrisrichardson.cloudphotos.ui.business.*quot;
 width=quot;100%quot; height=quot;100%quot;>
  idth quot;100%quot; h i ht quot;100%quot;


 <business:Services id=quot;servicesquot; />
  bus ess Se ces d se ces /
 <control:Controller id=quot;controllerquot; />

 <mx:Label text=quot;Cloud Photosquot; fontSize=quot;33quot;/>
 <ns1:HomePage width=quot;100%quot; height=quot;100%quot;>
                width quot;100%quot; height quot;100%quot;>
 </ns1:HomePage>
</mx:Application>



                                                                                  Slide 36
                      Copyright (c) 2009 Chris Richardson. All rights reserved.
View - HomePage
             g
<mx:Vbox …>

 <mx:Binding destination=quot;currentStatequot;
             destination currentState
            source=quot;{CloudPhotosModelLocator.getInstance().viewState}quot;/>

 <mx:states>
  <mx:State name=quot;displayAlbumsquot;>
     <mx:SetProperty name=quot;selectedIndexquot; target=quot;{viewStack}quot; value=quot;{0}quot;/>
  </mx:State>
  <mx:State name=quot;displayAlbumquot;>
    <mx:SetProperty name=quot;selectedIndexquot; target=quot;{viewStack}quot; value=quot;{1}quot;/>
  </mx:State>
 </mx:states>

 <mx:TabNavigator id=quot;tabNavigatorquot; …>
                  id= tabNavigator   >

 <mx:ViewStack id=quot;viewStackquot; width=quot;100%quot; height=quot;100%quot; label=quot;My Albumsquot; >
   <components:AlbumList id=quot;albumListquot; width=quot;100%quot; height=quot;100%“/>
   <components:AlbumView id=quot;albumViewquot; width=quot;100%quot; height=quot;100%“/>
 </mx:ViewStack>
  …
 </mx:TabNavigator>

                                      CloudPhotosModelLocator.getInstance().viewState
</mx:VBox>
                                      determines whether we are viewing albums or an
                                      album



                                                                                              Slide 37
                                  Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Building Flex Applications
   The Cairngorm framework
   Cloud Photos Example Application
   Scenario: di l i
   S      i displaying albums
                           lb
   Scenario: creating a new album
   Scenario: copying photos between albums
 Pushing data to the client
 Building and testing Flex applications
                                                                         Slide 38
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Display Albums Flow
   py




                                                                      Slide 39
          Copyright (c) 2009 Chris Richardson. All rights reserved.
View dispatches event
        p
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:Vbox … creationComplete=quot;displayAlbums()quot;>
  <mx:Script>
  <![CDATA[
   private function displayAlbums():void {
    var event : DisplayAlbumsEvent = new DisplayAlbumsEvent();
    event.dispatch();
   }

    private function createAlbum() : void {
      PopUpManager.centerPopUp(PopUpManager.createPopUp(this, CreateAlbumPopup, true));
    }
  ]]>
  </mx:Script>

 <mx:HBox width=quot;100%quot; height=quot;10%quot;>
   <mx:Button label=quot;Create Newquot; click=quot;createAlbum()quot;/>
 </mx:HBox>

 <mx:Tile id=quot;albumGridquot; width=quot;100%quot; height=quot;90%quot;>
  <mx:Repeater id quot; quot; d t P
      R      t id=quot;rpquot; dataProvider=quot;{CloudPhotosModelLocator.getInstance().albums}quot;>
                               id   quot;{Cl dPh t M d lL     t     tI t     () lb    }quot;
   <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/>
  </mx:Repeater>
 </mx:Tile>
</mx:VBox>




                                                                                              Slide 40
                                  Copyright (c) 2009 Chris Richardson. All rights reserved.
Controller executes command
package net.chrisrichardson.cloudphotos.ui.control
{
  import com.adobe.cairngorm.control.FrontController;

    import net.chrisrichardson.cloudphotos.ui.command.*;
    import net.chrisrichardson.cloudphotos.ui.event.*;

    public class Controller extends FrontController
    {
      public function Controller()
      {
        initializeCommands();
      }

        public function initializeCommands() : void
        {
          addCommand( CreateAlbumEvent.CREATE_ALBUM, CreateAlbumCommand);
          addCommand( DisplayAlbumsEvent.DISPLAY_ALBUMS, DisplayAlbumsCommand);
          addCommand( DisplayAlbumEvent.DISPLAY_ALBUM, DisplayAlbumCommand);
          addCommand( CopyPhotoToAlbumEvent.COPY_PHOTO, CopyPhotoToAlbumCommand);

        }
    }

}




                                                                                                     Slide 41
                                         Copyright (c) 2009 Chris Richardson. All rights reserved.
Command calls delegate
                  g
public class DisplayAlbumsCommand implements ICommand, IResponder
{

public function execute( event:CairngormEvent ):void {
 var delegate : DisplayAlbumsDelegate = new DisplayAlbumsDelegate(this);
 delegate.displayAlbums();
}

    public function result( event : Object ):void {
      var albums : XMLList = event.result.album;
      var model : Cl dPh t M d lL
             d l CloudPhotosModelLocator = Cl dPh t M d lL
                                         t      CloudPhotosModelLocator.getInstance();
                                                                    t     tI t     ()
      model.albums = albums
    }

    p
    public function fault( event : Object ) : void {
                         (           j
       // handle error
    }
}




                                                                                            Slide 42
                                Copyright (c) 2009 Chris Richardson. All rights reserved.
Delegate invokes service
    g
public class DisplayAlbumsDelegate
{
  private var responder : IResponder;
  private var service : HTTPService;

    public function DisplayAlbumsDelegate( responder : IResponder ) {
      this.service = ServiceLocator.getInstance().getHTTPService( quot;displayAlbumsquot; );
                                                                   displayAlbums
      this.responder = responder;
    }

    public function displayAlbums() : void {
     var call : Obj t = service.send()
            ll Object       i      d()
     call.addResponder(responder);
    }


}




                                                                                          Slide 43
                              Copyright (c) 2009 Chris Richardson. All rights reserved.
Service definition
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>

<cairngorm:ServiceLocator
 xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;
 xmlns:cairngorm http://www.adobe.com/2006/cairngorm >
 xmlns:cairngorm=quot;http://www adobe com/2006/cairngormquot;>

<mx:HTTPService id=quot;displayAlbumsquot;
  url=quot;http://.../api/albumquot;
  resultFormat=quot;e4xquot;
      ltF     t quot;4quot;
  useProxy=quot;falsequot;
  method=quot;GETquot; >
 </mx:HTTPService>
  /


</cairngorm:ServiceLocator>



                                                                                 Slide 44
                     Copyright (c) 2009 Chris Richardson. All rights reserved.
Command updates model
              p
public class DisplayAlbumsCommand implements ICommand, IResponder
{

public function execute( event:CairngormEvent ):void {
   var delegate : DisplayAlbumsDelegate = new DisplayAlbumsDelegate(this);
   delegate.displayAlbums();
 }

    public function result( event : Object ):void {
     var albums : XMLList = event.result.album;
     var model : Cl dPh t M d lL
             d l CloudPhotosModelLocator = Cl dPh t M d lL
                                         t     CloudPhotosModelLocator.getInstance();
                                                                   t     tI t     ()
     model.albums = albums
    }

    p
    public function fault( event : Object ) : void {
                         (           j                                        <albums>
       // handle error                                                         <album>…</album>
    }                                                                          <album>…</album>
}                                                                              …
                                                                              </albums>



                                                                                                  Slide 45
                                    Copyright (c) 2009 Chris Richardson. All rights reserved.
View displays model
        py
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:Vbox … creationComplete=quot;displayAlbums()quot;>
  <mx:Script>
  <![CDATA[
   private function displayAlbums():void {
     var event : DisplayAlbumsEvent = new DisplayAlbumsEvent();
     event.dispatch();
   }

    private function createAlbum() : void {
      PopUpManager.centerPopUp(PopUpManager.createPopUp(this, CreateAlbumPopup, true));
    }
  ]]>
  </mx:Script>

 <mx:HBox width=quot;100%quot; height=quot;10%quot;>
   <mx:Button label=quot;Create Newquot; click=quot;createAlbum()quot;/>
 </mx:HBox>

 <mx:Tile id=quot;albumGridquot; width=quot;100%quot; height=quot;90%quot;>
  <mx:Repeater id quot; quot; d t P
  <    R     t id=quot;rpquot; dataProvider=quot;{CloudPhotosModelLocator.getInstance().albums}quot;>
                               id   quot;{Cl dPh t M d lL     t     tI t     () lb    }quot;>
   <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/>
  </mx:Repeater>
 </mx:Tile>
</mx:VBox>




                                                                                               Slide 46
                                   Copyright (c) 2009 Chris Richardson. All rights reserved.
View component
        p
                                   <album>
<mx:GridItem >
                                     <id>e778769a-8432-46ca-b0f1-5c92f33a8710</id>
  <mx:Script>
                                     <title>Pictures of kids</title>
                                                             /
                                     <thumbnail>https://s3.amazonaws.com/…</thumbnail>
  <![CDATA[
                                    </album>
   [Bindable]
   public var album : XML;

   p
   public function viewAlbum() : void {
                            ()
     new DisplayAlbumEvent(album.id).dispatch();
     CloudPhotosModelLocator.getInstance().viewState = quot;displayAlbumquot;;
   }

  ]]>
  </mx:Script>
    /  S it

  <mx:Box width=quot;100quot; height=quot;125quot;>
   <mx:Image id=quot;imgquot; click=quot;viewAlbum()quot; source=quot;{album.thumbnail}quot; />
  </mx:Box>
  <mx:Text width=quot;100quot; height= 25 text= {album.title} />
           width= 100 height=quot;25quot; text=quot;{album title}quot;/>

 </mx:VBox>

</mx:GridItem>




                                                                                            Slide 47
                                Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Building Flex Applications
   The Cairngorm framework
   Cloud Photos Example Application
   Scenario: displaying albums
   S     i di l i        lb
   Scenario: creating a new album
   Scenario: copying photos between albums
 Pushing data to the client
 Building and testing Flex applications
                                                                         Slide 48
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Points of interest
  Uses a popup window
  Uploads files
  Command publishes a Cairngorm
             p                g
  event to notify view that upload is
  complete




                                                                         Slide 49
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Displaying a popup window
   p y g ppp
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:Vbox … creationComplete=quot;displayAlbums()quot;>
  <mx:Script>
  <![CDATA[
   private function displayAlbums():void {
     var event : DisplayAlbumsEvent = new DisplayAlbumsEvent();
     event.dispatch();
   }

   private function createAlbum() : void {
     PopUpManager.centerPopUp(PopUpManager.createPopUp(this, CreateAlbumPopup, true));
   }
  ]]>
  </mx:Script>

 <mx:HBox width=quot;100%quot; height=quot;10%quot;>
   <mx:Button label=quot;Create Newquot; click=quot;createAlbum()quot;/>
 </mx:HBox>

 <mx:Tile id=quot;albumGridquot; width=quot;100%quot; height=quot;90%quot;>
  <mx:Repeater id quot; quot; d t P
      R      t id=quot;rpquot; dataProvider=quot;{CloudPhotosModelLocator.getInstance().albums}quot;>
                               id   quot;{Cl dPh t M d lL     t     tI t     () lb    }quot;
   <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/>
  </mx:Repeater>
 </mx:Tile>
</mx:VBox>




                                                                                               Slide 50
                                   Copyright (c) 2009 Chris Richardson. All rights reserved.
CreateAlbum popup window
            ppp
<mx:TitleWindow>
<mx:Form width=quot;100%quot;>
  <mx:FormItem label=quot;Album Titlequot;>
   <mx:TextInput id quot; lb
         T  I    id=quot;albumTitlequot; change=quot;enableDisableCreateButton()quot;/>
                           Ti l quot; h        quot;   bl Di bl C      B  ()quot;/
  </mx:FormItem>
  <mx:FormItem label=quot;Album Datequot;>
   <mx:DateChooser id=quot;datequot; change=quot;enableDisableCreateButton()quot;/>
  </mx:FormItem>
  <mx:FormItem label=quot;Notesquot;>       <mx:TextArea id=quot;notesquot;/>    </mx:FormItem>
  <mx:FormItem label=quot;quot;>
   <mx:Button label=quot;Select Images...quot; click=quot;selectFiles()quot;/>
  </mx:FormItem>
  <mx:FormItem label=quot;quot;>
                                                                                              <Form> provides
   <mx:Label text=quot;{photosToUpload.length} imagesquot;/>
  </mx:FormItem>
   /
                                                                                              an easy way to
  <mx:FormItem label=quot;Selected Filesquot; width=quot;100%quot;>
                                                                                              layout the form
   <mx:DataGrid dataProvider=quot;{photosToUpload}quot; width=quot;100%quot;>
     <mx:columns>
                                                                                              fields
      <mx:DataGridColumn headerText=quot;Namequot; dataField=quot;namequot;/>
      <mx:DataGridColumn headerText=quot;Datequot; dataField=quot;creationDatequot;/>
     </mx:columns>
   </mx:DataGrid>
  </mx:FormItem>
 </mx:Form>

 <mx:ControlBar>
  <mx:Button id=quot;createButtonquot; label=quot;Create Album click= createAlbum(event) enabled= false />
             id= createButton label= Create Albumquot; click=quot;createAlbum(event)quot; enabled=quot;falsequot;/>
  <mx:Button label=quot;Cancelquot; click=quot;cancelCreateAlbum()quot;/>
 </mx:ControlBar>

</mx:TitleWindow>
                                                                                                      Slide 51
                                  Copyright (c) 2009 Chris Richardson. All rights reserved.
Selecting files to upload
        g           p
 private var myFileReference:FileReferenceList = new FileReferenceList();

  [Bindable]
 private var photosToUpload : Array;

 private function selectFiles():void {
  myFileReference.addEventListener(quot;selectquot;, selectHandler);
  myFileReference.browse();
 }

 private function selectHandler(event:Event):void {
   photosToUpload = myFileReference.fileList.slice();
   enableDisableCreateButton();
 }

 private function enableDisableCreateButton() : void {
   createButton.enabled = titl V lid t
       t B tt       bl d   titleValidator.validate().type ! quot;invalidquot;
                                            lid t () t    != quot;i  lidquot;
        && dateValidator.validate().type != quot;invalidquot; && filesSupplied()
 }

 p
 private function filesSupplied() : Boolean {
                         pp    ()
   return photosToUpload != null && photosToUpload.length > 0
 }

                                                                                       Slide 52
                           Copyright (c) 2009 Chris Richardson. All rights reserved.
Displaying progress and
dispatching Cairngorm event
   p      g      g
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:TitleWindow>
 <mx:Script>
  <![CDATA[
   private var uploadProgressWindow : PhotoUploadProgressWindow;

   private function createAlbum(event:Event) : void {
     uploadProgressWindow =
                   PhotoUploadProgressWindow(PopUpManager.createPopUp(this,
                                               PhotoUploadProgressWindow, true));
     PopUpManager.centerPopUp(uploadProgressWindow);
     var ev : C
              CreateAlbumEvent = new C
                   t Alb  E   t       CreateAlbumEvent()
                                          t Alb    E   t()
     ev.album = new Album(albumTitle.text, notes.text, date.selectedDate)
     ev.photosToUpload = photosToUpload
     ev.dispatch()
   }

</mx:Script>

</mx:TitleWindow>




                                                                                       Slide 53
                           Copyright (c) 2009 Chris Richardson. All rights reserved.
Uploading a file
 p      g
public class CreateAlbumDelegate
 {
   var photo : FileReference;

    public function notePhotoAdded(photoId : String) : void {
      …
      photoIndex = photoIndex + 1;
      var ur : URLRequest = new URLRequest();
      ur.url = Env.getRootUrl() + quot;api/album/quot; + album.id + quot;/photo/quot; +
                      p
                      photoId;
                             ;
      this.photo.addEventListener(Event.COMPLETE, completeHandler);
      this.photo.upload(ur, quot;photoquot;);
    }

    public function completeHandler(event: Event) : void { … }

}




                                                                                      Slide 54
                          Copyright (c) 2009 Chris Richardson. All rights reserved.
CreateAlbumCommand
package net.chrisrichardson.cloudphotos.ui.command {

public class CreateAlbumCommand implements ICommand, IResponder
 {
    public function CreateAlbumCommand()  {}

    public function execute( event:CairngormEvent ):void {
      var delegate : CreateAlbumDelegate = new CreateAlbumDelegate(this);
      var album : Album = (event as CreateAlbumEvent).album
      var photosToUpload : Array = (event as CreateAlbumEvent).photosToUpload
      delegate.createAlbum(album, photosToUpload);
    }

                                                                                            Long running
    public function result( event : Object ):void {
     new AlbumCreatedEvent((event as Album).id).dispatch();
                                                                                            - publishes a
    }
                                                                                            Cairngorm
    public function fault( event : Object ) : void { … }
                                                                                            event when
                                                                                            finished
}



                                                                                                 Slide 55
                                Copyright (c) 2009 Chris Richardson. All rights reserved.
CreateAlbumPopup
             pp
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
                                                                                         View subscribes to
<mx:TitleWindow creationComplete=quot;creationComplete()quot;>
                                                                                         AlbumCreatedEvent –
 <mx:Script>
                                                                                         easier than binding to
  <![CDATA[
                                                                                         model
     private function creationComplete() : void {
       CairngormEventDispatcher.getInstance()
               .addEventListener(quot;albumCreatedquot;, albumCreated);
     }

      public function albumCreated(event : CairngormEvent) : void {
        PopUpManager.removePopUp(uploadProgressWindow);
        CloudPhotosModelLocator.getInstance().viewState = quot;displayAlbumquot;;
        new DisplayAlbumsEvent().dispatch();
        new DisplayAlbumEvent((event as AlbumCreatedEvent).albumId).dispatch();
        PopUpManager.removePopUp(this);
      }

}
     ]]>
    </mx:Script>
     /       p

</mx:TitleWindow>

                                                                                                      Slide 56
                             Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 O     i     f Fl
 Building Flex Applications
   The Cairngorm framework
   Cloud Photos Example Application
   Scenario: displaying albums
                pyg
   Scenario: creating a new album
   Scenario: copying photos between
   albums
 Pushing data to the client
 Building and testing Flex applications

                                                                         Slide 57
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Points of interest
  Uses drag and drop to copy a photo
  to an album




                                                                        Slide 58
            Copyright (c) 2009 Chris Richardson. All rights reserved.
Initiating a drag
         g      g
<mx:VBox width=quot;100quot; height=quot;175quot;>
  <mx:Script>
                                                                                      PhotoThumbnail.mxml
  <![CDATA[
   [Bindable]
   var photo : XML;

     private function mouseMoveHandler(event:MouseEvent):void {
         var dragInitiator:Image=Image(event.currentTarget);
         var ds:DragSource = new DragSource();
         ds.addData(photo.id, 'photoId');
         DragManager.doDrag(dragInitiator, ds, event);
     }

…
    ]]>
    </mx:Script>

    <mx:Image id=quot;imgquot; width=quot;100%quot; height=quot;100%quot;
               mouseMove=quot;mouseMoveHandler(event)quot;
               source=quot;{photo.thumbnail}quot;/>

</mx:VBox>


                                                                                                  Slide 59
                          Copyright (c) 2009 Chris Richardson. All rights reserved.
Handling a drop
       g      p
<mx:VBox width=quot;100quot; height=quot;175quot;>
  <mx:Script>
                                                                         AlbumSummaryThumbnail.mxml
                                                                                    y
  <![CDATA[
   [Bindable]
   [Bi d bl ]
   public var album : XML ;

    private function dragEnterHandler(event:DragEvent):void {
       if (event.dragSource.hasFormat('photoId')) {
           var dropTarget:Image=Image(event.currentTarget);
           DragManager.acceptDragDrop(dropTarget);
       }
    }

    private function dragDropHandler(event:DragEvent):void {
       var photoId : Object = event.dragSource.dataForFormat('photoId');
           p            j              g                     (p       );
       new CopyPhotoToAlbumEvent(album.id, String(photoId)).dispatch();
    }

  ]]>
  </mx:Script>

  <mx:Box width=quot;100quot; height=quot;125quot; verticalScrollPolicy=quot;offquot; horizontalScrollPolicy=quot;offquot;>
   <mx:Image dragEnter=quot;dragEnterHandler(event);quot; dragDrop=quot;dragDropHandler(event);quot;
         source=quot;{album.thumbnail}quot;/>
  </mx:Box>
  <mx:Text id=quot;titlequot; width=quot;100quot; height=quot;25quot; text=quot;{album.title}quot;/>

</mx:VBox>



                                                                                              Slide 60
                                  Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Developing Flex Applications
        pg         pp
 Pushing data to the client
 Building and testing Flex applications




                                                                        Slide 61
            Copyright (c) 2009 Chris Richardson. All rights reserved.
Why events?
  y
 Cloud Photos server asynchronously
 uploads photos to S3
 Client might display photo before it is
 available
                  ⇒
 Notify client when a photo is available
 Client can reload the image



                                                                        Slide 62
            Copyright (c) 2009 Chris Richardson. All rights reserved.
BlazeDS
 Open-source project
 Connects Flex and AIR clients to Java
 backend services
   Client-side Flex components
   Server-side components, E.g. Servlet
 RPC services
   Proxying for remote (web) services
   Invoke server-side Java object
 Publish-Subscribe messaging
   Supports integration with JMS
 Spring BlazeDS project for simplified
 development

                                                                         Slide 63
             Copyright (c) 2009 Chris Richardson. All rights reserved.
BlazeDS messaging components
             gg      p


Client                                  Server


                         receives
                       messages from                                                                       JMS Queue/
         Consumer                                   Destination                             Adapter
                                                                                                             Topic


                    using


         Channel                                      Endpoint
                        corresponds to
                                                  http://localhost:8080/webapp/messagebroker/amfpolling




                                                                                                          Slide 64
                                Copyright (c) 2009 Chris Richardson. All rights reserved.
Channel/Endpoint options
       /   p      p
 HTTP Options:
   Simple polling with piggyback
   Long polling – message/connection
   Streaming – many messages/connection
 Formats:
   AMF – efficient binary format
   AMFX – XML format




                                                                         Slide 65
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Example client-side consumer
    p
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<mx:Canvas creationComplete=quot;creationComplete()quot;>
  <mx:Script>
   <![CDATA[
    ![CDATA[
    public function creationComplete() : void { consumer.subscribe();}

   private function messageHandler(event:MessageEvent):void {
    for each (var photoThumbnail : PhotoThumbnail in thumbnailContainer.getChildren()) {
     photoThumbnail.reloadIfNecessary(event.message.body.toString());
    }
   }
                                                                                Server publishes a JMS event
                                                                                when it has uploaded an image
  ]]>
    </mx:Script>
                                                                                to S3.
                                                                                Client subscribes and reloads
  <mx:Consumer id=quot;consumerquot;
     destination=quot;message-destinationquot;
                                                                                images if required
     message=quot;messageHandler(event)quot; …/>

 <mx:Tile id=quot;thumbnailContainerquot; width=quot;100%quot; height=quot;90%quot;>
  <mx:Repeater id=quot;rpquot;
                 id rp
            dataProvider=quot;{CloudPhotosModelLocator.getInstance().currentAlbum.photos.photo}quot;>
   <components:PhotoThumbnail photo=quot;{rp.currentItem}quot;/>
  </mx:Repeater>
 </mx:Tile>

</mx:Canvas>




                                                                                                      Slide 66
                                   Copyright (c) 2009 Chris Richardson. All rights reserved.
Spring beans for messaging
     pg                   gg
<amq:topic id=quot;destinationquot;
 physicalName=quot;org.apache.activemq.spring.Test.spring.embeddedquot;/>

<bean id=quot;consumerJmsTemplatequot; class=quot;org.springframework.jms.core.JmsTemplatequot;>
 <property name=quot;connectionFactoryquot; ref=quot;jmsFactoryquot;/>
</bean>

<bean id=quot;producerquot;
       class=quot;net.chrisrichardson.kickstart.backend.services.SpringProducerquot;>
  <property name=quot;templatequot; ref=quot;myJmsTemplatequot;/>
  <property name=quot;destinationquot; ref=quot;destinationquot; />
 </bean>

public class SpringProducer {
 private JmsTemplate template;
 private Destination destination;

    public void send(String message) {
      template.convertAndSend(destination, message);
    }

}


                                                                                           Slide 67
                               Copyright (c) 2009 Chris Richardson. All rights reserved.
BlazeDS MessageBrokerServlet
             g
<servlet>
  <servlet-name>MessageBrokerServlet</servlet-name>
  <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
         l   l   fl         i                   kS     l  /   l    l
  <init-param>
         <param-name>services.configuration.file</param-name>
         <param-value>/WEB-INF/flex/services-config.xml</param-value>
  </init-param>
    /i i
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
     lt       i
     <servlet-name>MessageBrokerServlet</servlet-name>
     <url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>




                                                                                   Slide 68
                       Copyright (c) 2009 Chris Richardson. All rights reserved.
services-config.xml
              g
 Shared by client and server
 Messaging Service
   One or more adapters
   One or more destinations
   One or more channels
 Destinations
   Referenced by client
   Source/sink of messages
                        g
   Has an adapter, e.g. JMSAdapter
 Channels
   Used by a Flex component to communicate with the
   BlazeDS server
   Bl   DS
   Communicate with server-side endpoints
 Endpoints
   URLs that
   URL th t are mapped t M
                     d to MessageBroker servlet
                                 Bk         lt

                                                                            Slide 69
                Copyright (c) 2009 Chris Richardson. All rights reserved.
Channels and endpoints
                p
<services-config>

<channel-definition id quot;
  h      l d fi i i  id=quot;my-polling-amfquot;
                                lli   fquot;
      class=quot;mx.messaging.channels.AMFChannelquot;>
    <endpoint
      url=quot;http://localhost:8080/webapp/messagebroker/amfpollingquot;
      class=quot;flex.messaging.endpoints.AMFEndpointquot;/>
       l     quot;fl          i       di   AMFE d i quot;/
    <properties>
           <polling-enabled>true</polling-enabled>
           <polling-interval-seconds>4</polling-interval-seconds>
    </properties>
     /        ti
</channel-definition>


</services-config>
 /    i       fi




                                                                                   Slide 70
                       Copyright (c) 2009 Chris Richardson. All rights reserved.
Messaging service
     gg
<service id=quot;message-servicequot; class=quot;flex.messaging.services.MessageServicequot;>

 <adapters>
  <adapter-definition id=quot;actionscriptquot;
   class=quot;flex.messaging.services.messaging.adapters.ActionScriptAdapterquot;
   default=quot;truequot; />
  <adapter-definition id=quot;jmsquot;
   class=quot;flex.messaging.services.messaging.adapters.JMSAdapterquot; />
 </adapters>

 <default-channels>
  <channel ref=quot;my-polling-amfquot; />
            ref my polling amf
 </default-channels>

 <destination id=quot;message-destinationquot;>
  <properties>
   <jms>
     j
     <destination-jndi-name>topicjndiname</destination-jndi-name>
     …
   </jms>
  </properties>
    /p p
  <adapter ref=quot;jmsquot; />
 </destination>
</service>
                                                                                        Slide 71
                            Copyright (c) 2009 Chris Richardson. All rights reserved.
Agenda
 g
 The joy and pain of UI development
 Overview of Flex
 Developing Flex Applications
       pg          pp
 Pushing data to the client
 Building and testing Flex
 applications




                                                                       Slide 72
           Copyright (c) 2009 Chris Richardson. All rights reserved.
Using Flex Mojos
    g        j
 Open source project
 Maven Mojos for building and testing
 flex applications
 http://code.google.com/p/flex-mojos/
 Badly documented but they work
      y                    y




                                                                       Slide 73
           Copyright (c) 2009 Chris Richardson. All rights reserved.
Building a Flex client p j
       g               project
<project>
…
<pluginRepositories>
     <pluginRepository>
        l iR       i
        <id>pia-repository</id>
        <url>http://repository.sonatype.org/content/groups/flexgroup/</url>
     </pluginRepository>
 </pluginRepositories>
 <dependencies>
  <dependency>
    <groupId>cairngorm</groupId>
                                                                    “mvn install” builds SWF
     <artifactId>cairngorm</artifactId>
     <version>2_2_1</version>
     <type>swc</type>
     </dependency>
       /p         y
</dependencies>
<build>
  <sourceDirectory>src</sourceDirectory>
  <plugins>
    <plugin>
     <groupId>info.flex mojos</groupId>
     <groupId>info.flex-mojos</groupId>
     <artifactId>flex-compiler-mojo</artifactId>
  </plugin>
  ….
  </plugins>
 </build>
</project>




                                                                                                Slide 74
                                    Copyright (c) 2009 Chris Richardson. All rights reserved.
Adding the SWF to y
     g            your WAR
<project>
<packaging>war</packaging>
…
<dependencies>
  d    d    i
  <dependency>
     <groupId>net.chrisrichardson</groupId>
     <artifactId>kickstart-webapp</artifactId>
                                                   Input = SWF + Existing WAR file
     <version>1.0-SNAPSHOT</version>
     <type>war</type>
                                                   Output = new WAR file containing         SWF
    </dependency>
    <dependency>
     <groupId>net.chrisrichardson</groupId>
     <artifactId>photoflexui</artifactId>
     <version>1.0-SNAPSHOT</version>
     <type>swf</type>
       yp        / yp
    </dependency>
</dependencies>
 <build>
  <plugins>
     <plugin>
      <groupId>org.sonatype.flexmojos</groupId>
      <artifactId>flexmojos-maven-plugin</artifactId>
      <executions>
        <execution>
         <goals><goal>copy-flex-resources</goal></goals>
        </execution>
      </executions>
     </plugin>
…


                                                                                          Slide 75
                              Copyright (c) 2009 Chris Richardson. All rights reserved.
Automated testing
                g
 $$: HP QTP, RIATest
 FlexUnit
   Focused on unit tests
   Record UI tests with FlexMonkey
   Encountered a licensing error during
   compilation!
 Fluint
   Supposedly better than FlexUnit
   Not supported by Flex Mojos


                                                                         Slide 76
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Selenium-Flex
 Looks the most familiar/promising
   selenium.flexClick()
   selenium flexClick()
   selenium.flexWaitForElement()
   …
 Selenium extensions invoke ActionScript
 functions via External interface
 Include SeleniumFlexAPI.swc in your
 application
 External interface seems not to work in IE6
 Tricky to get working in FireFox
      y    g         g
   Launching SeleniumServer via Java API didn’t
   work – extensions not loaded
   maven-selenium-plugin worked
                   pg

                                                                          Slide 77
              Copyright (c) 2009 Chris Richardson. All rights reserved.
Example Selenium-Flex test
    p
public class WebIntegrationTest extends TestCase {

@Override
protected void setUp() throws Exception {
  selenium = new DefaultSeleniumFlex(quot;localhostquot;, 4444, browserType,
     quot;http://localhost:8080quot;);
  selenium.start();
}


    public void test() throws Exception {
     selenium.open(quot;http://localhost:8080/webapp/photoflexui.htmlquot;);
     waitForFlexApplicationToLoad(quot;createAlbumButtonquot;);

        selenium.flexWaitForElement(quot;albumThumbnail[1]quot;);
        selenium.flexClick(quot;albumThumbnail[1]quot;);

        selenium.flexWaitForElementVisible(quot;backToAlbumsButtonquot;);
        selenium.flexClick( backToAlbumsButtons );
        selenium flexClick(quot;backToAlbumsButtonsquot;);

        selenium.flexWaitForElementVisible(quot;createAlbumButtonquot;);
        selenium.flexClick(quot;createAlbumButtonquot;);
    }

}



                                                                                                  Slide 78
                                      Copyright (c) 2009 Chris Richardson. All rights reserved.
My next steps
 y         p
 Write some automated tests
 Investigate Spring ActionScript
   Dependency injection framework
   Promotes loose coupling
   “Inject stubs for services”
 Investigate ExternalInterface
   ActionScript                JavaScript




                                                                         Slide 79
             Copyright (c) 2009 Chris Richardson. All rights reserved.
Summary

Flex                                             HTML/Javascript/CSS
                                                                p
   Better paradigm                                 (Open-source) testing
                                                   tools are more
   Easier to develop
                                                   mature




                                                                             Slide 80
                 Copyright (c) 2009 Chris Richardson. All rights reserved.
Final thoughts
          g
                                        Download or contribute to Cloud
                                        Tools today :
                                                  y
                                             www.cloudtools.org
                                        Checkout Cloud Foundry:
                                             www.cloudfoundry.com
                                             www cloudfoundry com
                                        Buy my book ☺
                                        Send email:
                                             chris@chrisrichardson.net
                                        Visit my website:
                                             www.chrisrichardson.net
                                        Talk to me about consulting and
                                        training
                                             Phone: 510 904 9832



                                                                       Slide 81
          Copyright (c) 2009 Chris Richardson. All rights reserved.
Resources
 http://www.actionscript.org/
 http://www.adobe.com/devnet/actionscript/articl
 es/actionscript3_overview.html
 http://www.adobe.com/devnet/flex/
 http://www.adobe.com/devnet/flash/
 http://www.infoq.com/articles/java-flex-blazeds
 Intro link:
 http://www.adobe.com/devnet/flex/articles/intro
 ducing_cairngorm.html
 http://dispatchevent.org/roger/as3-e4x-
 rundown/  /
 http://myflex.org/presentations/ComparingFlexFr
 ameworks.pdf
 http://code.google.com/p/flexlib/
    p //     gg         /p/      /

                                                                          Slide 82
              Copyright (c) 2009 Chris Richardson. All rights reserved.

Weitere ähnliche Inhalte

Was ist angesagt?

Building a right sized, do-anything runtime using OSGi technologies: a case s...
Building a right sized, do-anything runtime using OSGi technologies: a case s...Building a right sized, do-anything runtime using OSGi technologies: a case s...
Building a right sized, do-anything runtime using OSGi technologies: a case s...mfrancis
 
DrupalCamp ATL 2010: Not all CMSs are created equal
DrupalCamp ATL 2010: Not all CMSs are created equalDrupalCamp ATL 2010: Not all CMSs are created equal
DrupalCamp ATL 2010: Not all CMSs are created equalandrewmriley
 
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012Alexandre Morgaut
 
Nads & presagis teaming to innovate in distributed simulation xx
Nads & presagis teaming to innovate in distributed simulation xxNads & presagis teaming to innovate in distributed simulation xx
Nads & presagis teaming to innovate in distributed simulation xxSimware
 
Extending Titanium with native iOS and Android modules
Extending Titanium with native iOS and Android modules Extending Titanium with native iOS and Android modules
Extending Titanium with native iOS and Android modules omorandi
 

Was ist angesagt? (14)

Introduction inbox v2.0
Introduction inbox v2.0Introduction inbox v2.0
Introduction inbox v2.0
 
Building a right sized, do-anything runtime using OSGi technologies: a case s...
Building a right sized, do-anything runtime using OSGi technologies: a case s...Building a right sized, do-anything runtime using OSGi technologies: a case s...
Building a right sized, do-anything runtime using OSGi technologies: a case s...
 
Issue3 07 2008
Issue3 07 2008Issue3 07 2008
Issue3 07 2008
 
Issue2 06 2008
Issue2 06 2008Issue2 06 2008
Issue2 06 2008
 
DrupalCamp ATL 2010: Not all CMSs are created equal
DrupalCamp ATL 2010: Not all CMSs are created equalDrupalCamp ATL 2010: Not all CMSs are created equal
DrupalCamp ATL 2010: Not all CMSs are created equal
 
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
 
Ibm blade center
Ibm blade centerIbm blade center
Ibm blade center
 
Issue6 10 2008
Issue6 10 2008Issue6 10 2008
Issue6 10 2008
 
Issue5 09 2008
Issue5 09 2008Issue5 09 2008
Issue5 09 2008
 
Issue4 08 2008
Issue4 08 2008Issue4 08 2008
Issue4 08 2008
 
Nads & presagis teaming to innovate in distributed simulation xx
Nads & presagis teaming to innovate in distributed simulation xxNads & presagis teaming to innovate in distributed simulation xx
Nads & presagis teaming to innovate in distributed simulation xx
 
Extending Titanium with native iOS and Android modules
Extending Titanium with native iOS and Android modules Extending Titanium with native iOS and Android modules
Extending Titanium with native iOS and Android modules
 
Issue1 042008
Issue1 042008Issue1 042008
Issue1 042008
 
Issue7 11 2008
Issue7 11 2008Issue7 11 2008
Issue7 11 2008
 

Ähnlich wie Flex For Java Developers - SDForum Java SIG

Evolving Mobile Architectures
Evolving Mobile ArchitecturesEvolving Mobile Architectures
Evolving Mobile Architecturessgleadow
 
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...Chris Richardson
 
Cloud Foundry Demo SD Forum Cloud Sig Feb09
Cloud Foundry Demo SD Forum Cloud Sig Feb09Cloud Foundry Demo SD Forum Cloud Sig Feb09
Cloud Foundry Demo SD Forum Cloud Sig Feb09Chris Richardson
 
Inspiration Tour - Microsoft Silverlight
Inspiration Tour - Microsoft SilverlightInspiration Tour - Microsoft Silverlight
Inspiration Tour - Microsoft SilverlightPaolo Barone
 
SD Forum Java SIG - Running Java Applications On Amazon EC2
SD Forum Java SIG - Running Java Applications On Amazon EC2SD Forum Java SIG - Running Java Applications On Amazon EC2
SD Forum Java SIG - Running Java Applications On Amazon EC2Chris Richardson
 
CommunityOneEast 09 - Running Java On Amazon EC2
CommunityOneEast 09 - Running Java On Amazon EC2CommunityOneEast 09 - Running Java On Amazon EC2
CommunityOneEast 09 - Running Java On Amazon EC2Chris Richardson
 
Kann JavaScript elegant sein?
Kann JavaScript elegant sein?Kann JavaScript elegant sein?
Kann JavaScript elegant sein?jbandi
 
Comparing JVM Web Frameworks - Rich Web Experience 2010
Comparing JVM Web Frameworks - Rich Web Experience 2010Comparing JVM Web Frameworks - Rich Web Experience 2010
Comparing JVM Web Frameworks - Rich Web Experience 2010Matt Raible
 
Why You Need a Front End Developer
Why You Need a Front End DeveloperWhy You Need a Front End Developer
Why You Need a Front End DeveloperMike Wilcox
 
Prototyping Adobe AIR Applications with Fireworks CS4
Prototyping Adobe AIR Applications with Fireworks CS4Prototyping Adobe AIR Applications with Fireworks CS4
Prototyping Adobe AIR Applications with Fireworks CS4Juan Sanchez
 
Flex For Java Architects Ledroff Breizh Jug V Blog Cc
Flex For Java Architects Ledroff Breizh Jug V Blog CcFlex For Java Architects Ledroff Breizh Jug V Blog Cc
Flex For Java Architects Ledroff Breizh Jug V Blog CcFrançois Le Droff
 
Optimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMOptimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMGabriel Walt
 
10 things ever architect should know about the Windows Azure Platform - ericnel
10 things ever architect should know about the Windows Azure Platform -  ericnel10 things ever architect should know about the Windows Azure Platform -  ericnel
10 things ever architect should know about the Windows Azure Platform - ericnelEric Nelson
 
Spring into the Cloud - JDC2012 Cairo, Egypt
Spring into the Cloud - JDC2012 Cairo, EgyptSpring into the Cloud - JDC2012 Cairo, Egypt
Spring into the Cloud - JDC2012 Cairo, EgyptChris Richardson
 
Enterprise Mashups With Soa
Enterprise Mashups With SoaEnterprise Mashups With Soa
Enterprise Mashups With Soaumityalcinalp
 

Ähnlich wie Flex For Java Developers - SDForum Java SIG (20)

Evolving Mobile Architectures
Evolving Mobile ArchitecturesEvolving Mobile Architectures
Evolving Mobile Architectures
 
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
 
Cloud Foundry Demo SD Forum Cloud Sig Feb09
Cloud Foundry Demo SD Forum Cloud Sig Feb09Cloud Foundry Demo SD Forum Cloud Sig Feb09
Cloud Foundry Demo SD Forum Cloud Sig Feb09
 
Inspiration Tour - Microsoft Silverlight
Inspiration Tour - Microsoft SilverlightInspiration Tour - Microsoft Silverlight
Inspiration Tour - Microsoft Silverlight
 
SD Forum Java SIG - Running Java Applications On Amazon EC2
SD Forum Java SIG - Running Java Applications On Amazon EC2SD Forum Java SIG - Running Java Applications On Amazon EC2
SD Forum Java SIG - Running Java Applications On Amazon EC2
 
CommunityOneEast 09 - Running Java On Amazon EC2
CommunityOneEast 09 - Running Java On Amazon EC2CommunityOneEast 09 - Running Java On Amazon EC2
CommunityOneEast 09 - Running Java On Amazon EC2
 
Kann JavaScript elegant sein?
Kann JavaScript elegant sein?Kann JavaScript elegant sein?
Kann JavaScript elegant sein?
 
Comparing JVM Web Frameworks - Rich Web Experience 2010
Comparing JVM Web Frameworks - Rich Web Experience 2010Comparing JVM Web Frameworks - Rich Web Experience 2010
Comparing JVM Web Frameworks - Rich Web Experience 2010
 
Why You Need a Front End Developer
Why You Need a Front End DeveloperWhy You Need a Front End Developer
Why You Need a Front End Developer
 
Js il.com
Js il.comJs il.com
Js il.com
 
Ruby at UW C4C
Ruby at UW C4CRuby at UW C4C
Ruby at UW C4C
 
Prototyping Adobe AIR Applications with Fireworks CS4
Prototyping Adobe AIR Applications with Fireworks CS4Prototyping Adobe AIR Applications with Fireworks CS4
Prototyping Adobe AIR Applications with Fireworks CS4
 
Dmeeker Finala
Dmeeker FinalaDmeeker Finala
Dmeeker Finala
 
Web summit.pptx
Web summit.pptxWeb summit.pptx
Web summit.pptx
 
Flex For Java Architects Ledroff Breizh Jug V Blog Cc
Flex For Java Architects Ledroff Breizh Jug V Blog CcFlex For Java Architects Ledroff Breizh Jug V Blog Cc
Flex For Java Architects Ledroff Breizh Jug V Blog Cc
 
Optimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMOptimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEM
 
10 things ever architect should know about the Windows Azure Platform - ericnel
10 things ever architect should know about the Windows Azure Platform -  ericnel10 things ever architect should know about the Windows Azure Platform -  ericnel
10 things ever architect should know about the Windows Azure Platform - ericnel
 
Spring into the Cloud - JDC2012 Cairo, Egypt
Spring into the Cloud - JDC2012 Cairo, EgyptSpring into the Cloud - JDC2012 Cairo, Egypt
Spring into the Cloud - JDC2012 Cairo, Egypt
 
Silverlight
SilverlightSilverlight
Silverlight
 
Enterprise Mashups With Soa
Enterprise Mashups With SoaEnterprise Mashups With Soa
Enterprise Mashups With Soa
 

Mehr von Chris Richardson

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?Chris Richardson
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternChris Richardson
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...Chris Richardson
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Chris Richardson
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsChris Richardson
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfChris Richardson
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Chris Richardson
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...Chris Richardson
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Chris Richardson
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 Chris Richardson
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureChris Richardson
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Chris Richardson
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled servicesChris Richardson
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Chris Richardson
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...Chris Richardson
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Chris Richardson
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...Chris Richardson
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationChris Richardson
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate PlatformChris Richardson
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolithChris Richardson
 

Mehr von Chris Richardson (20)

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-pattern
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patterns
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled services
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders application
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate Platform
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith
 

Kürzlich hochgeladen

Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 

Kürzlich hochgeladen (20)

Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 

Flex For Java Developers - SDForum Java SIG

  • 1. Flex for Java developers: My quest for pain-free UI development Chris Richardson Author of POJOs in Action www.chrisrichardson.net chris@chrisrichardson.net @crichardson Cinco de Mayo 2009
  • 2. About Chris Grew up in England and live in Oakland • Over 20+ years of software • development experience including 12 years of Java Started Java architecture consulting • company and sold it to BEA Speaker at JavaOne, SpringOne, etc. • Java Champion • Run a consulting and training company • that helps organizations reduce g development costs and i d l d increase effectiveness cloudtools.org www.cloudfoundry.com Slide 2 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 3. Agenda g The joy and pain of UI development Overview of Flex Developing Flex Applications Pushing data to the client g Building and testing Flex applications Slide 3 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 4. Arms race: Frameworks vs. UI complexity p y 1998 1998- 2000 2000- 2002 2002- 2005 2005- 2007 2008 1999 2002 2005 2006 Really Really More More More simply Simple Complex Complex complex Rich UIs pages Pages Pages Pages pages Home Spring Spring grown MVC Struts Struts Spring MVC/Web frame 1.0 1.0 MVC WebFlow Flow work Dojo /☺ ☺ Slide 4 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 5. Cloud Foundry y Slide 5
  • 6. Cloud Foundry UI y Single page application Dojo toolkit Uses DWR to push events to browser p End result is quite nice But getting there was painful Slide 6 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 7. Why is building RIAs so painful? y g p Open-source JavaScript projects Variable quality q y Some are poorly documented Built on a shaky foundation of web technologies JavaScript p Dynamic ⇒ limited IDE support Prototype-based ⇒ simulated classes No packages ⇒ build your own … CSS layout Difficult to learn Relies on “hacks” to accomplish basic layout tasks Lack of portability across browsers Easier to use tables? Numerous b N browser incompatibilities i tibiliti Slide 7 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 8. Today's web = multi-layer hack y y Was – a straightforward Hacks to enable offline hypertext browsing system applications Now – an application … delivery platform Fake class system ⇒Time for a Javascript change Hypertext Slide 8 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 9. GWT is an option p Treats JavaScript as the runtime environment Develop and debug in Java quot;Swing-stylequot; programming model But my social network liked Flex … Slide 9 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 10. So I downloaded Flex Builder and wrote some Flex code… d l d Slide 10 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 11. Agenda g The joy and pain of UI development Overview of Flex Developing Flex Applications pg pp Pushing data to the client Building and testing Flex applications Slide 11 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 12. What is Flex? Open-source framework for building Rich Internet Applications Current version is Flex 3 (Flex 4 in 4Q09) Flex apps run on the ubiquitous Flash pp q player In the browser On the desktop with Adobe AIR Excellent documentation Develop applications in MXML – declaratively define UI ActionScript 3 – handle events, invoke backend services, dynamically construct UI ,y y Slide 12 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 13. ActionScript 3 – the scripting language for the Flash p y gg player Class-based, object-oriented language Compile-time type checking Packages Dynamic vs. sealed classes Dynamic – add properties/methods at runtime ti Method closures High Hi h performance AVM2 with JIT f ith compiler Dialect Di le t of ECMAS ipt (like J ECMAScript JavaScript) S ipt) Slide 13 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 14. ActionScript XML support ( p pp (E4X) ) var x : XML = <createAlbumRequest> <title>{title}</title> var albums : XML = <albums> <album> <creationDate> <id>id1</id> {creationDate.time} <title>t1</title> / </creationDate> <thumbnail>xyz<thumbnail> <notes>{notes}</notes> </album> <album> </createAlbumRequest> <id>id2</id> <title>t2</title> <thumbnail>abc</thumbnail> var title : String = x.title; </album> var notes : String = x.notes; ….. </albums> var notes : XMLList = albums.album.notes var albums2: XMLList = ablums.album.(title = “t1”) Slide 14 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 15. Comprehensive component library p p y Components have properties and methods generate events Visual components Controls: Button, TextField, … Container: TabContainer, Form, Box, … Can be styled with CSS Non-Visual Data access components, e.g. HTTP, Web Services Validators Formatters Slide 15 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 16. Declaratively define UI in MXML y <mx:Application > <mx:Form> <mx:FormItem label=quot;Symbolquot; fontWeight=quot;boldquot;> label= Symbol fontWeight= bold > <mx:TextInput id=quot;symbolquot; text=quot;AAPLquot; fontWeight=quot;normalquot;/> </mx:FormItem> <mx:FormItem label=quot;quot;> <mx:Button label=quot;Get Quotequot; click=quot;handleClick(event)quot;/> </mx:FormItem> / </mx:Form> <mx:DataGrid dataProvider=quot;{quotes}quot; width=quot;100%quot;> <mx:columns> <mx:DataGridColumn headerText=quot;Symbolquot; dataField=quot;symbolquot;/> <mx:DataGridColumn headerText=quot;Pricequot; dataField=quot;pricequot;/> </mx:columns> / l </mx:DataGrid> </mx:Application> Equivalent to creating component tree in ActionScript Slide 16 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 17. Events Components generate events Handled by ActionScript code <mx:Button l b l quot;G t Q t quot; click=quot;handleClick(event)quot;/> < B tt label=quot;Get Quotequot; li k quot;h dl Cli k( t)quot;/> private function handleClick(event :Event) : void { … } Slide 17 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 18. Data Binding g Control is updated whenever variable changes [Bindable] private var quotes : Array = []; <mx:DataGrid dataProvider=quot;{quotes}quot; width=quot;100%quot;> dataProvider= {quotes} width= 100% > <mx:columns> <mx:DataGridColumn headerText=quot;Symbolquot; dataField=quot;symbolquot;/> <mx:DataGridColumn headerText=quot;Pricequot; dataField=quot;pricequot;/> </mx:columns> </mx:DataGrid> Slide 18 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 19. Custom components p Define <mx:GridItem > AlbumThumbnail.mxml <mx:Script> subclasses in <![CDATA[ [Bindable] MXML or public var album : XML; p public function viewAlbum() : void { ….} () } ActionScript A ti S i t ]]> </mx:Script> Use to <mx:VBox width=quot;100quot; height=quot;125quot;> modularize dl i <mx:Image id quot;i I id=quot;imgquot; click=quot;viewAlbum()quot; quot; li k quot; i Alb ()quot; source=quot;{album.thumbnail}quot; /> </mx:Box> application <mx:Text width=quot;100quot; height=quot;25quot; text=quot;{album.title}quot;/> 3rd party d </mx:VBox> components </mx:GridItem> <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/> Slide 19 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 20. Flex security sandbox y Uses the Flash Player security model By default, a Flex application can only access resources on the site that it was downloaded from Cross-domain policy files on remote server grants access to Flex applications from other domains Slide 20 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 21. Flex Tools from Adobe Flex SDK Free, open-source F Compilers and command-line debugger FlexBuilder – Cheap ($249) Eclipse-based IDE For Mac and Windows MXML and ActionScript editors – completion, renaming and validation Drag and drop UI builder Good debugging: breakpoints, Comprehensive h l C h i help Slide 21 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 22. Flex Stock Quote Demo Q Slide 22 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 23. Flex back-end integration g BlazeDS Open-source project O j Allows Flex clients to talk to server-side Java applications RPC Server-push over HTTP p LiveCycle Data Services ES Commercial Superset of BlazeDS More scalable Client/Server d t synchronization Cli t/S data h i ti Slide 23 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 24. Flex Application Architecture pp Blaze DS SOFEA = Service-Oriented Front-End Architecture Service Oriented Front End Slide 24 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 25. Agenda g The joy and pain of UI development Overview of Flex Building Flex Applications The Cairngorm framework Cloud Photos Example Application Scenario: displaying albums S i di l i lb Scenario: creating a new album Scenario: copying photos between albums Pushing data to the client Building and testing Flex applications Slide 25 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 26. Tangled code g <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; layout=quot;absolutequot; implements=quot;mx.rpc.IResponderquot; backgroundColor=quot;#ffffffquot;> <mx:Script> Data [Bindable] private var quote : String; private function handleClick(event :Event) : void { var service : HTTPService = new HTTPService(); Data … Access } Logic public function result(data:Object):void { …. } p public function fault(info:Object):void { } ( j ) ]]> </mx:Script> <mx:VDividedBox width=quot;414quot; height=quot;217quot; Presentation logic …. </mx:VDividedBox> </mx:Application> Slide 26 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 27. Cairngorm framework g MVC framework for Flex Model – data View – Flex components that display the model (through binding) Controller – implements quot;business logicquot; logicquot;, i.e. accessing backend services and update the model Encourages: Separation of concerns Separation of development roles: front-end and b k d back-endd Avoids big ball of mud An alternative is PureMVC Slide 27 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 28. Cairngorm classes and roles g Views Display the model The code has a cookie- ModelLocator cutter feel to it but I Provides access to the model like the structure “Business” Events Generated by Views Front Controller Routes events to Commands Commands Handle events Contain quot;business logicquot;/data access logic g/ g Invoke delegates Delegates Proxy for remote services Contract between front-end and back-end team Calls b k t C ll back to command d ServiceLocator Centralized registry of (supposedly) all data access components Used by delegates Slide 28 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 29. Cairngorm flow g Slide 29 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 30. Agenda g The joy and pain of UI development Overview of Flex Building Flex Applications The Cairngorm framework Cloud Photos Example Application Scenario: displaying albums S i di l i lb Scenario: creating a new album Scenario: copying photos between albums Pushing data to the client Building and testing Flex applications Slide 30 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 31. Cloud Photos Application pp Tomcat RESTful web services Flex Client Scala/Spring MVC /p g Events Java/Spring/JMS Manage your photos online Upload and p view photos Simple DB Organize S3 photos into Amazon Web Services albums … Slide 31 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 32. Cloud Photos – screenshots Slide 32 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 33. Cloud Photo – web services http://localhost:8080/webapp/api/album <albums> <album> <id>e778769a-8432-46ca-b0f1-5c92f33a8710</id> <title>Pictures of kids</title> <thumbnail>https://s3.amazonaws.com/…</thumbnail> </album> / <album> <id>1ff7528a-65aa-4300-a5bb-c5b7e6eba985</id> <title>Some birds</title> <thumbnail>https://s3.amazonaws.com…</thumbnail> p // / </album> ….. </albums> Slide 33 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 34. Application structure pp Slide 34 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 35. Model – a Singleton g package net.chrisrichardson.cloudphotos.ui.model { import com.adobe.cairngorm.model.IModelLocator; Metadata tag enables binding for all public properties [Bindable] public class CloudPhotosModelLocator implements IModelLocator { private static var modelLocator:CloudPhotosModelLocator; public var viewState : String = quot;displayAlbumsquot;; public var albums : XMLList; public var currentAlbum : XML bli tAlb XML; public static function getInstance():CloudPhotosModelLocator{ if (modelLocator == null) { Singleton modelLocator = new CloudPhotosModelLocator();(); } return modelLocator; } } } Slide 35 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 36. View - Main application pp <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Application layout=quot;verticalquot; layout vertical xmlns:ns1=quot;net.chrisrichardson.cloudphotos.ui.components.*quot; xmlns:control=quot;net.chrisrichardson.cloudphotos.ui.control.*quot; xmlns:business=quot;net.chrisrichardson.cloudphotos.ui.business.*quot; width=quot;100%quot; height=quot;100%quot;> idth quot;100%quot; h i ht quot;100%quot; <business:Services id=quot;servicesquot; /> bus ess Se ces d se ces / <control:Controller id=quot;controllerquot; /> <mx:Label text=quot;Cloud Photosquot; fontSize=quot;33quot;/> <ns1:HomePage width=quot;100%quot; height=quot;100%quot;> width quot;100%quot; height quot;100%quot;> </ns1:HomePage> </mx:Application> Slide 36 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 37. View - HomePage g <mx:Vbox …> <mx:Binding destination=quot;currentStatequot; destination currentState source=quot;{CloudPhotosModelLocator.getInstance().viewState}quot;/> <mx:states> <mx:State name=quot;displayAlbumsquot;> <mx:SetProperty name=quot;selectedIndexquot; target=quot;{viewStack}quot; value=quot;{0}quot;/> </mx:State> <mx:State name=quot;displayAlbumquot;> <mx:SetProperty name=quot;selectedIndexquot; target=quot;{viewStack}quot; value=quot;{1}quot;/> </mx:State> </mx:states> <mx:TabNavigator id=quot;tabNavigatorquot; …> id= tabNavigator > <mx:ViewStack id=quot;viewStackquot; width=quot;100%quot; height=quot;100%quot; label=quot;My Albumsquot; > <components:AlbumList id=quot;albumListquot; width=quot;100%quot; height=quot;100%“/> <components:AlbumView id=quot;albumViewquot; width=quot;100%quot; height=quot;100%“/> </mx:ViewStack> … </mx:TabNavigator> CloudPhotosModelLocator.getInstance().viewState </mx:VBox> determines whether we are viewing albums or an album Slide 37 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 38. Agenda g The joy and pain of UI development Overview of Flex Building Flex Applications The Cairngorm framework Cloud Photos Example Application Scenario: di l i S i displaying albums lb Scenario: creating a new album Scenario: copying photos between albums Pushing data to the client Building and testing Flex applications Slide 38 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 39. Display Albums Flow py Slide 39 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 40. View dispatches event p <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Vbox … creationComplete=quot;displayAlbums()quot;> <mx:Script> <![CDATA[ private function displayAlbums():void { var event : DisplayAlbumsEvent = new DisplayAlbumsEvent(); event.dispatch(); } private function createAlbum() : void { PopUpManager.centerPopUp(PopUpManager.createPopUp(this, CreateAlbumPopup, true)); } ]]> </mx:Script> <mx:HBox width=quot;100%quot; height=quot;10%quot;> <mx:Button label=quot;Create Newquot; click=quot;createAlbum()quot;/> </mx:HBox> <mx:Tile id=quot;albumGridquot; width=quot;100%quot; height=quot;90%quot;> <mx:Repeater id quot; quot; d t P R t id=quot;rpquot; dataProvider=quot;{CloudPhotosModelLocator.getInstance().albums}quot;> id quot;{Cl dPh t M d lL t tI t () lb }quot; <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/> </mx:Repeater> </mx:Tile> </mx:VBox> Slide 40 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 41. Controller executes command package net.chrisrichardson.cloudphotos.ui.control { import com.adobe.cairngorm.control.FrontController; import net.chrisrichardson.cloudphotos.ui.command.*; import net.chrisrichardson.cloudphotos.ui.event.*; public class Controller extends FrontController { public function Controller() { initializeCommands(); } public function initializeCommands() : void { addCommand( CreateAlbumEvent.CREATE_ALBUM, CreateAlbumCommand); addCommand( DisplayAlbumsEvent.DISPLAY_ALBUMS, DisplayAlbumsCommand); addCommand( DisplayAlbumEvent.DISPLAY_ALBUM, DisplayAlbumCommand); addCommand( CopyPhotoToAlbumEvent.COPY_PHOTO, CopyPhotoToAlbumCommand); } } } Slide 41 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 42. Command calls delegate g public class DisplayAlbumsCommand implements ICommand, IResponder { public function execute( event:CairngormEvent ):void { var delegate : DisplayAlbumsDelegate = new DisplayAlbumsDelegate(this); delegate.displayAlbums(); } public function result( event : Object ):void { var albums : XMLList = event.result.album; var model : Cl dPh t M d lL d l CloudPhotosModelLocator = Cl dPh t M d lL t CloudPhotosModelLocator.getInstance(); t tI t () model.albums = albums } p public function fault( event : Object ) : void { ( j // handle error } } Slide 42 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 43. Delegate invokes service g public class DisplayAlbumsDelegate { private var responder : IResponder; private var service : HTTPService; public function DisplayAlbumsDelegate( responder : IResponder ) { this.service = ServiceLocator.getInstance().getHTTPService( quot;displayAlbumsquot; ); displayAlbums this.responder = responder; } public function displayAlbums() : void { var call : Obj t = service.send() ll Object i d() call.addResponder(responder); } } Slide 43 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 44. Service definition <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <cairngorm:ServiceLocator xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; xmlns:cairngorm http://www.adobe.com/2006/cairngorm > xmlns:cairngorm=quot;http://www adobe com/2006/cairngormquot;> <mx:HTTPService id=quot;displayAlbumsquot; url=quot;http://.../api/albumquot; resultFormat=quot;e4xquot; ltF t quot;4quot; useProxy=quot;falsequot; method=quot;GETquot; > </mx:HTTPService> / </cairngorm:ServiceLocator> Slide 44 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 45. Command updates model p public class DisplayAlbumsCommand implements ICommand, IResponder { public function execute( event:CairngormEvent ):void { var delegate : DisplayAlbumsDelegate = new DisplayAlbumsDelegate(this); delegate.displayAlbums(); } public function result( event : Object ):void { var albums : XMLList = event.result.album; var model : Cl dPh t M d lL d l CloudPhotosModelLocator = Cl dPh t M d lL t CloudPhotosModelLocator.getInstance(); t tI t () model.albums = albums } p public function fault( event : Object ) : void { ( j <albums> // handle error <album>…</album> } <album>…</album> } … </albums> Slide 45 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 46. View displays model py <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Vbox … creationComplete=quot;displayAlbums()quot;> <mx:Script> <![CDATA[ private function displayAlbums():void { var event : DisplayAlbumsEvent = new DisplayAlbumsEvent(); event.dispatch(); } private function createAlbum() : void { PopUpManager.centerPopUp(PopUpManager.createPopUp(this, CreateAlbumPopup, true)); } ]]> </mx:Script> <mx:HBox width=quot;100%quot; height=quot;10%quot;> <mx:Button label=quot;Create Newquot; click=quot;createAlbum()quot;/> </mx:HBox> <mx:Tile id=quot;albumGridquot; width=quot;100%quot; height=quot;90%quot;> <mx:Repeater id quot; quot; d t P < R t id=quot;rpquot; dataProvider=quot;{CloudPhotosModelLocator.getInstance().albums}quot;> id quot;{Cl dPh t M d lL t tI t () lb }quot;> <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/> </mx:Repeater> </mx:Tile> </mx:VBox> Slide 46 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 47. View component p <album> <mx:GridItem > <id>e778769a-8432-46ca-b0f1-5c92f33a8710</id> <mx:Script> <title>Pictures of kids</title> / <thumbnail>https://s3.amazonaws.com/…</thumbnail> <![CDATA[ </album> [Bindable] public var album : XML; p public function viewAlbum() : void { () new DisplayAlbumEvent(album.id).dispatch(); CloudPhotosModelLocator.getInstance().viewState = quot;displayAlbumquot;; } ]]> </mx:Script> / S it <mx:Box width=quot;100quot; height=quot;125quot;> <mx:Image id=quot;imgquot; click=quot;viewAlbum()quot; source=quot;{album.thumbnail}quot; /> </mx:Box> <mx:Text width=quot;100quot; height= 25 text= {album.title} /> width= 100 height=quot;25quot; text=quot;{album title}quot;/> </mx:VBox> </mx:GridItem> Slide 47 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 48. Agenda g The joy and pain of UI development Overview of Flex Building Flex Applications The Cairngorm framework Cloud Photos Example Application Scenario: displaying albums S i di l i lb Scenario: creating a new album Scenario: copying photos between albums Pushing data to the client Building and testing Flex applications Slide 48 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 49. Points of interest Uses a popup window Uploads files Command publishes a Cairngorm p g event to notify view that upload is complete Slide 49 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 50. Displaying a popup window p y g ppp <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Vbox … creationComplete=quot;displayAlbums()quot;> <mx:Script> <![CDATA[ private function displayAlbums():void { var event : DisplayAlbumsEvent = new DisplayAlbumsEvent(); event.dispatch(); } private function createAlbum() : void { PopUpManager.centerPopUp(PopUpManager.createPopUp(this, CreateAlbumPopup, true)); } ]]> </mx:Script> <mx:HBox width=quot;100%quot; height=quot;10%quot;> <mx:Button label=quot;Create Newquot; click=quot;createAlbum()quot;/> </mx:HBox> <mx:Tile id=quot;albumGridquot; width=quot;100%quot; height=quot;90%quot;> <mx:Repeater id quot; quot; d t P R t id=quot;rpquot; dataProvider=quot;{CloudPhotosModelLocator.getInstance().albums}quot;> id quot;{Cl dPh t M d lL t tI t () lb }quot; <components:AlbumThumbnail album=quot;{rp.currentItem}quot;/> </mx:Repeater> </mx:Tile> </mx:VBox> Slide 50 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 51. CreateAlbum popup window ppp <mx:TitleWindow> <mx:Form width=quot;100%quot;> <mx:FormItem label=quot;Album Titlequot;> <mx:TextInput id quot; lb T I id=quot;albumTitlequot; change=quot;enableDisableCreateButton()quot;/> Ti l quot; h quot; bl Di bl C B ()quot;/ </mx:FormItem> <mx:FormItem label=quot;Album Datequot;> <mx:DateChooser id=quot;datequot; change=quot;enableDisableCreateButton()quot;/> </mx:FormItem> <mx:FormItem label=quot;Notesquot;> <mx:TextArea id=quot;notesquot;/> </mx:FormItem> <mx:FormItem label=quot;quot;> <mx:Button label=quot;Select Images...quot; click=quot;selectFiles()quot;/> </mx:FormItem> <mx:FormItem label=quot;quot;> <Form> provides <mx:Label text=quot;{photosToUpload.length} imagesquot;/> </mx:FormItem> / an easy way to <mx:FormItem label=quot;Selected Filesquot; width=quot;100%quot;> layout the form <mx:DataGrid dataProvider=quot;{photosToUpload}quot; width=quot;100%quot;> <mx:columns> fields <mx:DataGridColumn headerText=quot;Namequot; dataField=quot;namequot;/> <mx:DataGridColumn headerText=quot;Datequot; dataField=quot;creationDatequot;/> </mx:columns> </mx:DataGrid> </mx:FormItem> </mx:Form> <mx:ControlBar> <mx:Button id=quot;createButtonquot; label=quot;Create Album click= createAlbum(event) enabled= false /> id= createButton label= Create Albumquot; click=quot;createAlbum(event)quot; enabled=quot;falsequot;/> <mx:Button label=quot;Cancelquot; click=quot;cancelCreateAlbum()quot;/> </mx:ControlBar> </mx:TitleWindow> Slide 51 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 52. Selecting files to upload g p private var myFileReference:FileReferenceList = new FileReferenceList(); [Bindable] private var photosToUpload : Array; private function selectFiles():void { myFileReference.addEventListener(quot;selectquot;, selectHandler); myFileReference.browse(); } private function selectHandler(event:Event):void { photosToUpload = myFileReference.fileList.slice(); enableDisableCreateButton(); } private function enableDisableCreateButton() : void { createButton.enabled = titl V lid t t B tt bl d titleValidator.validate().type ! quot;invalidquot; lid t () t != quot;i lidquot; && dateValidator.validate().type != quot;invalidquot; && filesSupplied() } p private function filesSupplied() : Boolean { pp () return photosToUpload != null && photosToUpload.length > 0 } Slide 52 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 53. Displaying progress and dispatching Cairngorm event p g g <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:TitleWindow> <mx:Script> <![CDATA[ private var uploadProgressWindow : PhotoUploadProgressWindow; private function createAlbum(event:Event) : void { uploadProgressWindow = PhotoUploadProgressWindow(PopUpManager.createPopUp(this, PhotoUploadProgressWindow, true)); PopUpManager.centerPopUp(uploadProgressWindow); var ev : C CreateAlbumEvent = new C t Alb E t CreateAlbumEvent() t Alb E t() ev.album = new Album(albumTitle.text, notes.text, date.selectedDate) ev.photosToUpload = photosToUpload ev.dispatch() } </mx:Script> </mx:TitleWindow> Slide 53 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 54. Uploading a file p g public class CreateAlbumDelegate { var photo : FileReference; public function notePhotoAdded(photoId : String) : void { … photoIndex = photoIndex + 1; var ur : URLRequest = new URLRequest(); ur.url = Env.getRootUrl() + quot;api/album/quot; + album.id + quot;/photo/quot; + p photoId; ; this.photo.addEventListener(Event.COMPLETE, completeHandler); this.photo.upload(ur, quot;photoquot;); } public function completeHandler(event: Event) : void { … } } Slide 54 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 55. CreateAlbumCommand package net.chrisrichardson.cloudphotos.ui.command { public class CreateAlbumCommand implements ICommand, IResponder { public function CreateAlbumCommand() {} public function execute( event:CairngormEvent ):void { var delegate : CreateAlbumDelegate = new CreateAlbumDelegate(this); var album : Album = (event as CreateAlbumEvent).album var photosToUpload : Array = (event as CreateAlbumEvent).photosToUpload delegate.createAlbum(album, photosToUpload); } Long running public function result( event : Object ):void { new AlbumCreatedEvent((event as Album).id).dispatch(); - publishes a } Cairngorm public function fault( event : Object ) : void { … } event when finished } Slide 55 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 56. CreateAlbumPopup pp <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> View subscribes to <mx:TitleWindow creationComplete=quot;creationComplete()quot;> AlbumCreatedEvent – <mx:Script> easier than binding to <![CDATA[ model private function creationComplete() : void { CairngormEventDispatcher.getInstance() .addEventListener(quot;albumCreatedquot;, albumCreated); } public function albumCreated(event : CairngormEvent) : void { PopUpManager.removePopUp(uploadProgressWindow); CloudPhotosModelLocator.getInstance().viewState = quot;displayAlbumquot;; new DisplayAlbumsEvent().dispatch(); new DisplayAlbumEvent((event as AlbumCreatedEvent).albumId).dispatch(); PopUpManager.removePopUp(this); } } ]]> </mx:Script> / p </mx:TitleWindow> Slide 56 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 57. Agenda g The joy and pain of UI development Overview of Flex O i f Fl Building Flex Applications The Cairngorm framework Cloud Photos Example Application Scenario: displaying albums pyg Scenario: creating a new album Scenario: copying photos between albums Pushing data to the client Building and testing Flex applications Slide 57 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 58. Points of interest Uses drag and drop to copy a photo to an album Slide 58 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 59. Initiating a drag g g <mx:VBox width=quot;100quot; height=quot;175quot;> <mx:Script> PhotoThumbnail.mxml <![CDATA[ [Bindable] var photo : XML; private function mouseMoveHandler(event:MouseEvent):void { var dragInitiator:Image=Image(event.currentTarget); var ds:DragSource = new DragSource(); ds.addData(photo.id, 'photoId'); DragManager.doDrag(dragInitiator, ds, event); } … ]]> </mx:Script> <mx:Image id=quot;imgquot; width=quot;100%quot; height=quot;100%quot; mouseMove=quot;mouseMoveHandler(event)quot; source=quot;{photo.thumbnail}quot;/> </mx:VBox> Slide 59 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 60. Handling a drop g p <mx:VBox width=quot;100quot; height=quot;175quot;> <mx:Script> AlbumSummaryThumbnail.mxml y <![CDATA[ [Bindable] [Bi d bl ] public var album : XML ; private function dragEnterHandler(event:DragEvent):void { if (event.dragSource.hasFormat('photoId')) { var dropTarget:Image=Image(event.currentTarget); DragManager.acceptDragDrop(dropTarget); } } private function dragDropHandler(event:DragEvent):void { var photoId : Object = event.dragSource.dataForFormat('photoId'); p j g (p ); new CopyPhotoToAlbumEvent(album.id, String(photoId)).dispatch(); } ]]> </mx:Script> <mx:Box width=quot;100quot; height=quot;125quot; verticalScrollPolicy=quot;offquot; horizontalScrollPolicy=quot;offquot;> <mx:Image dragEnter=quot;dragEnterHandler(event);quot; dragDrop=quot;dragDropHandler(event);quot; source=quot;{album.thumbnail}quot;/> </mx:Box> <mx:Text id=quot;titlequot; width=quot;100quot; height=quot;25quot; text=quot;{album.title}quot;/> </mx:VBox> Slide 60 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 61. Agenda g The joy and pain of UI development Overview of Flex Developing Flex Applications pg pp Pushing data to the client Building and testing Flex applications Slide 61 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 62. Why events? y Cloud Photos server asynchronously uploads photos to S3 Client might display photo before it is available ⇒ Notify client when a photo is available Client can reload the image Slide 62 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 63. BlazeDS Open-source project Connects Flex and AIR clients to Java backend services Client-side Flex components Server-side components, E.g. Servlet RPC services Proxying for remote (web) services Invoke server-side Java object Publish-Subscribe messaging Supports integration with JMS Spring BlazeDS project for simplified development Slide 63 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 64. BlazeDS messaging components gg p Client Server receives messages from JMS Queue/ Consumer Destination Adapter Topic using Channel Endpoint corresponds to http://localhost:8080/webapp/messagebroker/amfpolling Slide 64 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 65. Channel/Endpoint options / p p HTTP Options: Simple polling with piggyback Long polling – message/connection Streaming – many messages/connection Formats: AMF – efficient binary format AMFX – XML format Slide 65 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 66. Example client-side consumer p <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Canvas creationComplete=quot;creationComplete()quot;> <mx:Script> <![CDATA[ ![CDATA[ public function creationComplete() : void { consumer.subscribe();} private function messageHandler(event:MessageEvent):void { for each (var photoThumbnail : PhotoThumbnail in thumbnailContainer.getChildren()) { photoThumbnail.reloadIfNecessary(event.message.body.toString()); } } Server publishes a JMS event when it has uploaded an image ]]> </mx:Script> to S3. Client subscribes and reloads <mx:Consumer id=quot;consumerquot; destination=quot;message-destinationquot; images if required message=quot;messageHandler(event)quot; …/> <mx:Tile id=quot;thumbnailContainerquot; width=quot;100%quot; height=quot;90%quot;> <mx:Repeater id=quot;rpquot; id rp dataProvider=quot;{CloudPhotosModelLocator.getInstance().currentAlbum.photos.photo}quot;> <components:PhotoThumbnail photo=quot;{rp.currentItem}quot;/> </mx:Repeater> </mx:Tile> </mx:Canvas> Slide 66 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 67. Spring beans for messaging pg gg <amq:topic id=quot;destinationquot; physicalName=quot;org.apache.activemq.spring.Test.spring.embeddedquot;/> <bean id=quot;consumerJmsTemplatequot; class=quot;org.springframework.jms.core.JmsTemplatequot;> <property name=quot;connectionFactoryquot; ref=quot;jmsFactoryquot;/> </bean> <bean id=quot;producerquot; class=quot;net.chrisrichardson.kickstart.backend.services.SpringProducerquot;> <property name=quot;templatequot; ref=quot;myJmsTemplatequot;/> <property name=quot;destinationquot; ref=quot;destinationquot; /> </bean> public class SpringProducer { private JmsTemplate template; private Destination destination; public void send(String message) { template.convertAndSend(destination, message); } } Slide 67 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 68. BlazeDS MessageBrokerServlet g <servlet> <servlet-name>MessageBrokerServlet</servlet-name> <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class> l l fl i kS l / l l <init-param> <param-name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> /i i <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> lt i <servlet-name>MessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> Slide 68 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 69. services-config.xml g Shared by client and server Messaging Service One or more adapters One or more destinations One or more channels Destinations Referenced by client Source/sink of messages g Has an adapter, e.g. JMSAdapter Channels Used by a Flex component to communicate with the BlazeDS server Bl DS Communicate with server-side endpoints Endpoints URLs that URL th t are mapped t M d to MessageBroker servlet Bk lt Slide 69 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 70. Channels and endpoints p <services-config> <channel-definition id quot; h l d fi i i id=quot;my-polling-amfquot; lli fquot; class=quot;mx.messaging.channels.AMFChannelquot;> <endpoint url=quot;http://localhost:8080/webapp/messagebroker/amfpollingquot; class=quot;flex.messaging.endpoints.AMFEndpointquot;/> l quot;fl i di AMFE d i quot;/ <properties> <polling-enabled>true</polling-enabled> <polling-interval-seconds>4</polling-interval-seconds> </properties> / ti </channel-definition> </services-config> / i fi Slide 70 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 71. Messaging service gg <service id=quot;message-servicequot; class=quot;flex.messaging.services.MessageServicequot;> <adapters> <adapter-definition id=quot;actionscriptquot; class=quot;flex.messaging.services.messaging.adapters.ActionScriptAdapterquot; default=quot;truequot; /> <adapter-definition id=quot;jmsquot; class=quot;flex.messaging.services.messaging.adapters.JMSAdapterquot; /> </adapters> <default-channels> <channel ref=quot;my-polling-amfquot; /> ref my polling amf </default-channels> <destination id=quot;message-destinationquot;> <properties> <jms> j <destination-jndi-name>topicjndiname</destination-jndi-name> … </jms> </properties> /p p <adapter ref=quot;jmsquot; /> </destination> </service> Slide 71 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 72. Agenda g The joy and pain of UI development Overview of Flex Developing Flex Applications pg pp Pushing data to the client Building and testing Flex applications Slide 72 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 73. Using Flex Mojos g j Open source project Maven Mojos for building and testing flex applications http://code.google.com/p/flex-mojos/ Badly documented but they work y y Slide 73 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 74. Building a Flex client p j g project <project> … <pluginRepositories> <pluginRepository> l iR i <id>pia-repository</id> <url>http://repository.sonatype.org/content/groups/flexgroup/</url> </pluginRepository> </pluginRepositories> <dependencies> <dependency> <groupId>cairngorm</groupId> “mvn install” builds SWF <artifactId>cairngorm</artifactId> <version>2_2_1</version> <type>swc</type> </dependency> /p y </dependencies> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <groupId>info.flex mojos</groupId> <groupId>info.flex-mojos</groupId> <artifactId>flex-compiler-mojo</artifactId> </plugin> …. </plugins> </build> </project> Slide 74 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 75. Adding the SWF to y g your WAR <project> <packaging>war</packaging> … <dependencies> d d i <dependency> <groupId>net.chrisrichardson</groupId> <artifactId>kickstart-webapp</artifactId> Input = SWF + Existing WAR file <version>1.0-SNAPSHOT</version> <type>war</type> Output = new WAR file containing SWF </dependency> <dependency> <groupId>net.chrisrichardson</groupId> <artifactId>photoflexui</artifactId> <version>1.0-SNAPSHOT</version> <type>swf</type> yp / yp </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.sonatype.flexmojos</groupId> <artifactId>flexmojos-maven-plugin</artifactId> <executions> <execution> <goals><goal>copy-flex-resources</goal></goals> </execution> </executions> </plugin> … Slide 75 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 76. Automated testing g $$: HP QTP, RIATest FlexUnit Focused on unit tests Record UI tests with FlexMonkey Encountered a licensing error during compilation! Fluint Supposedly better than FlexUnit Not supported by Flex Mojos Slide 76 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 77. Selenium-Flex Looks the most familiar/promising selenium.flexClick() selenium flexClick() selenium.flexWaitForElement() … Selenium extensions invoke ActionScript functions via External interface Include SeleniumFlexAPI.swc in your application External interface seems not to work in IE6 Tricky to get working in FireFox y g g Launching SeleniumServer via Java API didn’t work – extensions not loaded maven-selenium-plugin worked pg Slide 77 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 78. Example Selenium-Flex test p public class WebIntegrationTest extends TestCase { @Override protected void setUp() throws Exception { selenium = new DefaultSeleniumFlex(quot;localhostquot;, 4444, browserType, quot;http://localhost:8080quot;); selenium.start(); } public void test() throws Exception { selenium.open(quot;http://localhost:8080/webapp/photoflexui.htmlquot;); waitForFlexApplicationToLoad(quot;createAlbumButtonquot;); selenium.flexWaitForElement(quot;albumThumbnail[1]quot;); selenium.flexClick(quot;albumThumbnail[1]quot;); selenium.flexWaitForElementVisible(quot;backToAlbumsButtonquot;); selenium.flexClick( backToAlbumsButtons ); selenium flexClick(quot;backToAlbumsButtonsquot;); selenium.flexWaitForElementVisible(quot;createAlbumButtonquot;); selenium.flexClick(quot;createAlbumButtonquot;); } } Slide 78 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 79. My next steps y p Write some automated tests Investigate Spring ActionScript Dependency injection framework Promotes loose coupling “Inject stubs for services” Investigate ExternalInterface ActionScript JavaScript Slide 79 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 80. Summary Flex HTML/Javascript/CSS p Better paradigm (Open-source) testing tools are more Easier to develop mature Slide 80 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 81. Final thoughts g Download or contribute to Cloud Tools today : y www.cloudtools.org Checkout Cloud Foundry: www.cloudfoundry.com www cloudfoundry com Buy my book ☺ Send email: chris@chrisrichardson.net Visit my website: www.chrisrichardson.net Talk to me about consulting and training Phone: 510 904 9832 Slide 81 Copyright (c) 2009 Chris Richardson. All rights reserved.
  • 82. Resources http://www.actionscript.org/ http://www.adobe.com/devnet/actionscript/articl es/actionscript3_overview.html http://www.adobe.com/devnet/flex/ http://www.adobe.com/devnet/flash/ http://www.infoq.com/articles/java-flex-blazeds Intro link: http://www.adobe.com/devnet/flex/articles/intro ducing_cairngorm.html http://dispatchevent.org/roger/as3-e4x- rundown/ / http://myflex.org/presentations/ComparingFlexFr ameworks.pdf http://code.google.com/p/flexlib/ p // gg /p/ / Slide 82 Copyright (c) 2009 Chris Richardson. All rights reserved.