GWT 2 = Easier AJAX

unalaskaweepingInternet και Εφαρμογές Web

19 Ιουλ 2012 (πριν από 5 χρόνια και 3 μήνες)

505 εμφανίσεις

GWT 2 = Easier AJAX
YAJUG
1 1/5/201 0
Who am I?

Olivier Gérardin

Technical Director, Sfeir Benelux (groupe Sfeir)

Java / Web architect

13+ years Java

3
years GWT
Agenda

GWT reminders

New in GWT 2.0

SpeedTracer

In-browser development mode

Code splitting & compile
report

UiBinder

Client bundle

Layout panels

Misc.

Pointers, Conclusion, Q&A
Reminders
GWT
solves all your problems

GWT gives you AJAX without the pain of JavaScript
development

Takes care of cross-browser issues

Allows full debugging (breakpoints, step by step, inspecting/
watching variables)

Strong static typing

early error detection

Full refactoring options

No browser plugin or mandatory IDE

Short learning curve

Simple RPC mechanism built in

But can communicate with any server technology
Program in Java…

GWT allows developing client-side web apps in full
Java (with only a few restrictions)

Leverage existing Java tools and skills

Use any IDE (Eclipse, NetBeans, IntelliJ, …)

Program like a traditional graphical client (Swing,
SWT, …)

Widgets, containers, listeners, etc.

Use OO patterns (MVC, MVP, observer, composite, etc.)

Test like any Java app

Use standard Java debuggers

Test with JUnit
… deploy in JavaScript

JavaScript is only generated:

For deployment

To test in actual web mode

GWT guarantees that the generated JavaScript app
behaves exactly like the Java app

And it does (most of the time)
4 easy pieces
1)
Java-to-JavaScript compiler

Generates JS code from Java source

Performs many optimization
2)
JRE
emulation library

GWT compatible version of most used Java core
classes (java.lan, java.util)
3)
Java libraries

Utility classes (JSON,
I18N, …)

Widget library
4)
Hosted
Development mode

Run/debug the app as Java bytecode
Key
benefits
Easy development

During development, you are writing and running a
classic Java app

Use your favorite IDE

All IDE features available (code completion, code analysis,
refactoring, links, Javadoc, …)

Plugins help GWT-specific tasks

launching development mode

compiling

refactoring

creating projects, modules, RPC services, …

even design GUI (GWT Designer from Instantiations)
More benefits

Easy RPC implementation / consumption /
deployment

Easy JSON / XML parsing

Easy UI building / widget reuse

Easy history support

Easy i18n

Easy debugging

Easy testing
Any room for improvement???
Of course…
New in GWT 2.0
Speed tracer

Performance analysis tool

Visualize where your app spends time:

JS execution

Browser rendering

CSS handling (style selection/calculation)

DOM handling / event processing

Resource loading
Speed Tracer: example
In-browser development mode

Before 2.0: hosted mode uses customized browser
engine

Heavily customized

Only one supported browser per platform (IE on Windows, WebKit
on Mac, Mozilla on Linux)

Difficult to keep up-to-date

Includes platform-specific code (SWT)

Browser and hosted application share the same process

Most plugins don’t work (including Google Gears…)
In-browser development mode

now:

Hosted mode shell runs outside browser

Communicates with browser using plugin through TCP
In-browser development mode

Benefits

Use any (supported) browser/version on any platform

Currently Safari, Firefox, IE, Chrome
(not on OS X!)

Behavior closer to web mode

No interference with browser plugins

No more platform-specific stuff in GWT (one jar for all!)

Network protocol between shell and browser

cross-platform
dev possible

Dev mode shell on machine X, slave browser on machine Y

E.g. dev on Linux, test in IE on Windows…
Initiating dev mode
Plugin installation
Code splitting

Before: monolithic download

can become very big

Slow startup times

After:

Programmer can insert “split points” in code

Hints for the compiler to place everything not required up to
split point in separate download

Compiler divides code in several “chunks”, which are loaded
on-demand

Benefits:

Initial loading time reduced 50% on average with a single split
point

Allows on-demand module loading (provider pattern)
Specifying a split point
GWT.runAsync(
new
RunAsyncCallback() {

public

void
onFailure(Throwable reason) {

// …
}
pub
lic vo
i
d on
Success() {

// ..

}
});
Pattern: AsyncProvider
public

interface
AsyncClient<P> {
vo
id
onU
navailable(Throwable reason);
voi
d
onAv
ailable(P instance);
}
Async provider: Implementing the provider
public

class
Provider {


private

static
Provider
instance
=
null
;


p
ub
lic st
a
tic vo
i
d ge
tAsync(fin
al As
yncClient<Provider> client) {
GWT.runAsync(new
Ru
nAsyncCallback() {
pub
lic vo
i
d on
Failure(Throwable reason) {
c
lient.onUnavailable(reason);
}
public
void
o
nSuc
cess() {

if (
insta
nc
e
== null)
{


instance
= new Pr
ovi
der
();
}
client.onAvailable(instance)
;
Async provider: Loading the provider
private

void
loadProvider() {
Provider.getAsync(
new
AsyncClient<Provider>() {
public

void
onAvailable(Provider provider) {
provider.doSomething();
}
public

void
onUnavailable(Throwable reason) {
Window.alert(
”Failed: "
+ reason);
}
});
}
Compile Report (formerly: SOYC)

Better understanding of the compilation process

Helps tuning code splitting

Simple compiler flag

Produces HTML report

Shows:

Permutations

Sizes per chunk, package, etc.

Dependencies

Compiler flag:
-compileReport
Compile Report: output
Declarative UI: UiBinder

Declarative construction of GUI using XML grammar

Mix HTML and widgets

Benefits:

Clearly separate responsibilities

better collaboration

Static UI construction (XML)

Dynamic UI behavior (Java)

More efficient

HTML vs DOM API calls

Easy to transition from static HTML to dynamic
UiBinder: define layout

XML file (xx.ui.xml)
<
ui:UiBinder

xmlns:ui
=
'urn:ui:com.google.gwt.uibinder'
xmlns:gwt
=
'urn:import:com.google.gwt.user.client.ui'
>
<
gwt:HorizontalPanel
>
<
gwt:Label
text
=
"Sexe :"
/>
<
gwt:VerticalPanel
>
<
gwt:RadioButton
name
=
'sexeradio'
text
=
'M’
/>
<
gwt:RadioButton
name
=
'sexeradio'
text
=
'F’
/>
</
gwt:VerticalPanel
>
</
gwt:HorizontalPanel
>
</
ui:UiBinder
>

UiBinder: instantiate
public

class
SexeRadio2
extends
Composite {
@UiTemplate
(
"SexeRadio2.ui.xml"
)
interface
MyUiBinder

extends
UiBinder<Panel, SexeRadio2> {}
private

static

final
MyUiBinder
binder
= GWT.create
(MyUiBinder.
class
);
public
SexeRadio2() {
final
Panel panel =
binder
.createAndBindUi(
this
);
initWidget(panel);
UiBinder: bind fields

Automatically assign references to dynamically created widgets to
designated Java fields (@UiField)

XML :
<
gwt:RadioButton
name
=
'sexeradio'
text
=
'M’
ui:field
=
'maleRadio'
/>
<
gwt:RadioButton
name
=
'sexeradio'
text
=
'F’
ui:field
=
'femaleRadio'
/>

Code:
@UiField
RadioButton
maleRadio
;
@UiField
UiBinder: bind handlers

Automatically attach event handlers (@UiHandler)

Widgets only (not DOM elements)

Handler type inferred from parameter type

Code:
@UiHandler
(
"maleRadio"
)
void
maleClicked(ClickEvent event) {
GWT.log(
"C'est un garçon !"
,
null
);
}
More UiBinder goodness

Mix HTML and widgets in same XML file

Define CSS styles with <ui:style>

Inline / external

Apply to widgets with attributes styleNames / addStyleNames

Programmatic access to styles (works with CssResource)

Use external resources (images, CSS stylesheets, …)
declared as client bundles with <ui:with>

Instantiate widgets that don’t have zero-arg
constructor with @UiFactory
Resource bundles

Download multiple heterogeneous resources from
server in a single request

Images (similar to ImageBundle in 1.x)

CSS

Text

Any other resource

Benefits:

Fewer round trips to the server

Less overhead

More responsive interface
Resource bundles: general mechanism

Familiar mechanism

Coding time: define interface

Method type constrains resource type

Method name (accessor) designates resource

Annotation @source specifies resource content

If unspecified, source is derived from accessor

I18N aware (append _fr, _fr_FR)

Runtime: access resource

Obtain instance via GWT.create(interface.class) and call accessor
directly

Reference accessor through other mechanism (CSS injection
@sprite, etc.)
Resource bundles: DataResource

Works with any kind of source

Make the resource available through a URL

Rename file to make resulting URL strongly-
cacheable if appropriate

XXX.pdf

AAA12345.cache.pdf

Webserver should be configured accordingly
Resource bundles: TextResource

Access to static text content

TextResource is inlined into JavaScript

ExternalTextResource is fetched asynchronously
interface
Resources
extends
ClientBundle {
Resources
INSTANCE
= GWT.create(Resources.
class
);

@
Source(
“text1.txt"
)
TextResource text1();

@
Source(
“text2.txt"
)
ExternalTextResource text2();
Accessing TextResouce

// TextResource

myTextArea.setInnerText(
Resources.INSTANCE.text1().getText());

// ExternalTextResource
Resources.INSTANCE.text2().getText(

new
ResourceCallback<TextResource>() {

public

void
onError(ResourceException e)
{ ... }

public

void
onSuccess(TextResource r) {
myTextArea.setInnerText(r.getText());
}
Resource bundles: ImageResource

Optimize runtime access to image data

Transparently group /split images

Uses ImageIO library

Use in injected CSS with @sprite directive

Supports most image formats

Including animated GIF

Not an image-processing library!
Resource bundles: CssResource

Define an extension of CSS

Syntax validations / compile-time optimizations

Injected at runtime

Usage:

Write CSS stylesheet

Extend CssResource
interface
MyCss
extends
CssResource {
}

I n c l u d e i n C l i e n t B u n d l e

interface
MyResources
extends
ClientBundle {

@
Source(
"my.css"
)
MyCss css();
}

CSS extensions

Sprites with @sprite

Bundle:
class
MyResources
extends
ClientBundle {

@
Source(
"my.css"
)
MyCssResource css();

@
Source(
"some.png"
)
ImageResource imageAccessor();
}

my.css:

@sprite .mySpriteClass {
gwt-image: "imageAccessor”
CSS extensions

Constants with @def

Runtime evaluation with @eval and value()

Conditional CSS with @if/@elif/@else
Layout panels

Layout panels

Predictable, consistent layout

Constraint based system built on top of CSS

Plays nice with custom CSS styles

Each child must have 0 or 2 constraints per axis

Horizontal: none, left/width, right/width, left/right

Vertical: none, top/height, bottom/height, top/bottom

no constraint = fill parent

Any unit (%, px, …)

Must be added to an instance of ProvidesResize

typically RootLayoutPanel
Layout Panels

Easily usable with UiBinder
<g:layer left=‘25% right=‘25%’ top=‘10px’ bottom=‘0’>
<g:Label>Label</g:Label>
</g:layer>

Bunch of specialized panels implemented as
LayoutPanels:

DockLayoutPanel, SplitLayoutPanel, StackLayoutPanel,
TabLayoutPanel
And also…

Compiler optimizations

Most notably reduces generated JS size (expect 3-20 %)

Draft compile mode: flag
-drafCompile

No optimizations / Faster builds

Not for deployment!

GWTTestCase

No more dependency on SWT

No native code / browser required

HtmlUnit: GUI-less browser written in Java
Pointers, Conclusion, etc.
Pointers

GWT home (downloads, docs, FAQs, guides, etc.)

http://code.google.com/toolkit


Google groups “GWT” group

http://groups.google.com/group/Google-Web-Toolkit

onGWT: fresh news about GWT

http://www.ongwt.com


LinkedIn “GWT Users” group

http://www.linkedin.com/groups?gid=129889

Shameless self-promotion
Thank
you
Questions?

gerardin.o@sfeir.lu
blog.gerardin.info
twitter: @ogerardin