SlideShare a Scribd company logo
1 of 124
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.
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
wheel...
Code reuse by composition
... composition ...
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!!!
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

FlexTable

FlexTable

VerticalPanel

HorizontalPanel

FlexTable

HorizontalPanel

Label

Label

Label
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 design!
‣ Create more effective widgets!
‣ Cheaper in the long run

!35
© 2013 Orientation in Objects GmbH
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 is very good at hiding this!
‣ We can deny knowledge about it!
‣ … but not forever

Java

JavaScript
!37

© 2013 Orientation in Objects GmbH
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
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
DOM API in GWT
DivElement	
  element	
  =	
  
	
  
	
  
Document.get().createDivElement();
element.appendChild(otherElement);
element.getChild(0);
element.removeChild(otherElement);
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
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
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
Distinct phases
!
!
!
!
!
!
‣ JS Execution!
‣ CSS/ Layout update!

Browsers are
single-threaded

‣ Render
!44
© 2013 Orientation in Objects GmbH
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...!

‣ Try to keep JS execution short!
– Execute incrementally!
– Animations!

‣ Try to avoid JS executions

!46
© 2013 Orientation in Objects GmbH
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
Too many divs...
‣ Semantic markup !
– ul/li vs div/span!

‣ Accessibility!
– WAI-ARIA

!48
© 2013 Orientation in Objects GmbH
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 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
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
© 2013 Orientation in Objects GmbH
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
Widget lifecycle - Construction
public	
  Led()	
  {	
  
	
  	
  	
  setElement(Document.get().createDivElement());	
  
	
  	
  	
  setStyleName(getResources().style().led());	
  
	
  	
  	
  […]	
  
}
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
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
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
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)
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
Basic handling of DOM events
public	
  Led()	
  {	
  
	
  	
  	
  sinkEvents(Event.ONCLICK);
}
!
@Override	
  
public	
  void	
  onBrowserEvent(Event	
  event)	
  {
	
  	
  	
  if	
  (event.getTypeInt()	
  ==	
  Event.ONCLICK)	
  {
	
  	
  	
  	
  	
  	
  toggleLed();
	
  	
  	
  }
	
  	
  	
  […]
}
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);
	
  	
  	
  }
}
Custom Events
generics...

GwtEvent

EventHandler

generics...

MyEvent

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

!

[…]

!
!
	
  	
  	
  public	
  interface	
  Handler	
  extends	
  EventHandler	
  {
	
  	
  	
  	
  	
  	
  void	
  onSomethingHappened(ExampleEvent	
  event);
	
  	
  	
  }

!
[…]

!

}
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;
	
  	
  	
  }	
  

!
!

}

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

!

[…]

!
!
	
  	
  	
  protected	
  void	
  dispatch(Handler	
  handler)	
  {
	
  	
  	
  	
  	
  	
  handler.onSomethingHappened(this);
	
  	
  	
  }

!
!
}

[…]
Define your own events: allow registration
public	
  HandlerRegistration	
  addExampleHandler(
ExampleHandler	
  handler)	
  {
	
  	
  	
  return	
  addHandler(handler,	
  ExampleEvent.getType());
}
Eventmanager

Event

?

Handler
Handler
Handler
Eventmanager

Event

!

Handler
Handler
Handler
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();
	
  	
  	
  }
}
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
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();	
  
}
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"
>	
  
	
  	
  	
  <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>	
  
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)!
‣ In GWT we use **Panels for this

!91
© 2013 Orientation in Objects GmbH
We all did it already
verticalPanel.add(new	
  Label("Hello	
  GWT	
  world!"));
dockLayoutPanel.addWest(new	
  CustomerForm(),	
  300);
headerPanel.setContentWidget(new	
  CustomerForm());
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!
‣ Structure of logical and physical representation 

must be consistent

!94
© 2013 Orientation in Objects GmbH
The magic behind it
public	
  void	
  add(Widget	
  widget)	
  {	
  
	
  	
  	
  […]	
  
	
  	
  	
  element.appendChild(widget.getElement());	
  
	
  	
  	
  adopt(widget);	
  
	
  	
  	
  […]	
  
}
Contract
public	
  interface	
  HasWidgets	
  extends	
  
Iterable<Widget>	
  {	
  
!
	
  	
  	
  void	
  add(Widget	
  w);
!
	
  	
  	
  void	
  clear();
!
	
  	
  	
  Iterator<Widget>	
  iterator();
!
	
  	
  	
  boolean	
  remove(Widget	
  w);
}
Coding against interfaces is possible
public	
  interface	
  IsWidget	
  {
	
  	
  	
  Widget	
  asWidget();
}
interface	
  ForIsWidget	
  extends	
  HasWidgets	
  {
	
  	
  	
  void	
  add(IsWidget	
  w);
!
	
  	
  	
  boolean	
  remove(IsWidget	
  w);
}
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
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>	
  
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>	
  
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>	
  
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>	
  
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
top level, not
propagated by
browser

Resize outside in
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

SafeHTML

4.9

> 99,000

Grid, Widgets
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 

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
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);	
  
}
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 chunks

010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010101
!120
© 2013 Orientation in Objects GmbH
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
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
SINGLETON
You must not public static instance
Thank you
for your
attention !

More Related Content

What's hot

Building native Win8 apps with YUI
Building native Win8 apps with YUIBuilding native Win8 apps with YUI
Building native Win8 apps with YUITilo Mitra
 
Web Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xWeb Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xPatrickHillert
 
JHipster for Spring Boot webinar
JHipster for Spring Boot webinarJHipster for Spring Boot webinar
JHipster for Spring Boot webinarJulien Dubois
 
VueJS Introduction
VueJS IntroductionVueJS Introduction
VueJS IntroductionDavid Ličen
 
Scalable Front-end Development with Vue.JS
Scalable Front-end Development with Vue.JSScalable Front-end Development with Vue.JS
Scalable Front-end Development with Vue.JSGalih Pratama
 
Korea linuxforum2014 html5game-sangseoklim
Korea linuxforum2014 html5game-sangseoklimKorea linuxforum2014 html5game-sangseoklim
Korea linuxforum2014 html5game-sangseoklimSang Seok Lim
 
Knockout mvvm-m1-slides
Knockout mvvm-m1-slidesKnockout mvvm-m1-slides
Knockout mvvm-m1-slidesMasterCode.vn
 
The Superhero’s Method of Modern HTML5 Development by RapidValue Solutions
The Superhero’s Method of Modern HTML5 Development by RapidValue SolutionsThe Superhero’s Method of Modern HTML5 Development by RapidValue Solutions
The Superhero’s Method of Modern HTML5 Development by RapidValue SolutionsRapidValue
 
What Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 AppsWhat Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 AppsDoris Chen
 
HTML5 Introduction
HTML5 IntroductionHTML5 Introduction
HTML5 Introductionbeforeach
 
GWT - AppDays - (25 aprile 2014, pordenone)
GWT - AppDays - (25 aprile 2014, pordenone)GWT - AppDays - (25 aprile 2014, pordenone)
GWT - AppDays - (25 aprile 2014, pordenone)firenze-gtug
 
Design Patterns every Android developer should know
Design Patterns every Android developer should knowDesign Patterns every Android developer should know
Design Patterns every Android developer should knowmuratcanbur
 
課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)
課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)
課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)Jollen Chen
 
GWT 2.0 - December 15 2009
GWT 2.0 - December 15 2009GWT 2.0 - December 15 2009
GWT 2.0 - December 15 2009sullis
 
Room with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.jsRoom with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.jsZachary Klein
 

What's hot (16)

Building native Win8 apps with YUI
Building native Win8 apps with YUIBuilding native Win8 apps with YUI
Building native Win8 apps with YUI
 
Web Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.xWeb Components mit Polymer und AngularJS 1.x
Web Components mit Polymer und AngularJS 1.x
 
JHipster for Spring Boot webinar
JHipster for Spring Boot webinarJHipster for Spring Boot webinar
JHipster for Spring Boot webinar
 
VueJS Introduction
VueJS IntroductionVueJS Introduction
VueJS Introduction
 
Scalable Front-end Development with Vue.JS
Scalable Front-end Development with Vue.JSScalable Front-end Development with Vue.JS
Scalable Front-end Development with Vue.JS
 
Korea linuxforum2014 html5game-sangseoklim
Korea linuxforum2014 html5game-sangseoklimKorea linuxforum2014 html5game-sangseoklim
Korea linuxforum2014 html5game-sangseoklim
 
Knockout mvvm-m1-slides
Knockout mvvm-m1-slidesKnockout mvvm-m1-slides
Knockout mvvm-m1-slides
 
The Superhero’s Method of Modern HTML5 Development by RapidValue Solutions
The Superhero’s Method of Modern HTML5 Development by RapidValue SolutionsThe Superhero’s Method of Modern HTML5 Development by RapidValue Solutions
The Superhero’s Method of Modern HTML5 Development by RapidValue Solutions
 
What Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 AppsWhat Web Developers Need to Know to Develop Windows 8 Apps
What Web Developers Need to Know to Develop Windows 8 Apps
 
HTML5 Introduction
HTML5 IntroductionHTML5 Introduction
HTML5 Introduction
 
GWT - AppDays - (25 aprile 2014, pordenone)
GWT - AppDays - (25 aprile 2014, pordenone)GWT - AppDays - (25 aprile 2014, pordenone)
GWT - AppDays - (25 aprile 2014, pordenone)
 
The WebKit project
The WebKit projectThe WebKit project
The WebKit project
 
Design Patterns every Android developer should know
Design Patterns every Android developer should knowDesign Patterns every Android developer should know
Design Patterns every Android developer should know
 
課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)
課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)
課程名稱:八屏一雲時代來臨 教你HTML5六小時打通(3)
 
GWT 2.0 - December 15 2009
GWT 2.0 - December 15 2009GWT 2.0 - December 15 2009
GWT 2.0 - December 15 2009
 
Room with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.jsRoom with a Vue - Introduction to Vue.js
Room with a Vue - Introduction to Vue.js
 

Similar to GWT widget development

GWT + Gears : The browser is the platform
GWT + Gears : The browser is the platformGWT + Gears : The browser is the platform
GWT + Gears : The browser is the platformDidier Girard
 
GWT - Building Rich Internet Applications Using OO Tools
GWT - Building Rich Internet Applications Using OO ToolsGWT - Building Rich Internet Applications Using OO Tools
GWT - Building Rich Internet Applications Using OO Toolsbarciszewski
 
Desktop apps with node webkit
Desktop apps with node webkitDesktop apps with node webkit
Desktop apps with node webkitPaul Jensen
 
BOF-5110 Extending the Groovy SwingBuilder
BOF-5110 Extending the Groovy SwingBuilderBOF-5110 Extending the Groovy SwingBuilder
BOF-5110 Extending the Groovy SwingBuilderDanno Ferrin
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2JooinK
 
Curious Coders Java Web Frameworks Comparison
Curious Coders Java Web Frameworks ComparisonCurious Coders Java Web Frameworks Comparison
Curious Coders Java Web Frameworks ComparisonHamed Hatami
 
Building Rich User Experiences Without JavaScript Spaghetti
Building Rich User Experiences Without JavaScript SpaghettiBuilding Rich User Experiences Without JavaScript Spaghetti
Building Rich User Experiences Without JavaScript SpaghettiJared Faris
 
JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!_Dewy_
 
Headless browser: puppeteer and git client : GitKraken
Headless browser: puppeteer and git client : GitKrakenHeadless browser: puppeteer and git client : GitKraken
Headless browser: puppeteer and git client : GitKrakenSheikhMoonwaraAnjumM
 
Android Jump Start
Android Jump StartAndroid Jump Start
Android Jump StartHaim Michael
 
Javaland 2014 / GWT architectures and lessons learned
Javaland 2014 / GWT architectures and lessons learnedJavaland 2014 / GWT architectures and lessons learned
Javaland 2014 / GWT architectures and lessons learnedpgt technology scouting GmbH
 
Prototyping app using JS and HTML5 (Ciklum Kharkiv)
Prototyping app using JS and HTML5 (Ciklum Kharkiv)Prototyping app using JS and HTML5 (Ciklum Kharkiv)
Prototyping app using JS and HTML5 (Ciklum Kharkiv)Yuriy Silvestrov
 
Meet Magento Spain 2019 - Our Experience with Magento Cloud
Meet Magento Spain 2019 - Our Experience with Magento CloudMeet Magento Spain 2019 - Our Experience with Magento Cloud
Meet Magento Spain 2019 - Our Experience with Magento CloudLyzun Oleksandr
 
Gwt kickoff - Alberto Mancini & Francesca Tosi
Gwt kickoff - Alberto Mancini & Francesca TosiGwt kickoff - Alberto Mancini & Francesca Tosi
Gwt kickoff - Alberto Mancini & Francesca Tosifirenze-gtug
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]GDSC UofT Mississauga
 

Similar to GWT widget development (20)

GWT + Gears : The browser is the platform
GWT + Gears : The browser is the platformGWT + Gears : The browser is the platform
GWT + Gears : The browser is the platform
 
GWT Architectures and Lessons Learned (WJAX 2013)
GWT Architectures and Lessons Learned (WJAX 2013)GWT Architectures and Lessons Learned (WJAX 2013)
GWT Architectures and Lessons Learned (WJAX 2013)
 
GWT - Building Rich Internet Applications Using OO Tools
GWT - Building Rich Internet Applications Using OO ToolsGWT - Building Rich Internet Applications Using OO Tools
GWT - Building Rich Internet Applications Using OO Tools
 
Desktop apps with node webkit
Desktop apps with node webkitDesktop apps with node webkit
Desktop apps with node webkit
 
BOF-5110 Extending the Groovy SwingBuilder
BOF-5110 Extending the Groovy SwingBuilderBOF-5110 Extending the Groovy SwingBuilder
BOF-5110 Extending the Groovy SwingBuilder
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2
 
Curious Coders Java Web Frameworks Comparison
Curious Coders Java Web Frameworks ComparisonCurious Coders Java Web Frameworks Comparison
Curious Coders Java Web Frameworks Comparison
 
Web summit.pptx
Web summit.pptxWeb summit.pptx
Web summit.pptx
 
Building Rich User Experiences Without JavaScript Spaghetti
Building Rich User Experiences Without JavaScript SpaghettiBuilding Rich User Experiences Without JavaScript Spaghetti
Building Rich User Experiences Without JavaScript Spaghetti
 
JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!
 
Headless browser: puppeteer and git client : GitKraken
Headless browser: puppeteer and git client : GitKrakenHeadless browser: puppeteer and git client : GitKraken
Headless browser: puppeteer and git client : GitKraken
 
20120308 droid4me-paug presentation
20120308 droid4me-paug presentation20120308 droid4me-paug presentation
20120308 droid4me-paug presentation
 
Android Jump Start
Android Jump StartAndroid Jump Start
Android Jump Start
 
Javaland 2014 / GWT architectures and lessons learned
Javaland 2014 / GWT architectures and lessons learnedJavaland 2014 / GWT architectures and lessons learned
Javaland 2014 / GWT architectures and lessons learned
 
Prototyping app using JS and HTML5 (Ciklum Kharkiv)
Prototyping app using JS and HTML5 (Ciklum Kharkiv)Prototyping app using JS and HTML5 (Ciklum Kharkiv)
Prototyping app using JS and HTML5 (Ciklum Kharkiv)
 
Real solutions, no tricks
Real solutions, no tricksReal solutions, no tricks
Real solutions, no tricks
 
Meet Magento Spain 2019 - Our Experience with Magento Cloud
Meet Magento Spain 2019 - Our Experience with Magento CloudMeet Magento Spain 2019 - Our Experience with Magento Cloud
Meet Magento Spain 2019 - Our Experience with Magento Cloud
 
Gwt kickoff - Alberto Mancini & Francesca Tosi
Gwt kickoff - Alberto Mancini & Francesca TosiGwt kickoff - Alberto Mancini & Francesca Tosi
Gwt kickoff - Alberto Mancini & Francesca Tosi
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
Vaadin Jump Start
Vaadin Jump StartVaadin Jump Start
Vaadin Jump Start
 

More from pgt technology scouting GmbH

More from pgt technology scouting GmbH (6)

Client-Server-Kommunikation mit dem Command Pattern
Client-Server-Kommunikation mit dem Command PatternClient-Server-Kommunikation mit dem Command Pattern
Client-Server-Kommunikation mit dem Command Pattern
 
GWT architecture best practices and lessons learned
GWT architecture best practices and lessons learnedGWT architecture best practices and lessons learned
GWT architecture best practices and lessons learned
 
GWT - building a better web
GWT - building a better web GWT - building a better web
GWT - building a better web
 
Modularization in java 8
Modularization in java 8Modularization in java 8
Modularization in java 8
 
Gwt, die bessere spinne
Gwt, die bessere spinneGwt, die bessere spinne
Gwt, die bessere spinne
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 

Recently uploaded

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
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
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
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
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
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
 
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
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 

Recently uploaded (20)

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
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
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
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
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
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
 
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
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 

GWT widget development

  • 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.
  • 5. It’s all about having the choice
  • 6. Choice of using existing
  • 7. Choice of using existing
  • 10. or buying. + support + vendor lock-in
  • 12. We only have 60 Minutes We must assume you are not new to GWT
  • 13. Mission: give some directions
  • 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. What are UI components?
  • 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. Code reuse by composition
  • 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. RIGHT? Yes…! ! But still…! ! …third party widgets are generic components.
  • 22. RIGHT? Yes…! ! But still…! ! …third party widgets are generic components.
  • 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
  • 26. You got the picture,
 right?
  • 27. You got the picture,
 right? Label VerticalPanel HorizontalPanel VerticalPanel HorizontalPanel Label Label FlexTable FlexTable VerticalPanel HorizontalPanel FlexTable HorizontalPanel Label Label Label
  • 28. Unfortunately, we are modern Mac Gyvers! <div /> WEB DEVELOPER A div is all you need
  • 29. GWT 
 Efficiency custom components: code reuse + separation of concerns + composition + type safety
  • 30. So what is a GWT Widget?
  • 31. It‘s a JS thing holding a DOM element <div />
  • 32. Created to workaround IE6 memory leaks
  • 33. Widgets are quite heavy weight
  • 34. Each widget includes full event management... ...even if there is nothing to see
  • 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
  • 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. 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. 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. DOM API in GWT DivElement  element  =       Document.get().createDivElement(); element.appendChild(otherElement); element.getChild(0); element.removeChild(otherElement);
  • 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. 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. 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. Distinct phases ! ! ! ! ! ! ‣ JS Execution! ‣ CSS/ Layout update! Browsers are single-threaded ‣ Render !44 © 2013 Orientation in Objects GmbH
  • 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. 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. Too many divs... ‣ Semantic markup ! – ul/li vs div/span! ‣ Accessibility! – WAI-ARIA !48 © 2013 Orientation in Objects GmbH
  • 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
  • 55. Use a Composite, the thing holding a Widget Widget
  • 56. Use a Composite, the thing holding a Widget
  • 60. You end up exposing only widget + YourGreatInterface Widget Composite YourGreatWidget
  • 62. The trick Widget initWidget( flexThing ) Composite YourGreatWidget FlexTable
  • 63. Internals are locked away Widget Composite YourGreatWidget FlexTable
  • 65. GWT Widgets and DOM elements
  • 66. GWT Widgets and DOM elements div input div
  • 67. GWT Widgets and DOM elements SearchBox div input div
  • 68. GWT Widgets and DOM elements ‣ Two representations! – Logical (Java)! – Physical (HTML/DOM) SearchBox div input div !68 © 2013 Orientation in Objects GmbH
  • 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. Widget lifecycle - Construction public  Led()  {        setElement(Document.get().createDivElement());        setStyleName(getResources().style().led());        […]   }
  • 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. 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. 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. 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. 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. Basic handling of DOM events public  Led()  {        sinkEvents(Event.ONCLICK); } ! @Override   public  void  onBrowserEvent(Event  event)  {      if  (event.getTypeInt()  ==  Event.ONCLICK)  {            toggleLed();      }      […] }
  • 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);      } }
  • 79. Define your own events: handler… public  class  ExampleEvent  extends   GwtEvent<ExampleEvent.Handler>  { ! […] ! !      public  interface  Handler  extends  EventHandler  {            void  onSomethingHappened(ExampleEvent  event);      } ! […] ! }
  • 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. Define your own events: dispatching public  class  ExampleEvent  extends   GwtEvent<ExampleEvent.Handler>  {   ! […] ! !      protected  void  dispatch(Handler  handler)  {            handler.onSomethingHappened(this);      } ! ! } […]
  • 82. Define your own events: allow registration public  HandlerRegistration  addExampleHandler( ExampleHandler  handler)  {      return  addHandler(handler,  ExampleEvent.getType()); }
  • 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. 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. 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. How to build widgets ‣ Manual DOM manipulation! ‣ UiBinder !88 © 2013 Orientation in Objects GmbH
  • 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>  
  • 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. We all did it already verticalPanel.add(new  Label("Hello  GWT  world!")); dockLayoutPanel.addWest(new  CustomerForm(),  300); headerPanel.setContentWidget(new  CustomerForm());
  • 93. Widgets, panels and DOM elements Panel div div label Label div input TextBox
  • 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. The magic behind it public  void  add(Widget  widget)  {        […]        element.appendChild(widget.getElement());        adopt(widget);        […]   }
  • 96. Contract public  interface  HasWidgets  extends   Iterable<Widget>  {   !      void  add(Widget  w); !      void  clear(); !      Iterator<Widget>  iterator(); !      boolean  remove(Widget  w); }
  • 97. Coding against interfaces is possible public  interface  IsWidget  {      Widget  asWidget(); } interface  ForIsWidget  extends  HasWidgets  {      void  add(IsWidget  w); !      boolean  remove(IsWidget  w); }
  • 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. 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. 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. 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. 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>  
  • 104. What about Layouts? When we think
 of layouts, we
 think of structuring
 the UI from
 a bigger perspektive
  • 107. Web page layouts Desktop like, 
 full page Long page,
 scroll up/ down
 page
  • 109. Layout widgets resize chaining through ! ProvidesResize RequiresResize ! ! ! Chaining is required,
 resize event only top level, not propagated by browser Resize outside in
  • 110. Full page application, inside out & outside in RootLayoutPanel
  • 113. Widgets do not scale…
  • 114. Widgets do not scale…
  • 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. Why? setInnerHtml, job done As with CSS: native vs JS Many, many objects and 
 DOM manipulation
  • 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. 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);   }
  • 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. 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. 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. SINGLETON You must not public static instance