GWT widget development
Even though widget libraries for GWT
exist, it’s sometimes necessary to
create a widget on your own...
http://pgt.de

PAPICK

http://oio.de

STEFFEN
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
Why widget development?
It’s all about having the choice
Choice of using existing
Choice of using existing
building your own
or buying.
or buying.
+ support
+ vendor lock-in
Freedom of choice?
We only have 60 Minutes

We must
assume
you are
not new to
GWT
Mission: give some directions
What are components?

com·po·nent
kəmˈpōnənt/

!

a part or element of a larger
whole, esp. a part of a
machine or vehicle...
What are UI components?
What for?

code
reuse

separation of
concerns
Code reuse?
Just import
library into
project, and
use this
progress
bar.
Don‘t
reinvent the
wheel,
unless it is
a better
w...
Code reuse by composition
... composition ...
separation of concerns?

The coders at 

gwt-bootstrap did
the progress bar
widget magic.!
!
I will never build
widgets!!!...
RIGHT?

Yes…!
!
But still…!
!
…third party widgets are generic components.
RIGHT?

Yes…!
!
But still…!
!
…third party widgets are generic components.
Don‘t use generic tools, unless you are Mac Gyver…

MAC GYVER
All he needed was a ball-point pen and a paper clip
Code duplication
Code duplication
You got the picture,

right?
You got the picture,

right?

Label

VerticalPanel
HorizontalPanel

VerticalPanel

HorizontalPanel

Label

Label

FlexTabl...
Unfortunately, we are modern Mac Gyvers!

<div />
WEB DEVELOPER
A div is all you need
GWT 

Efficiency
custom
components:
code reuse
+
separation of
concerns
+
composition
+
type safety
So what is a GWT Widget?
It‘s a JS thing holding a DOM element

<div />
Created to workaround IE6 memory leaks
Widgets are quite heavy weight
Each widget includes full event management...
...even if there is nothing to see
Custom components
‣ Increase efficiency in development!
‣ Domain driven!
‣ Avoid composition abuse!
‣ Implement custom des...
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
We are not Swing developers!
‣ GWT development is web development!
‣ GWT applications are JavaScript applications!
‣ GWT i...
JS Apps do DOM manipulation
‣ GWT widget API hides this from the user!
‣ Abuse of composition leads to heavy DOM manipulat...
DOM API
‣ Document Object Model!
‣ Representation of HTML document in memory!
– Tree stucture!

‣ Manipulation/creation of...
DOM API in GWT
DivElement	
  element	
  =	
  
	
  
	
  
Document.get().createDivElement();
element.appendChild(otherElemen...
DOM events
‣ Bubbling:!

!
The process by which an event propagates upward
!
through its ancestors after being handled by ...
DOM events
‣ Sinking:

Event.sinkEvents(element,	
  Event.ONCLICK);
Event.setEventListener(element,	
  new	
  
EventListen...
Reflows
‣ Layout update!
‣ DOM changes do not directly result in a visual/layout update!
– All Updates that occur in one J...
Distinct phases
!
!
!
!
!
!
‣ JS Execution!
‣ CSS/ Layout update!

Browsers are
single-threaded

‣ Render
!44
© 2013 Orien...
Hooks

idle

Scheduler.scheduleEntry();
GWT application code
.scheduleFinally();
Browser event loop
.scheduleDeferred();
JavaScript execution defers rendering
‣ Long lasting JS execution causes delay in rendering!
– The browser hangs...!

‣ Tr...
CSS
‣ Use CSS layouts to handle resizing without JavaScript!
‣ Bad CSS selectors can lead to slow down of rendering!
– Def...
Too many divs...
‣ Semantic markup !
– ul/li vs div/span!

‣ Accessibility!
– WAI-ARIA

!48
© 2013 Orientation in Objects ...
Compatibility

Source: http://caniuse.com
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
Bad Smell: refused bequest
Subclasses get to inherit the
methods and data of their
parents. But what if they
don’t want or...
WhatYouNeed(tm)

YourGreatWidget
Nooooooooo!!!!!!

FlexTable

YourGreatWidget
Don’t extend FlexTable

Flextable
Use a Composite, the thing holding a Widget

Widget
Use a Composite, the thing holding a Widget
The trick
Widget
The trick
Widget

Composite
The trick
Widget

Composite

YourGreatWidget
You end up exposing only widget + YourGreatInterface
Widget

Composite

YourGreatWidget
In a hurry?
Widget

Composite

YourGreatWidget

FlexTable
The trick
Widget

initWidget( flexThing )
Composite

YourGreatWidget

FlexTable
Internals are locked away
Widget

Composite

YourGreatWidget

FlexTable
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
GWT Widgets and DOM elements
GWT Widgets and DOM elements

div
input

div
GWT Widgets and DOM elements

SearchBox
div
input

div
GWT Widgets and DOM elements
‣ Two representations!
– Logical (Java)!
– Physical (HTML/DOM)

SearchBox
div
input

div

!68...
The contract of GWT widgets
‣ setElement(Element)!

!

Sets	
  this	
  object's	
  browser	
  element.	
  
! UIObject	
  s...
Widget lifecycle - Construction
public	
  Led()	
  {	
  
	
  	
  	
  setElement(Document.get().createDivElement());	
  
	
...
Widget lifecycle - Attach
‣ void onLoad()!

This	
  method	
  is	
  called	
  immediately	
  after	
  a	
  
!
widget	
  be...
Widget lifecycle - Detach
‣ void onUnload()!

This	
  method	
  is	
  called	
  immediately	
  before	
  a	
  
!
widget	
 ...
GWT Events
!
!
!
!
CloseEvent
!
!
‣

GWTEvent
JavaScriptObject
NativeEvent
OpenEvent

ResizeEvent

DOMEvent
BlurEvent

Nat...
Custom event development

Events between 

Widgets by sending

and listening to
GwtEvents
GwtEvent
GwtEvent

Event handlin...
Custom event development

Events between 

Widgets by sending

and listening to
GwtEvents

Event handling in 

the compone...
Basic handling of DOM events
public	
  Led()	
  {	
  
	
  	
  	
  sinkEvents(Event.ONCLICK);
}
!
@Override	
  
public	
  v...
Providing events to the user
@Override	
  
public	
  HandlerRegistration	
  addValueChangeHandler(
ValueChangeHandler<Bool...
Custom Events
generics...

GwtEvent

EventHandler

generics...

MyEvent

MyEventHandler
Define your own events: handler…
public	
  class	
  ExampleEvent	
  extends	
  
GwtEvent<ExampleEvent.Handler>	
  {

!

[…...
Define your own events: payload
public	
  class	
  ExampleEvent	
  extends	
  
GwtEvent<ExampleEvent.Handler>	
  {	
  

!
...
Define your own events: dispatching
public	
  class	
  ExampleEvent	
  extends	
  
GwtEvent<ExampleEvent.Handler>	
  {	
  ...
Define your own events: allow registration
public	
  HandlerRegistration	
  addExampleHandler(
ExampleHandler	
  handler)	...
Eventmanager

Event

?

Handler
Handler
Handler
Eventmanager

Event

!

Handler
Handler
Handler
Define your own events
public	
  class	
  ExampleEvent	
  extends	
  
GwtEvent<ExampleEvent.Handler>	
  {

!

	
  	
  	
  ...
Use GWT Optimizations
‣ ClientBundle!
‣ CSSResource!
‣ ImageResource

connection
bottleneck

HTTP 1.1!
8.1.4 Practical
Con...
Use GWT Optimizations
public	
  interface	
  Resources	
  extends	
  ClientBundle	
  {	
  
	
  	
  	
  @Source("SearchBox....
How to build widgets
‣ Manual DOM manipulation!
‣ UiBinder

!88
© 2013 Orientation in Objects GmbH
UiBinder
<ui:UiBinder	
  
xmlns:ui="urn:ui:com.google.gwt.uibinder"	
  
xmlns:g="urn:import:com.google.gwt.user.client.ui"...
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
Composite Pattern
‣ Something that contains widgets and IS a widget!
‣ We know that from other UI toolkits (e.g. Swing)!
‣...
We all did it already
verticalPanel.add(new	
  Label("Hello	
  GWT	
  world!"));
dockLayoutPanel.addWest(new	
  CustomerFo...
Widgets, panels and DOM elements
Panel

div
div

label
Label

div

input
TextBox
The magic behind it
‣ The Panel ensures that the widget‘s underlying DOM element is
correctly attached to the document!
‣ ...
The magic behind it
public	
  void	
  add(Widget	
  widget)	
  {	
  
	
  	
  	
  […]	
  
	
  	
  	
  element.appendChild(w...
Contract
public	
  interface	
  HasWidgets	
  extends	
  
Iterable<Widget>	
  {	
  
!
	
  	
  	
  void	
  add(Widget	
  w)...
Coding against interfaces is possible
public	
  interface	
  IsWidget	
  {
	
  	
  	
  Widget	
  asWidget();
}
interface	
...
Supporting UiBinder
‣ Supporting UiBinder is easy as long as we have ….!
– Default constructor!
– Default add method!

‣ W...
UiChild example
@UiChild	
  
public	
  void	
  addField(Widget	
  widget,	
  String	
  
label)	
  {	
  
	
  	
  	
  […]	
 ...
UiChild example
@UiChild	
  
public	
  void	
  addField(Widget	
  widget,	
  String	
  
label)	
  {	
  
	
  	
  	
  […]	
 ...
UiChild example
@UiChild	
  
public	
  void	
  addField(Widget	
  widget,	
  String	
  
label)	
  {	
  
	
  	
  	
  […]	
 ...
UiChild example
@UiChild	
  
public	
  void	
  addField(Widget	
  widget,	
  String	
  
label)	
  {	
  
	
  	
  	
  […]	
 ...
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
What about Layouts?

When we think

of layouts, we

think of structuring

the UI from

a bigger perspektive
Structuring

Relationship between
widgets,
MVP, Eventbus, etc...
!
!
Not here,
not now...
Positioning
JS positioning

CSS
Layout
Web page layouts

Desktop like, 

full page

Long page,

scroll up/ down

page
Standard widgets

Resize
inside out
Layout widgets
resize chaining
through

!

ProvidesResize
RequiresResize

!
!
!

Chaining is required,

resize event only
...
Full page application, inside out & outside in

RootLayoutPanel
Scrolling page application
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
Widgets do not scale…
Widgets do not scale…
Heap dumping

Total memory
No grid, mostly empty

Object count
4.8

> 98,000

15.6

> 570,000

Grid, Text

6.5

> 180,000
...
Why?
setInnerHtml,
job done

As with CSS: native vs JS

Many, many objects and 

DOM manipulation
Bonus feature
‣ SafeHTML provides some level 

of security against script injection!
‣ SafeHTML templates 

provides some ...
SafeHtmlTemplates
interface	
  MyTemplate	
  extends	
  

SafeHtmlTemplates	
  {
!
	
  	
  	
  @Template("<td>{0}</td>")
	...
Finally

NoWidgets

Layouts

Panels

Composite
Simple widgets

Committing to web development

Getting started
Go native whenever possible
‣ CSS is run natively by the browser!
‣ Optimize DOM manipulation by providing bigger HTML chu...
Separate browser specifics
Don‘t if – then – else for different browsers, use deferred binding

<replace-with class="de......
Avoid spaghetti code
‣ Try software engineering, it‘s ok!
‣ Many known patterns work well with GWT!
‣ If you don‘t know be...
SINGLETON
You must not public static instance
Thank you
for your
attention !
Upcoming SlideShare
Loading in...5
×

GWT widget development

2,446

Published on

Even though widget libraries for GWT exist, it’s sometimes necessary to create a widget on your own. Widget creation will confront you with challenges like GWT specifics or the way browsers work.
Participants will learn how to compose existing widgets as well as creating new ones based on DOM elements. As it is important to know how browsers behave, topics like DOM API, reflows and event propagation will be explained. But there are also GWT specific aspects, like important interfaces and classes or how to prevent code injection.

Published in: Technology
2 Comments
0 Likes
Statistics
Notes
  • Be the first to like this

No Downloads
Views
Total Views
2,446
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
0
Comments
2
Likes
0
Embeds 0
No embeds

No notes for slide

GWT widget development

  1. 1. GWT widget development Even though widget libraries for GWT exist, it’s sometimes necessary to create a widget on your own. Widget creation will confront you with challenges like GWT specifics or the way browsers work.! Participants will learn how to compose existing widgets as well as creating new ones based on DOM elements. As it is important to know how browsers behave, topics like DOM API, reflows and event propagation will be explained. But there are also GWT specific aspects, like important interfaces and classes or how to prevent code injection.
  2. 2. http://pgt.de PAPICK http://oio.de STEFFEN
  3. 3. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  4. 4. Why widget development?
  5. 5. It’s all about having the choice
  6. 6. Choice of using existing
  7. 7. Choice of using existing
  8. 8. building your own
  9. 9. or buying.
  10. 10. or buying. + support + vendor lock-in
  11. 11. Freedom of choice?
  12. 12. We only have 60 Minutes We must assume you are not new to GWT
  13. 13. Mission: give some directions
  14. 14. What are components? com·po·nent kəmˈpōnənt/ ! a part or element of a larger whole, esp. a part of a machine or vehicle.
  15. 15. What are UI components?
  16. 16. What for? code reuse separation of concerns
  17. 17. Code reuse? Just import library into project, and use this progress bar. Don‘t reinvent the wheel, unless it is a better wheel...
  18. 18. Code reuse by composition
  19. 19. ... composition ...
  20. 20. separation of concerns? The coders at 
 gwt-bootstrap did the progress bar widget magic.! ! I will never build widgets!!!! ! It is not of my concern. I simply use them!!!
  21. 21. RIGHT? Yes…! ! But still…! ! …third party widgets are generic components.
  22. 22. RIGHT? Yes…! ! But still…! ! …third party widgets are generic components.
  23. 23. Don‘t use generic tools, unless you are Mac Gyver… MAC GYVER All he needed was a ball-point pen and a paper clip
  24. 24. Code duplication
  25. 25. Code duplication
  26. 26. You got the picture,
 right?
  27. 27. You got the picture,
 right? Label VerticalPanel HorizontalPanel VerticalPanel HorizontalPanel Label Label FlexTable FlexTable VerticalPanel HorizontalPanel FlexTable HorizontalPanel Label Label Label
  28. 28. Unfortunately, we are modern Mac Gyvers! <div /> WEB DEVELOPER A div is all you need
  29. 29. GWT 
 Efficiency custom components: code reuse + separation of concerns + composition + type safety
  30. 30. So what is a GWT Widget?
  31. 31. It‘s a JS thing holding a DOM element <div />
  32. 32. Created to workaround IE6 memory leaks
  33. 33. Widgets are quite heavy weight
  34. 34. Each widget includes full event management... ...even if there is nothing to see
  35. 35. Custom components ‣ Increase efficiency in development! ‣ Domain driven! ‣ Avoid composition abuse! ‣ Implement custom design! ‣ Create more effective widgets! ‣ Cheaper in the long run !35 © 2013 Orientation in Objects GmbH
  36. 36. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  37. 37. We are not Swing developers! ‣ GWT development is web development! ‣ GWT applications are JavaScript applications! ‣ GWT is very good at hiding this! ‣ We can deny knowledge about it! ‣ … but not forever Java JavaScript !37 © 2013 Orientation in Objects GmbH
  38. 38. JS Apps do DOM manipulation ‣ GWT widget API hides this from the user! ‣ Abuse of composition leads to heavy DOM manipulation! ‣ Custom components are important, and there are things that we should be aware of... © 2013 Orientation in Objects GmbH !38
  39. 39. DOM API ‣ Document Object Model! ‣ Representation of HTML document in memory! – Tree stucture! ‣ Manipulation/creation of elements! ‣ Navigation of elements !39 © 2013 Orientation in Objects GmbH
  40. 40. DOM API in GWT DivElement  element  =       Document.get().createDivElement(); element.appendChild(otherElement); element.getChild(0); element.removeChild(otherElement);
  41. 41. DOM events ‣ Bubbling:! ! The process by which an event propagates upward ! through its ancestors after being handled by the event's ! target. ! Source: http://www.w3.org/TR/DOM-Level-2-Events/events.htm#Events-overview-terminology ! ‣ Event.stopPropagation! – The event won‘t be delivered to listeners of ancestors! ! ‣ Event.preventDefault! – Prevents default browser behavior !41 © 2013 Orientation in Objects GmbH
  42. 42. DOM events ‣ Sinking: Event.sinkEvents(element,  Event.ONCLICK); Event.setEventListener(element,  new   EventListener()  {      @Override        public  void  onBrowserEvent(Event  event)  {            if  (event.getTypeInt()  ==  Event.ONCLICK)  {                  […]            }      } }); !42 © 2013 Orientation in Objects GmbH
  43. 43. Reflows ‣ Layout update! ‣ DOM changes do not directly result in a visual/layout update! – All Updates that occur in one JS execution result in one update! ‣ Effective size and position of elements are only available after update !43 © 2013 Orientation in Objects GmbH
  44. 44. Distinct phases ! ! ! ! ! ! ‣ JS Execution! ‣ CSS/ Layout update! Browsers are single-threaded ‣ Render !44 © 2013 Orientation in Objects GmbH
  45. 45. Hooks idle Scheduler.scheduleEntry(); GWT application code .scheduleFinally(); Browser event loop .scheduleDeferred();
  46. 46. JavaScript execution defers rendering ‣ Long lasting JS execution causes delay in rendering! – The browser hangs...! ‣ Try to keep JS execution short! – Execute incrementally! – Animations! ‣ Try to avoid JS executions !46 © 2013 Orientation in Objects GmbH
  47. 47. CSS ‣ Use CSS layouts to handle resizing without JavaScript! ‣ Bad CSS selectors can lead to slow down of rendering! – Define the right most selector as specific as possible! – Avoid selectors that are too complex! – […]! ‣ Try to express states as CSS classes CSS is the new 
 native !47 © 2013 Orientation in Objects GmbH
  48. 48. Too many divs... ‣ Semantic markup ! – ul/li vs div/span! ‣ Accessibility! – WAI-ARIA !48 © 2013 Orientation in Objects GmbH
  49. 49. Compatibility Source: http://caniuse.com
  50. 50. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  51. 51. Bad Smell: refused bequest Subclasses get to inherit the methods and data of their parents. But what if they don’t want or need what they are given? They are given all these great gifts and pick just a few to play with. ! The traditional story is that this means the hierarchy is wrong. http://sourcemaking.com/refactoring/refused-bequest 978-0201485677
  52. 52. WhatYouNeed(tm) YourGreatWidget
  53. 53. Nooooooooo!!!!!! FlexTable YourGreatWidget
  54. 54. Don’t extend FlexTable Flextable
  55. 55. Use a Composite, the thing holding a Widget Widget
  56. 56. Use a Composite, the thing holding a Widget
  57. 57. The trick Widget
  58. 58. The trick Widget Composite
  59. 59. The trick Widget Composite YourGreatWidget
  60. 60. You end up exposing only widget + YourGreatInterface Widget Composite YourGreatWidget
  61. 61. In a hurry? Widget Composite YourGreatWidget FlexTable
  62. 62. The trick Widget initWidget( flexThing ) Composite YourGreatWidget FlexTable
  63. 63. Internals are locked away Widget Composite YourGreatWidget FlexTable
  64. 64. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  65. 65. GWT Widgets and DOM elements
  66. 66. GWT Widgets and DOM elements div input div
  67. 67. GWT Widgets and DOM elements SearchBox div input div
  68. 68. GWT Widgets and DOM elements ‣ Two representations! – Logical (Java)! – Physical (HTML/DOM) SearchBox div input div !68 © 2013 Orientation in Objects GmbH
  69. 69. The contract of GWT widgets ‣ setElement(Element)! ! Sets  this  object's  browser  element.   ! UIObject  subclasses  must  call  this   method  before  attempting  to  call  any   ! other  methods,  and  it  may  only  be   ! called  once. ! ! ! ‣ To be on the safe side: do it in the constructor !69 © 2013 Orientation in Objects GmbH
  70. 70. Widget lifecycle - Construction public  Led()  {        setElement(Document.get().createDivElement());        setStyleName(getResources().style().led());        […]   }
  71. 71. Widget lifecycle - Attach ‣ void onLoad()! This  method  is  called  immediately  after  a   ! widget  becomes  attached  to  the  browser's   document. ! ‣ AttachEvent.Handler.onAttachOrDetach(…) Fired  when  the  event  source  is  attached  to  the   browser's  document  or  detached  from  it. !71 © 2013 Orientation in Objects GmbH
  72. 72. Widget lifecycle - Detach ‣ void onUnload()! This  method  is  called  immediately  before  a   ! widget  will  be  detached  from  the  browser's   document. ! ‣ AttachEvent.Handler.onAttachOrDetach(…) Fired  when  the  event  source  is  attached  to  the   browser's  document  or  detached  from  it. !72 © 2013 Orientation in Objects GmbH
  73. 73. GWT Events ! ! ! ! CloseEvent ! ! ‣ GWTEvent JavaScriptObject NativeEvent OpenEvent ResizeEvent DOMEvent BlurEvent Native events are not enough!! – Tab selection?! ‣ SelectionEvent ! Fire existing GwtEvents! HasNativeEvent FocusEvent ChangeEvent KeyEvent – SelectionEvent! – SelectionChangeEvent! – ValueChangeEvent! ‣ ! If none matches your use-case: define your own! !73 © 2013 Orientation in Objects GmbH
  74. 74. Custom event development Events between 
 Widgets by sending
 and listening to GwtEvents GwtEvent GwtEvent Event handling in 
 the component, listen to 
 native events Event onBrowserEvent(Event event)
  75. 75. Custom event development Events between 
 Widgets by sending
 and listening to GwtEvents Event handling in 
 the component, listen to 
 native events ValueChangeEvent Event LEDActivationEvent Event.ONCLICK, 
 Event.ONKEYDOWN
  76. 76. Basic handling of DOM events public  Led()  {        sinkEvents(Event.ONCLICK); } ! @Override   public  void  onBrowserEvent(Event  event)  {      if  (event.getTypeInt()  ==  Event.ONCLICK)  {            toggleLed();      }      […] }
  77. 77. Providing events to the user @Override   public  HandlerRegistration  addValueChangeHandler( ValueChangeHandler<Boolean>  handler)  {      return  addHandler(handler,                            ValueChangeEvent.getType()); } ! @Override   public  void  setValue(Boolean  value,  boolean  fireEvents)  {      this.value  =  value;        if(fireEvents)  {            ValueChangeEvent.fire(this,  value);      } }
  78. 78. Custom Events generics... GwtEvent EventHandler generics... MyEvent MyEventHandler
  79. 79. Define your own events: handler… public  class  ExampleEvent  extends   GwtEvent<ExampleEvent.Handler>  { ! […] ! !      public  interface  Handler  extends  EventHandler  {            void  onSomethingHappened(ExampleEvent  event);      } ! […] ! }
  80. 80. Define your own events: payload public  class  ExampleEvent  extends   GwtEvent<ExampleEvent.Handler>  {   ! […] !      private  final  int  value;        public  ExampleEvent(int  value)  {            this.value  =  value;      }   !      public  int  getValue()  {            return  value;      }   ! ! } […]
  81. 81. Define your own events: dispatching public  class  ExampleEvent  extends   GwtEvent<ExampleEvent.Handler>  {   ! […] ! !      protected  void  dispatch(Handler  handler)  {            handler.onSomethingHappened(this);      } ! ! } […]
  82. 82. Define your own events: allow registration public  HandlerRegistration  addExampleHandler( ExampleHandler  handler)  {      return  addHandler(handler,  ExampleEvent.getType()); }
  83. 83. Eventmanager Event ? Handler Handler Handler
  84. 84. Eventmanager Event ! Handler Handler Handler
  85. 85. Define your own events public  class  ExampleEvent  extends   GwtEvent<ExampleEvent.Handler>  { !      private  static  Type<ExampleEvent.Handler>  type; !      public  static  Type<ExampleEvent.Handler>  getType()  {            if  (type  ==  null)  {                  type  =  new  Type<ExampleEvent.Handler>();            }            return  type;      }      @Override        public  Type<Handler>  getAssociatedType()  {            return  getType();      } }
  86. 86. Use GWT Optimizations ‣ ClientBundle! ‣ CSSResource! ‣ ImageResource connection bottleneck HTTP 1.1! 8.1.4 Practical Considerations! A single-user client SHOULD NOT maintain more than 2 connections © 2013 Orientation in Objects GmbH with any server or proxy. !86
  87. 87. Use GWT Optimizations public  interface  Resources  extends  ClientBundle  {        @Source("SearchBox.css")        Style  style();   !      @Source("search.png")        ImageResource  search();   }   ! public  interface  Style  extends  CssResource  {        String  root();        String  text();        String  icon();   }
  88. 88. How to build widgets ‣ Manual DOM manipulation! ‣ UiBinder !88 © 2013 Orientation in Objects GmbH
  89. 89. UiBinder <ui:UiBinder   xmlns:ui="urn:ui:com.google.gwt.uibinder"   xmlns:g="urn:import:com.google.gwt.user.client.ui" >        <ui:with  type=„[…]"  field="style"></ui:with>        <div  class="{style.root}">              <input  type="text"  class="{style.text}"  />              <div  class="{style.icon}"></div>        </div>   </ui:UiBinder>  
  90. 90. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  91. 91. Composite Pattern ‣ Something that contains widgets and IS a widget! ‣ We know that from other UI toolkits (e.g. Swing)! ‣ In GWT we use **Panels for this !91 © 2013 Orientation in Objects GmbH
  92. 92. We all did it already verticalPanel.add(new  Label("Hello  GWT  world!")); dockLayoutPanel.addWest(new  CustomerForm(),  300); headerPanel.setContentWidget(new  CustomerForm());
  93. 93. Widgets, panels and DOM elements Panel div div label Label div input TextBox
  94. 94. The magic behind it ‣ The Panel ensures that the widget‘s underlying DOM element is correctly attached to the document! ‣ Structure of logical and physical representation 
 must be consistent !94 © 2013 Orientation in Objects GmbH
  95. 95. The magic behind it public  void  add(Widget  widget)  {        […]        element.appendChild(widget.getElement());        adopt(widget);        […]   }
  96. 96. Contract public  interface  HasWidgets  extends   Iterable<Widget>  {   !      void  add(Widget  w); !      void  clear(); !      Iterator<Widget>  iterator(); !      boolean  remove(Widget  w); }
  97. 97. Coding against interfaces is possible public  interface  IsWidget  {      Widget  asWidget(); } interface  ForIsWidget  extends  HasWidgets  {      void  add(IsWidget  w); !      boolean  remove(IsWidget  w); }
  98. 98. Supporting UiBinder ‣ Supporting UiBinder is easy as long as we have ….! – Default constructor! – Default add method! ‣ We can improve the UiBinder compatibility of our widgets! – @UiConstructor! – @UiChild !98 © 2013 Orientation in Objects GmbH
  99. 99. UiChild example @UiChild   public  void  addField(Widget  widget,  String   label)  {        […]   } <ui:UiBinder  […]  xmlns:oio="urn:import:[…]">        <oio:SimpleFormPanel>              <oio:field  label="Firstname">                    <g:TextBox  />              </oio:field>        </oio:SimpleFormPanel>   </ui:UiBinder>  
  100. 100. UiChild example @UiChild   public  void  addField(Widget  widget,  String   label)  {        […]   } <ui:UiBinder  […]  xmlns:oio="urn:import:[…]">        <oio:SimpleFormPanel>              <oio:field  label="Firstname">                    <g:TextBox  />              </oio:field>        </oio:SimpleFormPanel>   </ui:UiBinder>  
  101. 101. UiChild example @UiChild   public  void  addField(Widget  widget,  String   label)  {        […]   } <ui:UiBinder  […]  xmlns:oio="urn:import:[…]">        <oio:SimpleFormPanel>              <oio:field  label="Firstname">                    <g:TextBox  />              </oio:field>        </oio:SimpleFormPanel>   </ui:UiBinder>  
  102. 102. UiChild example @UiChild   public  void  addField(Widget  widget,  String   label)  {        […]   } <ui:UiBinder  […]  xmlns:oio="urn:import:[…]">        <oio:SimpleFormPanel>              <oio:field  label="Firstname">                    <g:TextBox  />              </oio:field>        </oio:SimpleFormPanel>   </ui:UiBinder>  
  103. 103. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  104. 104. What about Layouts? When we think
 of layouts, we
 think of structuring
 the UI from
 a bigger perspektive
  105. 105. Structuring Relationship between widgets, MVP, Eventbus, etc... ! ! Not here, not now...
  106. 106. Positioning JS positioning CSS Layout
  107. 107. Web page layouts Desktop like, 
 full page Long page,
 scroll up/ down
 page
  108. 108. Standard widgets Resize inside out
  109. 109. Layout widgets resize chaining through ! ProvidesResize RequiresResize ! ! ! Chaining is required,
 resize event only top level, not propagated by browser Resize outside in
  110. 110. Full page application, inside out & outside in RootLayoutPanel
  111. 111. Scrolling page application
  112. 112. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  113. 113. Widgets do not scale…
  114. 114. Widgets do not scale…
  115. 115. Heap dumping Total memory No grid, mostly empty Object count 4.8 > 98,000 15.6 > 570,000 Grid, Text 6.5 > 180,000 SafeHTML 4.9 > 99,000 Grid, Widgets
  116. 116. Why? setInnerHtml, job done As with CSS: native vs JS Many, many objects and 
 DOM manipulation
  117. 117. Bonus feature ‣ SafeHTML provides some level 
 of security against script injection! ‣ SafeHTML templates 
 provides some 
 pain easing in HTML
 development! ‣ Getting used to SafeHTML 
 ! helps getting used to cell widgets, 
 ! ! helps getting used to cell grids, … © 2013 Orientation in Objects GmbH !117
  118. 118. SafeHtmlTemplates interface  MyTemplate  extends  
 SafeHtmlTemplates  { !      @Template("<td>{0}</td>")      SafeHtml  cell(String  content); !      @Template("<tr>{0}</tr>")      SafeHtml  row(SafeHtml  cells); !      @Template("<table>{0}</table>")      SafeHtml  table(SafeHtml  rows);   }
  119. 119. Finally NoWidgets Layouts Panels Composite Simple widgets Committing to web development Getting started
  120. 120. Go native whenever possible ‣ CSS is run natively by the browser! ‣ Optimize DOM manipulation by providing bigger HTML chunks 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 010101010101010101010101010101010101010101010101 !120 © 2013 Orientation in Objects GmbH
  121. 121. Separate browser specifics Don‘t if – then – else for different browsers, use deferred binding <replace-with class="de...MyEntryPointIE"> <when-type-is class="de...MyEntryPointDefault" /> <any> <when-property-is name="user.agent" value="ie6" /> <when-property-is name="user.agent" value="ie8" /> <when-property-is name="user.agent" value="ie9" /> <when-property-is name="user.agent" value="opera" /> </any> </replace-with> !121 © 2013 Orientation in Objects GmbH
  122. 122. Avoid spaghetti code ‣ Try software engineering, it‘s ok! ‣ Many known patterns work well with GWT! ‣ If you don‘t know better, use MVP !122 © 2013 Orientation in Objects GmbH
  123. 123. SINGLETON You must not public static instance
  124. 124. Thank you for your attention !

×