This posts gives an overview of the new developments which have been made available today
1. lib-gwt-svg
I am releasing a new version of lib-gwt-svg (version 0.4.6). As can be seen in the release notes, the emphasis is mostly on fixing bugs and making the API easier to use. Here is a high level view of the main changes:
Generics
I have finally bitten the bullet, read the excellent tutorial on Java Generics by G. Bracha and generified the API.
Collections
I have changed the implementation of the SVG collection classes. They have been promoted from pure overlay types to wrapper types (see my post on goals and design for more explanations of what I mean by that). They now implement java.lang.Iterable, so you can write code like this:
OMNodeList<OMSVGRectElement> rectList = document.getElementsByTagNameNS(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_RECT_TAG);
for (OMSVGRectElement rect : rectList) {
...
}
GWT XPath expressions
lib-gwt-svg now offers a new DOMHelper.evaluateXPath() XPath evaluation function, which lets you do really powerful computations with little code. Imagine you have an SVG drawing containing many circles and you want to increase their radii by 10%. Here you go:
Iterator<OMSVGCircleElement> iterator = DOMHelper.evaluateXPath(svg, ".//svg:circle", new SVGPrefixResolver());
while (iterator.hasNext()) {
OMSVGLength radius = iterator.next().getR().getBaseVal();
radius.setValue(1.1f * radius.getValue());
}
Another problem I find XPath very good at is to replace getElementById(). getElementById does not work in all circumstances. If called too early (before the node is inserted in the DOM structure), it will fail. You can easily devise an XPath which will do the same thing and work is all circumstances. One area where I think this pattern should be applied is UiBinder HTML binding. UiBinder currently relies upon adding temporary “id” attributes to the elements you want to bind to, then removing it before it gives control back to you. However UiBinder will fail if the HTML node you want to bind to already has an id: it is either ui:field or ‘id’. If XPath where used instead, their less intrusive nature would let one use both ui:field and ‘id’ in the same DOM node. This is the way lib-gwt-svg UiBinder integration works.
One final note on XPath: they seem to work very well on all browsers: Webkit based, Firefox and Opera.
Events
As explained in the goals and design post, lib-gwt-svg uses overlay types internally. These overlay types are then embedded in wrapper types which provide a more java-friendly view of the SVG types and lets them implement interfaces, notably GWT event registration interfaces. Though it is straightforward to go from the wrapper type to the underlying overlay type, the other conversion is more costly: you need to instantiate a new wrapper and wrap the overlay type in it. Up to version 0.4.5 included, the wrapper type also carried the HandlerManager which stores event registration information. Thus, the wrapper was not truly hollow and you could end up with event registration information for the same overlay type contained in several instances of HandlerManager owned by several wrappers. With version 0.4.6, there is just one HandlerManager per SVG object, and it is carried by the overlay type itself.
2. lib-gwt-svg-samples
The samples work correctly with all SVG enabled browsers (except the SMIL animation sample, which works only in Opera and FF3.7 alpha4).
The samples can now be resized, as should every SVG application.
3. lib-gwt-svg-edu
I am releasing two new puzzle games, which leverage the same SVG feature: the ability to create arbitrary clip path. This is very convenient to cut one image into several pieces and layout the pieces in arbitrary order. If you want to explore the possibilities of this pattern, here is a trick which is not available from the UI: try to launch the game with the following parameters added to the URL: ?connector=SQUARE and ?connector=NONE.
I have also reorganized the program so that navigation works better: going back to the main menu no longer requires the game to restart. I am just swapping DOM elements to achieve the same result.
The program was originally developed and tested with FF3.x and works really well on this platform (except a minor bug in the display of the “push-push” game title, fixed by FF3.7a4). With this release, I have also tested it on Opera: there are no bugs I am aware of on this platform. I tried to do the same with Webkit-based browsers (Safari and Chrome) but there a currently several bugs and missing features and these browsers quickly crash when running the games. So I was faced with two possible choices: either recode the games to bypass these bugs and missing features, or file bug reports help these browser improve. As you guess, I chose the “lazy” path for the moment and went for the second option. You can check the browser bugs page for the list of bugs I have filed.
I just found this library after having investigated a few options – most notably gwt wrapper projects for the raphaeljs library. I’m not especially interested in the overhead of VML support so this looks very exciting!