82
Flex for Java developers: Flex for Java developers: My quest for pain-free UI development development Chris Richardson Author of POJOs in Action www.chrisrichardson.net [email protected] @crichardson Cinco de Mayo 2009

Flex For Java Developers - SDForum Java SIG

Embed Size (px)

DESCRIPTION

One day Chris Richardson, in need of a rich UI and deeply frustrated with Javascript and CSS, sat on his couch and downloaded FlexBuilder. This is what he found out.

Citation preview

Page 1: Flex For Java Developers - SDForum Java SIG

Flex for Java developers: Flex for Java developers: My quest for pain-free UI

development development

Chris RichardsonAuthor of POJOs in [email protected]

@crichardson

Cinco de Mayo 2009

Page 2: Flex For Java Developers - SDForum Java SIG

About ChrisAbout 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 BEAcompany and sold it to BEA

• Speaker at JavaOne, SpringOne, etc.• Java Champion• Run a consulting and training company

that helps organizations reduce d l d i

gdevelopment costs and increase effectiveness

cloudtools.org

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

www.cloudfoundry.com

Page 3: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexDeveloping Flex ApplicationsPushing data to the clientgBuilding and testing Flex applications

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

Page 4: Flex For Java Developers - SDForum Java SIG

Arms race: Frameworks vs. UI complexityp y

1998- 2000- 2002- 2005-19981999

20002002

20022005

20052006 2007 2008

Really simply pages

Really Simple Pages

More Complex

Pages

More Complex

Pages

More complex pages

Rich UIs

Home grown frame

work

Struts 1.0

Struts 1.0

Spring MVC

Spring MVC/Web

Flow

Spring MVC

WebFlowDojo

/☺ ☺

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

Page 5: Flex For Java Developers - SDForum Java SIG

Cloud Foundryy

Slide 5

Page 6: Flex For Java Developers - SDForum Java SIG

Cloud Foundry UIy

Single page applicationDojo toolkitUses DWR to push events to browserpEnd result is quite niceBut getting there was painfulBut getting there was painful

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

Page 7: Flex For Java Developers - SDForum Java SIG

Why is building RIAs so painful?y g pOpen-source JavaScript projects

Variable qualityq ySome are poorly documentedBuilt on a shaky foundation of web technologies

JavaScriptpDynamic ⇒ limited IDE supportPrototype-based ⇒ simulated classesNo packages ⇒ build your own…

CSS layoutDifficult to learnRelies on “hacks” to accomplish basic layout tasksLack of portability across browsersEasier to use tables?

N b i tibilitiNumerous browser incompatibilities

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

Page 8: Flex For Java Developers - SDForum Java SIG

Today's web = multi-layer hacky y

Was – a straightforward Hacks to enable offline applicationshypertext browsing system

Now – an application

applications

delivery platformFake class

system

⇒Time for a Javascript

change Hypertext

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

Page 9: Flex For Java Developers - SDForum Java SIG

GWT is an optionp

Treats JavaScript as the runtime environmentDevelop and debug in Java"Swing-style" programming model

But my social network liked Flex …

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

Page 10: Flex For Java Developers - SDForum Java SIG

So I downloaded Flex Builder

d l dCopyright (c) 2009 Chris Richardson. All rights reserved. Slide 10

and wrote some Flex code…

Page 11: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexDeveloping Flex Applicationsp g ppPushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 12: Flex For Java Developers - SDForum Java SIG

What is Flex?

Open-source framework for building Rich Internet ApplicationsRich Internet ApplicationsCurrent version is Flex 3 (Flex 4 in 4Q09)

Flex apps run on the ubiquitous Flash pp qplayer

In the browserOn the desktop with Adobe AIROn the desktop with Adobe AIR

Excellent documentationDevelop applications in

MXML – declaratively define UIActionScript 3 – handle events, invoke backend services, dynamically construct UI, y y

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

Page 13: Flex For Java Developers - SDForum Java SIG

ActionScript 3 – the scripting language for the Flash playerg g p y

Class-based, object-oriented languageCompile-time type checkingPackagesDynamic vs. sealed classes

Dynamic – add properties/methods at tiruntime

Method closuresHi h f AVM2 ith JIT High performance AVM2 with JIT compilerDi le t of ECMAS ipt (like J S ipt)Dialect of ECMAScript (like JavaScript)

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

Page 14: Flex For Java Developers - SDForum Java SIG

ActionScript XML support (E4X)p pp ( )

var x : XML = <createAlbumRequest>var x : XML = <createAlbumRequest><title>{title}</title><creationDate>

{creationDate.time}

var albums : XML = <albums><album><id>id1</id><title>t1</title>

</creationDate><notes>{notes}</notes>

</createAlbumRequest>

/<thumbnail>xyz<thumbnail>

</album><album><id>id2</id><title>t2</title>

var title : String = x.title;var notes : String = x.notes;

<title>t2</title><thumbnail>abc</thumbnail>

</album>…..

</albums>

var notes : XMLList = albums.album.notes

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

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

Page 15: Flex For Java Developers - SDForum Java SIG

Comprehensive component libraryp p y

Components have properties and methodshave properties and methodsgenerate events

Visual componentsControls: Button, TextField, …Container: TabContainer, Form, Box, …Can be styled with CSSCan be styled with CSS

Non-Visual Data access components, e.g. HTTP, Web ServicesServicesValidatorsFormatters

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

Page 16: Flex For Java Developers - SDForum Java SIG

Declaratively define UI in MXMLy<mx:Application >

<mx:Form><mx:FormItem label="Symbol" fontWeight="bold"><mx:FormItem label= Symbol fontWeight= bold >

<mx:TextInput id="symbol" text="AAPL" fontWeight="normal"/></mx:FormItem><mx:FormItem label="">

<mx:Button label="Get Quote" click="handleClick(event)"/></mx:FormItem>/

</mx:Form><mx:DataGrid dataProvider="{quotes}" width="100%">

<mx:columns><mx:DataGridColumn headerText="Symbol" dataField="symbol"/><mx:DataGridColumn headerText="Price" dataField="price"/>/ l</mx:columns>

</mx:DataGrid></mx:Application>

Equivalent to creating component tree in

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

ActionScript

Page 17: Flex For Java Developers - SDForum Java SIG

Events

Components generate eventsHandled by ActionScript code

< B tt l b l "G t Q t " li k "h dl Cli k( t)"/><mx:Button label="Get Quote" click="handleClick(event)"/>

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

}

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

Page 18: Flex For Java Developers - SDForum Java SIG

Data Bindingg

Control is updated whenever variable Control is updated whenever variable changes

[Bindable]private var quotes : Array = [];

<mx:DataGrid dataProvider="{quotes}" width="100%"><mx:DataGrid dataProvider= {quotes} width= 100% ><mx:columns><mx:DataGridColumn headerText="Symbol" dataField="symbol"/><mx:DataGridColumn headerText="Price" dataField="price"/>

</mx:columns>

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

</mx:DataGrid>

Page 19: Flex For Java Developers - SDForum Java SIG

Custom componentsp

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

subclasses in MXML or A ti S i t

<![CDATA[[Bindable]public var album : XML;

public function viewAlbum() : void { ….}

ActionScriptUse to

d l i

p () { }

]]></mx:Script>

<mx:VBox width="100" height="125">I id "i " li k " i Alb ()" modularize

application3 d

<mx:Image id="img" click="viewAlbum()" source="{album.thumbnail}" />

</mx:Box><mx:Text width="100" height="25"

text="{album.title}"/>

3rd party components

</mx:VBox>

</mx:GridItem>

<components:AlbumThumbnail

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

<components:AlbumThumbnailalbum="{rp.currentItem}"/>

Page 20: Flex For Java Developers - SDForum Java SIG

Flex security sandboxy

Uses the Flash Player security modelBy default, a Flex application can only access resources on the site that it was downloaded fromCross-domain policy files on remote server grants access to Flex applications from other domains

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

Page 21: Flex For Java Developers - SDForum Java SIG

Flex Tools from Adobe

Flex SDKF Free, open-sourceCompilers and command-line debugger

FlexBuilderFlexBuilder –Cheap ($249) Eclipse-based IDEFor Mac and WindowsFor Mac and WindowsMXML and ActionScript editors –completion, renaming and validationDrag and drop UI builderGood debugging: breakpoints, C h i h lComprehensive help

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

Page 22: Flex For Java Developers - SDForum Java SIG

Flex Stock Quote DemoQ

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

Page 23: Flex For Java Developers - SDForum Java SIG

Flex back-end integrationg

BlazeDSO jOpen-source projectAllows Flex clients to talk to server-side Java applicationsJava applicationsRPCServer-push over HTTPp

LiveCycle Data Services ESCommercialSuperset of BlazeDSMore scalableCli t/S d t h i tiClient/Server data synchronization

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

Page 24: Flex For Java Developers - SDForum Java SIG

Flex Application Architecturepp

BlazeDS

SOFEA = Service-Oriented Front-End Architecture

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

SOFEA = Service Oriented Front End Architecture

Page 25: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexBuilding Flex Applications

The Cairngorm frameworkCloud Photos Example ApplicationS i di l i lbScenario: displaying albumsScenario: creating a new albumScenario: copying photos between albumsScenario: copying photos between albums

Pushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 26: Flex For Java Developers - SDForum Java SIG

Tangled codeg

<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" implements="mx.rpc.IResponder" backgroundColor="#ffffff"><mx:Script>[Bindable] Data[Bindable]private var quote : String;

private function handleClick(event :Event) : void {var service : HTTPService = new HTTPService(); Data

Data

…}

public function result(data:Object):void { …. } public function fault(info:Object):void { }

Data Access Logic

p ( j ) { }]]></mx:Script>

<mx:VDividedBox width="414" height="217" ….

</mx:VDividedBox>Presentation logic

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

</mx:VDividedBox>

</mx:Application>

Page 27: Flex For Java Developers - SDForum Java SIG

Cairngorm frameworkg

MVC framework for FlexModel – dataModel – dataView – Flex components that display the model (through binding)Controller implements "business logic" Controller – implements "business logic", i.e. accessing backend services and update the model

Encourages:Encourages:Separation of concerns Separation of development roles: front-end

d b k dand back-endAvoids big ball of mudAn alternative is PureMVCAn alternative is PureMVC

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

Page 28: Flex For Java Developers - SDForum Java SIG

Cairngorm classes and rolesgViews

Display the modelModelLocator

The code has a cookie-ModelLocator

Provides access to the model“Business” Events

Generated by ViewsFront Controller

cutter feel to it but I like the structure

Front ControllerRoutes events to Commands

CommandsHandle eventsContain "business logic"/data access logicg / gInvoke delegates

DelegatesProxy for remote servicesContract between front-end and back-end teamC ll b k t dCalls back to command

ServiceLocatorCentralized registry of (supposedly) all data access componentsUsed by delegates

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

Page 29: Flex For Java Developers - SDForum Java SIG

Cairngorm flowg

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

Page 30: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexBuilding Flex Applications

The Cairngorm frameworkCloud Photos Example ApplicationS i di l i lbScenario: displaying albumsScenario: creating a new albumScenario: copying photos between albumsScenario: copying photos between albums

Pushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 31: Flex For Java Developers - SDForum Java SIG

Cloud Photos ApplicationTomcat

pp

Flex ClientScala/Spring MVC

RESTful web services

Events

Manage your

/ p g

Java/Spring/JMS

Manage your photos online

Upload and pview photosOrganize photos into

Simple DB

S3

photos into albums…

Amazon Web Services

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

Page 32: Flex For Java Developers - SDForum Java SIG

Cloud Photos – screenshots

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

Page 33: Flex For Java Developers - SDForum Java SIG

Cloud Photo – web serviceshttp://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>

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

Page 34: Flex For Java Developers - SDForum Java SIG

Application structurepp

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

Page 35: Flex For Java Developers - SDForum Java SIG

Model – a Singletong

package net.chrisrichardson.cloudphotos.ui.model {import com.adobe.cairngorm.model.IModelLocator;

[Bindable]public class CloudPhotosModelLocator implements IModelLocator {

private static var modelLocator:CloudPhotosModelLocator;

Metadata tag enables binding for all public properties

private static var modelLocator:CloudPhotosModelLocator;

public var viewState : String = "displayAlbums";

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

public static function getInstance():CloudPhotosModelLocator{if (modelLocator == null) {

modelLocator = new CloudPhotosModelLocator();Singleton

();}return modelLocator;

}

}

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

}

}

Page 36: Flex For Java Developers - SDForum Java SIG

View - Main applicationpp

<?xml version="1.0" encoding="utf-8"?><mx:Application layout="vertical" <mx:Application layout vertical

xmlns:ns1="net.chrisrichardson.cloudphotos.ui.components.*"xmlns:control="net.chrisrichardson.cloudphotos.ui.control.*" xmlns:business="net.chrisrichardson.cloudphotos.ui.business.*"

idth "100%" h i ht "100%"width="100%" height="100%">

<business:Services id="services" />bus ess Se ces d se ces /<control:Controller id="controller" />

<mx:Label text="Cloud Photos" fontSize="33"/><ns1:HomePage width "100%" height "100%"><ns1:HomePage width="100%" height="100%"></ns1:HomePage>

</mx:Application>

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

Page 37: Flex For Java Developers - SDForum Java SIG

View - HomePageg<mx:Vbox …>

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

<mx:states><mx:State name="displayAlbums">

<mx:SetProperty name="selectedIndex" target="{viewStack}" value="{0}"/></mx:State></mx:State><mx:State name="displayAlbum">

<mx:SetProperty name="selectedIndex" target="{viewStack}" value="{1}"/></mx:State>

</mx:states>

<mx:TabNavigator id="tabNavigator" ><mx:TabNavigator id= tabNavigator …>

<mx:ViewStack id="viewStack" width="100%" height="100%" label="My Albums" ><components:AlbumList id="albumList" width="100%" height="100%“/><components:AlbumView id="albumView" width="100%" height="100%“/>

</mx:ViewStack>…

</mx:TabNavigator>

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

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

album

Page 38: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexBuilding Flex Applications

The Cairngorm frameworkCloud Photos Example ApplicationS i di l i lbScenario: displaying albumsScenario: creating a new albumScenario: copying photos between albumsScenario: copying photos between albums

Pushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 39: Flex For Java Developers - SDForum Java SIG

Display Albums Flowp y

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

Page 40: Flex For Java Developers - SDForum Java SIG

View dispatches eventp<?xml version="1.0" encoding="utf-8"?><mx:Vbox … creationComplete="displayAlbums()">

<mx:Script><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="100%" height="10%"><mx:Button label="Create New" click="createAlbum()"/>

</mx:HBox>

<mx:Tile id="albumGrid" width="100%" height="90%">R t id " " d t P id "{Cl dPh t M d lL t tI t () lb }"<mx:Repeater id="rp" dataProvider="{CloudPhotosModelLocator.getInstance().albums}">

<components:AlbumThumbnail album="{rp.currentItem}"/></mx:Repeater>

</mx:Tile></mx:VBox>

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

Page 41: Flex For Java Developers - SDForum Java SIG

Controller executes commandpackage net.chrisrichardson.cloudphotos.ui.control{import com.adobe.cairngorm.control.FrontController;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() : voidpublic function initializeCommands() : void{

addCommand( CreateAlbumEvent.CREATE_ALBUM, CreateAlbumCommand);addCommand( DisplayAlbumsEvent.DISPLAY_ALBUMS, DisplayAlbumsCommand);addCommand( DisplayAlbumEvent.DISPLAY_ALBUM, DisplayAlbumCommand);addCommand( CopyPhotoToAlbumEvent.COPY_PHOTO, CopyPhotoToAlbumCommand);

}}

}

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

Page 42: Flex For Java Developers - SDForum Java SIG

Command calls delegateg

public class DisplayAlbumsCommand implements ICommand, IResponder{

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

}

public function result( event : Object ):void {var albums : XMLList = event.result.album;

d l Cl dPh t M d lL t Cl dPh t M d lL t tI t ()var model : CloudPhotosModelLocator = CloudPhotosModelLocator.getInstance();model.albums = albums

}

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

}}

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

Page 43: Flex For Java Developers - SDForum Java SIG

Delegate invokes servicegpublic class DisplayAlbumsDelegate{private var responder : IResponder;private var service : HTTPService;

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

}

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

call.addResponder(responder);}

}

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

Page 44: Flex For Java Developers - SDForum Java SIG

Service definition

<?xml version="1.0" encoding="utf-8"?>

<cairngorm:ServiceLocatorxmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cairngorm="http://www adobe com/2006/cairngorm">xmlns:cairngorm http://www.adobe.com/2006/cairngorm >

<mx:HTTPService id="displayAlbums" url="http://.../api/album"

ltF t " 4 "resultFormat="e4x"useProxy="false" method="GET" >

</mx:HTTPService>/

</cairngorm:ServiceLocator>

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

Page 45: Flex For Java Developers - SDForum Java SIG

Command updates modelp

public class DisplayAlbumsCommand implements ICommand, IResponder{

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

}

public function result( event : Object ):void {var albums : XMLList = event.result.album;

d l Cl dPh t M d lL t Cl dPh t M d lL t tI t ()var model : CloudPhotosModelLocator = CloudPhotosModelLocator.getInstance();model.albums = albums

}

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

}}

<albums><album>…</album><album>…</album>…

</albums>

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

Page 46: Flex For Java Developers - SDForum Java SIG

View displays modelp y<?xml version="1.0" encoding="utf-8"?><mx:Vbox … creationComplete="displayAlbums()">

<mx:Script><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="100%" height="10%"><mx:Button label="Create New" click="createAlbum()"/>

</mx:HBox>

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

</mx:Repeater></mx:Tile>

</mx:VBox>

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

Page 47: Flex For Java Developers - SDForum Java SIG

View componentp<mx:GridItem >

<mx:Script>

<album><id>e778769a-8432-46ca-b0f1-5c92f33a8710</id><title>Pictures of kids</title>

<![CDATA[[Bindable]public var album : XML;

public function viewAlbum() : void {

/<thumbnail>https://s3.amazonaws.com/…</thumbnail>

</album>

p () {new DisplayAlbumEvent(album.id).dispatch();CloudPhotosModelLocator.getInstance().viewState = "displayAlbum";

}

]]>/ S i t</mx:Script>

<mx:Box width="100" height="125"><mx:Image id="img" click="viewAlbum()" source="{album.thumbnail}" />

</mx:Box><mx:Text width="100" height="25" text="{album title}"/><mx:Text width= 100 height= 25 text= {album.title} />

</mx:VBox>

</mx:GridItem>

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

Page 48: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexBuilding Flex Applications

The Cairngorm frameworkCloud Photos Example ApplicationS i di l i lbScenario: displaying albumsScenario: creating a new albumScenario: copying photos between albumsScenario: copying photos between albums

Pushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 49: Flex For Java Developers - SDForum Java SIG

Points of interest

Uses a popup windowUploads filesCommand publishes a Cairngorm p gevent to notify view that upload is complete

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

Page 50: Flex For Java Developers - SDForum Java SIG

Displaying a popup windowp y g p p p<?xml version="1.0" encoding="utf-8"?><mx:Vbox … creationComplete="displayAlbums()">

<mx:Script><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="100%" height="10%"><mx:Button label="Create New" click="createAlbum()"/>

</mx:HBox>

<mx:Tile id="albumGrid" width="100%" height="90%">R t id " " d t P id "{Cl dPh t M d lL t tI t () lb }"<mx:Repeater id="rp" dataProvider="{CloudPhotosModelLocator.getInstance().albums}">

<components:AlbumThumbnail album="{rp.currentItem}"/></mx:Repeater>

</mx:Tile></mx:VBox>

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

Page 51: Flex For Java Developers - SDForum Java SIG

CreateAlbum popup windowp p p<mx:TitleWindow><mx:Form width="100%">

<mx:FormItem label="Album Title">T I id " lb Ti l " h " bl Di bl C B ()"/<mx:TextInput id="albumTitle" change="enableDisableCreateButton()"/>

</mx:FormItem><mx:FormItem label="Album Date">

<mx:DateChooser id="date" change="enableDisableCreateButton()"/></mx:FormItem><mx:FormItem label="Notes"> <mx:TextArea id="notes"/> </mx:FormItem><mx:FormItem label="">

<mx:Button label="Select Images..." click="selectFiles()"/></mx:FormItem><mx:FormItem label="">

<mx:Label text="{photosToUpload.length} images"/></mx:FormItem>

<Form> provides an easy way to /

<mx:FormItem label="Selected Files" width="100%"><mx:DataGrid dataProvider="{photosToUpload}" width="100%">

<mx:columns><mx:DataGridColumn headerText="Name" dataField="name"/><mx:DataGridColumn headerText="Date" dataField="creationDate"/>

</mx:columns>

an easy way to layout the form fields

</mx:columns></mx:DataGrid>

</mx:FormItem></mx:Form>

<mx:ControlBar><mx:Button id="createButton" label="Create Album" click="createAlbum(event)" enabled="false"/>

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

<mx:Button id= createButton label= Create Album click= createAlbum(event) enabled= false /><mx:Button label="Cancel" click="cancelCreateAlbum()"/>

</mx:ControlBar>

</mx:TitleWindow>

Page 52: Flex For Java Developers - SDForum Java SIG

Selecting files to uploadg pprivate var myFileReference:FileReferenceList = new FileReferenceList();

[Bindable][Bindable]private var photosToUpload : Array;

private function selectFiles():void {myFileReference.addEventListener("select", selectHandler);myFileReference.browse();

}

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

}

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

}

private function filesSupplied() : Boolean {

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

p pp () {return photosToUpload != null && photosToUpload.length > 0

}

Page 53: Flex For Java Developers - SDForum Java SIG

Displaying progress and dispatching Cairngorm eventp g g

<?xml version="1.0" encoding="utf-8"?><mx:TitleWindow><mx:Script><![CDATA[private var uploadProgressWindow : PhotoUploadProgressWindow;

private function createAlbum(event:Event) : void {private function createAlbum(event:Event) : void {uploadProgressWindow =

PhotoUploadProgressWindow(PopUpManager.createPopUp(this, PhotoUploadProgressWindow, true));

PopUpManager.centerPopUp(uploadProgressWindow); C t Alb E t C t Alb E t()var ev : CreateAlbumEvent = new CreateAlbumEvent()

ev.album = new Album(albumTitle.text, notes.text, date.selectedDate)ev.photosToUpload = photosToUploadev.dispatch()

}}

</mx:Script>

</mx:TitleWindow>

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

Page 54: Flex For Java Developers - SDForum Java SIG

Uploading a filep 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() + "api/album/" + album.id + "/photo/" +

photoId;p ;this.photo.addEventListener(Event.COMPLETE, completeHandler);this.photo.upload(ur, "photo");

}

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

}

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

Page 55: Flex For Java Developers - SDForum Java SIG

CreateAlbumCommand

package net.chrisrichardson.cloudphotos.ui.command {

public class CreateAlbumCommand implements ICommand, IResponder{

public function CreateAlbumCommand() {}

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

}}

public function result( event : Object ):void { new AlbumCreatedEvent((event as Album).id).dispatch();

}

Long running - publishes a }

public function fault( event : Object ) : void { … }

}

Cairngorm event when finished

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

}

Page 56: Flex For Java Developers - SDForum Java SIG

CreateAlbumPopupp p<?xml version="1.0" encoding="utf-8"?><mx:TitleWindow creationComplete="creationComplete()"><mx:Script>

View subscribes to AlbumCreatedEvent –<mx:Script>

<![CDATA[

private function creationComplete() : void {CairngormEventDispatcher.getInstance()

AlbumCreatedEvent –easier than binding to model

.addEventListener("albumCreated", albumCreated);}

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

}}

}]]>

</mx:Script>

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

/ p

</mx:TitleWindow>

Page 57: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentO i f FlOverview of FlexBuilding Flex Applications

The Cairngorm frameworkThe Cairngorm frameworkCloud Photos Example ApplicationScenario: displaying albumsp y gScenario: creating a new albumScenario: copying photos between albumsalbums

Pushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 58: Flex For Java Developers - SDForum Java SIG

Points of interest

Uses drag and drop to copy a photo to an album

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

Page 59: Flex For Java Developers - SDForum Java SIG

Initiating a dragg g<mx:VBox width="100" height="175">

<mx:Script><![CDATA[ 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="img" width="100%" height="100%" mouseMove="mouseMoveHandler(event)"source="{photo.thumbnail}"/>

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

</mx:VBox>

Page 60: Flex For Java Developers - SDForum Java SIG

Handling a dropg p<mx:VBox width="100" height="175">

<mx:Script> <![CDATA[

[Bi d bl ]AlbumSummaryThumbnail.mxml

[Bindable]public var album : XML ;

private function dragEnterHandler(event:DragEvent):void {if (event.dragSource.hasFormat('photoId')) {

var dropTarget:Image=Image(event.currentTarget);

y

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="100" height="125" verticalScrollPolicy="off" horizontalScrollPolicy="off"><mx:Image dragEnter="dragEnterHandler(event);" dragDrop="dragDropHandler(event);"

source="{album.thumbnail}"/></mx:Box><mx:Text id="title" width="100" height="25" text="{album.title}"/>

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

</mx:VBox>

Page 61: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexDeveloping Flex Applicationsp g ppPushing data to the clientBuilding and testing Flex applicationsBuilding and testing Flex applications

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

Page 62: Flex For Java Developers - SDForum Java SIG

Why events?y

Cloud Photos server asynchronously uploads photos to S3Client might display photo before it is available

⇒Notify client when a photo is availableClient can reload the imageClient can reload the image

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

Page 63: Flex For Java Developers - SDForum Java SIG

BlazeDS

Open-source project Connects Flex and AIR clients to Java Connects Flex and AIR clients to Java backend services

Client-side Flex componentsServer-side components, E.g. Servlet

RPC servicesProxying for remote (web) servicesProxying for remote (web) servicesInvoke server-side Java object

Publish-Subscribe messagingSupports integration with JMS

Spring BlazeDS project for simplified developmentdevelopment

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

Page 64: Flex For Java Developers - SDForum Java SIG

BlazeDS messaging componentsg g p

Client Server

Consumer Destination Adapter JMS Queue/Topic

receives messages from

Channel Endpoint

using

http://localhost:8080/webapp/messagebroker/amfpolling

corresponds to

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

Page 65: Flex For Java Developers - SDForum Java SIG

Channel/Endpoint options/ p p

HTTP Options:Simple polling with piggybackLong polling – message/connectionStreaming – many messages/connection

Formats:AMF – efficient binary formatAMFX – XML format

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

Page 66: Flex For Java Developers - SDForum Java SIG

Example client-side consumerp<?xml version="1.0" encoding="utf-8"?><mx:Canvas creationComplete="creationComplete()">

<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());

}}

]]></mx:Script>

Server publishes a JMS event when it has uploaded an image to S3.

<mx:Consumer id="consumer" destination="message-destination" message="messageHandler(event)" …/>

<mx:Tile id="thumbnailContainer" width="100%" height="90%"><mx:Repeater id="rp"

Client subscribes and reloads images if required

<mx:Repeater id rp dataProvider="{CloudPhotosModelLocator.getInstance().currentAlbum.photos.photo}">

<components:PhotoThumbnail photo="{rp.currentItem}"/></mx:Repeater>

</mx:Tile>

</mx:Canvas>

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

</mx:Canvas>

Page 67: Flex For Java Developers - SDForum Java SIG

Spring beans for messagingp g g g<amq:topic id="destination"

physicalName="org.apache.activemq.spring.Test.spring.embedded"/>

<bean id="consumerJmsTemplate" class="org.springframework.jms.core.JmsTemplate"><property name="connectionFactory" ref="jmsFactory"/>

</bean>

<bean id="producer" class="net.chrisrichardson.kickstart.backend.services.SpringProducer">

<property name="template" ref="myJmsTemplate"/><property name="destination" ref="destination" />

</bean></bean>

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

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

}

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

}

Page 68: Flex For Java Developers - SDForum Java SIG

BlazeDS MessageBrokerServletg

<servlet><servlet-name>MessageBrokerServlet</servlet-name>

l l fl i k S l / l l<servlet-class>flex.messaging.MessageBrokerServlet</servlet-class><init-param>

<param-name>services.configuration.file</param-name><param-value>/WEB-INF/flex/services-config.xml</param-value>

/i i</init-param><load-on-startup>1</load-on-startup>

</servlet>

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

</servlet-mapping>

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

Page 69: Flex For Java Developers - SDForum Java SIG

services-config.xmlgShared by client and serverMessaging ServiceMessaging Service

One or more adaptersOne or more destinationsOne or more channels

DestinationsReferenced by clientSource/sink of messagesgHas an adapter, e.g. JMSAdapter

ChannelsUsed by a Flex component to communicate with the Bl DSBlazeDS serverCommunicate with server-side endpoints

EndpointsURL th t d t M B k l tURLs that are mapped to MessageBroker servlet

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

Page 70: Flex For Java Developers - SDForum Java SIG

Channels and endpointsp<services-config>

h l d fi i i id " lli f"<channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">

<endpoint url="http://localhost:8080/webapp/messagebroker/amfpolling" l "fl i d i AMFE d i "/class="flex.messaging.endpoints.AMFEndpoint"/>

<properties><polling-enabled>true</polling-enabled><polling-interval-seconds>4</polling-interval-seconds>

/ ti</properties></channel-definition>

/ i fi</services-config>

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

Page 71: Flex For Java Developers - SDForum Java SIG

Messaging serviceg g<service id="message-service" class="flex.messaging.services.MessageService">

<adapters><adapters><adapter-definition id="actionscript"class="flex.messaging.services.messaging.adapters.ActionScriptAdapter"default="true" />

<adapter-definition id="jms"class="flex.messaging.services.messaging.adapters.JMSAdapter" />

</adapters>

<default-channels><channel ref="my-polling-amf" /><channel ref my polling amf />

</default-channels>

<destination id="message-destination"><properties>

j<jms><destination-jndi-name>topicjndiname</destination-jndi-name>…

</jms></properties>

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

/p p<adapter ref="jms" />

</destination></service>

Page 72: Flex For Java Developers - SDForum Java SIG

Agendag

The joy and pain of UI developmentOverview of FlexDeveloping Flex Applicationsp g ppPushing data to the clientBuilding and testing Flex Building and testing Flex applications

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

Page 73: Flex For Java Developers - SDForum Java SIG

Using Flex Mojosg j

Open source projectMaven Mojos for building and testing flex applicationshttp://code.google.com/p/flex-mojos/Badly documented but they worky y

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

Page 74: Flex For Java Developers - SDForum Java SIG

Building a Flex client projectg p j<project>…<pluginRepositories>

l i R i<pluginRepository><id>pia-repository</id><url>http://repository.sonatype.org/content/groups/flexgroup/</url>

</pluginRepository></pluginRepositories><dependencies>

<dependency><groupId>cairngorm</groupId>

<artifactId>cairngorm</artifactId><version>2_2_1</version><type>swc</type></dependency>

“mvn install” builds SWF

/ 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>

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

</project>

Page 75: Flex For Java Developers - SDForum Java SIG

Adding the SWF to your WARg y<project><packaging>war</packaging> …d d i<dependencies><dependency>

<groupId>net.chrisrichardson</groupId><artifactId>kickstart-webapp</artifactId><version>1.0-SNAPSHOT</version><type>war</type>

Input = SWF + Existing WAR fileOutput = new WAR file containing SWF</dependency>

<dependency><groupId>net.chrisrichardson</groupId><artifactId>photoflexui</artifactId><version>1.0-SNAPSHOT</version><type>swf</type>

Output = new WAR file containing SWF

yp / yp</dependency>

</dependencies><build><plugins>

<plugin><groupId>org.sonatype.flexmojos</groupId><groupId>org.sonatype.flexmojos</groupId><artifactId>flexmojos-maven-plugin</artifactId><executions>

<execution><goals><goal>copy-flex-resources</goal></goals>

</execution></executions>

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

</executions></plugin>

Page 76: Flex For Java Developers - SDForum Java SIG

Automated testingg

$$: HP QTP, RIATestFlexUnit

Focused on unit testsRecord UI tests with FlexMonkeyEncountered a licensing error during compilation!

FluintSupposedly better than FlexUnitNot supported by Flex Mojos

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

Page 77: Flex For Java Developers - SDForum Java SIG

Selenium-Flex

Looks the most familiar/promisingselenium flexClick()selenium.flexClick()selenium.flexWaitForElement()…

Selenium extensions invoke ActionScriptSelenium extensions invoke ActionScriptfunctions via External interfaceInclude SeleniumFlexAPI.swc in your applicationapplicationExternal interface seems not to work in IE6Tricky to get working in FireFoxy g g

Launching SeleniumServer via Java API didn’t work – extensions not loadedmaven-selenium-plugin workedp g

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

Page 78: Flex For Java Developers - SDForum Java SIG

Example Selenium-Flex testppublic class WebIntegrationTest extends TestCase {

@Override@Overrideprotected void setUp() throws Exception {

selenium = new DefaultSeleniumFlex("localhost", 4444, browserType,"http://localhost:8080");

selenium.start();}}

public void test() throws Exception {selenium.open("http://localhost:8080/webapp/photoflexui.html");waitForFlexApplicationToLoad("createAlbumButton");

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

selenium.flexWaitForElementVisible("backToAlbumsButton");selenium flexClick("backToAlbumsButtons");selenium.flexClick( backToAlbumsButtons );

selenium.flexWaitForElementVisible("createAlbumButton");selenium.flexClick("createAlbumButton");

}

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

}

Page 79: Flex For Java Developers - SDForum Java SIG

My next stepsy p

Write some automated testsInvestigate Spring ActionScript

Dependency injection frameworkPromotes loose coupling“Inject stubs for services”

Investigate ExternalInterfaceActionScript JavaScript

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

Page 80: Flex For Java Developers - SDForum Java SIG

Summary

Flex HTML/Javascript/CSSBetter paradigmEasier to develop

p(Open-source) testing tools are more maturemature

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

Page 81: Flex For Java Developers - SDForum Java SIG

Final thoughtsg

Download or contribute to Cloud Tools today :y

www.cloudtools.org

Checkout Cloud Foundry:

www cloudfoundry comwww.cloudfoundry.com

Buy my book ☺

Send email:

[email protected]

Visit my website:

www.chrisrichardson.net

Talk to me about consulting and training

Phone: 510 904 9832

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

Page 82: Flex For Java Developers - SDForum Java SIG

Resourceshttp://www.actionscript.org/http://www.adobe.com/devnet/actionscript/articlhttp://www.adobe.com/devnet/actionscript/articles/actionscript3_overview.htmlhttp://www.adobe.com/devnet/flex/http://www.adobe.com/devnet/flash/http://www.adobe.com/devnet/flash/http://www.infoq.com/articles/java-flex-blazedsIntro link: http://www.adobe.com/devnet/flex/articles/introhttp://www.adobe.com/devnet/flex/articles/introducing_cairngorm.htmlhttp://dispatchevent.org/roger/as3-e4x-rundown//http://myflex.org/presentations/ComparingFlexFrameworks.pdfhttp://code.google.com/p/flexlib/p // g g /p/ /

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