A Tour of the GWT Libraries Bruce Johnson...
Transcript of A Tour of the GWT Libraries Bruce Johnson...
Design axioms (Making GWT Better)
• User experience is primary
– The anti-navel-gazing clause
• Subsystems are independently useful
– The anti-frameworkiness clause
• Discourage unoptimizable patterns
– The anti-premature-overgeneralization clause
• Only pay for what you use (duh)
The essence of GWT
• Hosted mode: GWTShell
– Tree logger and hosted browser
• Web mode: GWTCompiler
– Compiles modules into JavaScript
• Deferred binding
– Independently-compiled permutations
• Small handful of magic in gwt-user.jar
Eating one’s own dogfood
• Tiny bits of magic at the leaves (only)
• JavaScript Native Interface (JSNI)
• GWT.create(T.class)
– Permutations and code generation
– Why does it require a class literal?
• JavaScriptObject
• Everything else is written using the above
GWT is not its libraries
• GWT libraries are value-add, not magic
• You can patch them
– Copy/paste/tweak + classpath priority
• You can support a new browser yourself
– <extend-property> for user.agent
– Create a DOMImpl subclass
• Not liking the libraries != not liking GWT
gwt-user.jar
• JRE emulation
• Core GWT classes
– GWT, JavaScriptObject
• Value-add libraries
– UI, RPC, History, …
• (gwt-servlet.jar if you deploy as .war)
JRE emulation
• What’s there? (see GWT site)
• How do I know what I can/can’t use?
– Won’t run in hosted mode!
• Don’t get hung up on missing features
– You can write them :-)
GWT class
• Dependency injection
• T x = GWT.create(T.class) becomes– T x = new T1(); // permutation #1– T x = new T2(); // permutation #2– T x = new T1(); // permutation #3– …
• Bindings are controlled by .gwt.xml files
• Example: DOM abstraction
Single Java
Code Base
Download exactly what you need in
a single, optimized,
can't-go-wrong chunk
Then cache it on the client
until the sun explodes
…
FireFox 1.0.x
Your Code
en_US
1D04ADDA.cache.html
Safari 2.0.x
Your Code
fr_FR
…
7EFE4D24.cache.html
IE 6
Your Code
en_UK
…
15F361BB.cache.html
Opera 9
Your Code
fr_CA
…
D415D917.cache.html
GWT class (cont’d)
• Compile-time code generation
• T x = GWT.create(T.class) can also…
– T x = new GeneratedT();
• Code-generation rules are controlled by.gwt.xml files
• Example: RPC, ImageBundle, …
GWT class (cont’d)
• getModuleBaseURL()
– How modules find their resources
– Prepend to relative URLs
– getModuleBaseURL() + “my-image.gif”
• isScript()
– But don’t use it
• set/getUncaughtExceptionHandler()
– Last resort exception catching
JavaScriptObject class
• Not a wrapper!
• Element, Event are opaque
• Explains why in GWT 1.4 you write this
DOM.appendChild(elem1, elem2);
instead of this
elem1.appendChild(elem2);
• GWT 1.5 smashes through this!
I18N
• Static vs. dynamic (see web site)
• Dictionary class for out-of-band L10N
• Static approach is based on locale namingconventions sensitive to GWT ‘locale’
– MyClass_fr_CA
– MyClass_fr
– MyClass
I18N (cont’d)
• Localizable
– For locale-sensitive algorithms
• Constants, ConstantsWithLookup
– For values and maps
• Messages
– For templatized messages
• DateTimeFormat, NumberFormat
– For parsing and formatting
Ad Hoc HTTP with RequestBuilder
• Great for interop with RESTful back-ends
b = new RequestBuilder(POST, url);
b.sendRequest(postData, myCallback);
• Configure timeouts, authentication, …
• Analyze HTTP response headers
• Always asynchronous
• See XHR caveats (javadoc)
XML
• Portable DOM based on W3C standard
• XMLParser.createDocument()
• XMLParser.parse(xmlString)
• RequestBuilder + XMLParser
JSON
• JSONParser.parse(jsonString)
– Creates a JSON structure from a string
• Class hierarchy reflects JSON types
– value, object, array, number, string, boolean
• RequestBuilder + JSONParser
• GWT 1.5 will subsume JSON…
JavaScriptObject in GWT 1.5
class Person extends JavaScriptObject {
public final native String getFirstName()
/*-{ return this.firstName; }-*/;
public final native String getLastName()
/*-{ return this.lastName; }-*/;
}
• Declare JSO subclasses
JavaScriptObject in GWT 1.5
• Such that this call
String n = person.getFirstName();
compiles to this JavaScript
var name = person.firstName;
• Zero-overhead type safety around JS!
– JSON is just a special case
• Now we can add methods on Element!
Unit testing and Benchmarking
• Works with most any JUnit test runner
• Extend GWTTestCase for unit tests
• Extend Benchmark for benchmarks
• Can run in hosted and web mode
– “Dgwt.args=-web”
– BrowserManagerServer to farm out tests
• In GWT 1.5, setDebugId()
RPC
• Send object graphs across the wire
• Cycles, polymorphism, and exceptions
• Share classes between client/server
• Always asynchonrous
• For speed, correctness, and productivity
– Not for interop
– No compromises on wire format
RPC (cont’d)
• Very well-documented (see web)
• By default, debug client & server together
• Not tied to servlets
– Use server-side RPC class to [un]marshal
• If you’re feeling adventurous…
– Save an RPC round-trip at startup
– SerializationStreamReader/Writer
History
• Programmatic history control
– Based on “history tokens”
– Constant bookmarkability
• Not at all magic, though
– addHistoryListener(listener)
– onHistoryChanged(token)
– newItem(token)
– back(), forward()
Other stuff
• Window
• Cookies
• Random
• Timer
• DeferredCommand and…
• IncrementalCommand
– This is a good one to remember
Then there’s the UI stuff…
• DOM (cross-browser DHTML)
– You’ll use this infrequently
• UIObject, Widget, Panel
– You’ll use their concrete subclasses
• Composite
– This is the right way to create app widgets
– Far better than extending panels
ImageBundle
interface MyImages extends ImageBundle {
AbstractImagePrototype saveFileIcon();
AbstractImagePrototype openFileIcon(); }
Automatically combines
saveFileIcon.jpg
openFileIcon.jpg
And using an image prototype is easy
p.createImage()
p.getHTML()
ImageBundle (cont’d)
• An example of win/win/win/win/win
• Compile-time checking of resource URLs
• Automatic creation of CSS sprites
• Change O(N) round-trips into O(1)
• Perfect caching
• Prevents Ajax layout jiggliness (mail)
Key principles of GWT UI
• Implicit layout
– Fast, automatic resizing
• Style things with CSS, not code
– UIObject.setStyleName(style)
– UIObject.addStyleDependentName(substyle)
• Keyboard support
• Result: fast, accessible apps