Wednesday, March 3, 2010

Metawidget: Questions & Answers

I received a number of questions following a recent Metawidget presentation. I thought I'd blog the answers here in case they come up again. Please note this Q&A assumes a working knowledge of Metawidget. The snippets in bold are for those that like to skim-read :)


Q. How can a user apply the various UI styles required without effectively shifting UI code to inside Metawidget tags? This could include CSS styles, or custom layout requirements?

A. Metawidget has various approaches to help you achieve fidelity between its automatically generated UIs and your own hand-made ones.

The first, and most significant, is that Metawidget does not try to 'own' your UI. It only generates a small piece of each screen, so does not compromise the full power of your UI toolkit to style everything else. Often, this full power of your UI toolkit bleeds back into the Metawidget itself. So, for example, if you're using Swing you can set the Swing Look and Feel and that will style your whole UI, including any Metawidgets (see screenshot). If you're using CSS you can set top-level styles and use CSS selectors (see screenshot). Some component libraries offer skinnable components and so on.

If you need more fine-grained control, Metawidget has WidgetProcessors. WidgetProcessors plug into the Metawidget pipeline on a per-widget basis and process each widget as it is generated. Importantly, WidgetProcessors have access to the same rich set of metadata as the WidgetBuilders and the Inspectors. So you can identify and style widgets not just by name but also by type, by constraints, by label, etc. This makes it straightforward to, say, attach a certain CSS class to all date widgets. Or attach an id for a CSS selector to pick up (see ReadableIdProcessor).

Beyond that, Metawidget has pluggable Layouts that can apply styles around the widgets. So for example HtmlTableLayout renderer can apply CSS style classes to the 'label column' and the 'component column'.

Client JavaScript Customization/plugin

Q. Can you plugin custom JavaScript on your forms/widgets? Many users want to trigger something when a field is touched.

A. Metawidget's WidgetProcessors are very versatile, and can be used to process each widget in an arbitrary number of ways. They can style a widget (see above), attach validators (see StandardValidatorProcessor), converters (see StandardConverterProcessor), bindings (see StandardBindingProcessor), event triggers (see example in the Reference Documentation) and so on.

This capability would extend to attaching JavaScript, though the specifics depend on your particular widget library. In some cases it may be automatic (see the Metawidget ICEfaces example).

Runtime impact, and concerns

Q. Each time a page is requested the form is created dynamically? Is caching per app, per session, per view?

A. Most parts (Inspectors, WidgetBuilders, WidgetProcessors, Layouts, PropertyStyles etc.) of the Metawidget internals are immutable. They are created once and reused for the lifetime of the app. Some parts may, at their own discretion, cache their results. By definition, they will be caching on a per-app basis.

For example, the JavaBeanProperyStyle caches the result of introspecting classes for JavaBean getters and setters. The GroovyPropertyStyle does not do this, because Groovy classes are dynamic.

Q. What happens with pages with many forms?

A. Because so much of Metawidget is immutable, there should be relatively little overhead with multiple instances. See also this previous blog entry.

Benchmarks between applications?

Q. I would like to see this. Perhaps flush out an existing app, with Metawidget being the only variable. Beat on the two apps for a while and see what's different?

A. Metawidget ships with 3 examples of existing apps and their Metawidget equivalents. So the apps are there, and we tried beating on them. See this previous blog entry.

How do you handle cross component library issues?

Q. Is there a widget builder for each combination?

A. No. Each WidgetBuilder is generally responsible for only one component library. There is a CompositeWidgetBuilder which handles mixing multiple widget libraries in the same app, and prioritising them (see this video).

Q. When you layout do you use your own code, or widgets from the UI? For example do you create your own <table> or let the widget set do this?

A. Generally we let the widget set do this (see TabPanelLayoutDecorator), though for specific requirements we sometimes handle it ourselves (see HtmlDivLayoutRenderer).

Q. Are there ways to override layouts?

A. Yes. Layouts are pluggable. They are also decoratable, so one layout can be wrapped around another (see this blog entry).

Q. What other UI widgets do you handle? Data tables (with forms for data input)? Or strictly standard forms like address, credit card, etc

A. It is important to understand Metawidget is not a component library - it simply automates other component libraries. So if you have a rich data table component it is straightforward to plug in a WidgetBuilder for it (see DisplayTagWidgetBuilder).

Static layout based on model

Q. Good in theory, but large enterprise environments often have DBA's and different groups in charge of model code?

A. Metawidget's Inspector architecture is highly pluggable and designed to support a broad range of architectures and development styles. UI metadata can be sourced from XML files, POJOs, Web services, database schemas, rule engines or whatever method best suits the development team. It can even be sourced remotely across tiers, and across hetergenous technologies.

Q. Can you output static stuff at all?

A. There are no plans for static output at this time. Because Metawidget is runtime-based, inspecting objects, it is not clear how static output could be supported. I believe it becomes a mindset - I remember people used to ask whether Hibernate could output static SQL, but after you use a runtime ORM for a while it becomes a moot point. You can think of Metawidget as an OIM (Object Interface Mapper).

Source structure, standards, and build environment

Q. Licensing, copyright, dependencies?

A. The source is broadly divided into folders for the Metawidget source, folders for the examples and folders for the tests. There's an Ant build around the whole lot, with all build dependencies inside a lib folder.

Within the Metawidget source, packages are carefully structured to separate out technologies, such as org.metawidget.swing and org.metawidget.faces. It is intended developers can easily strip out those plug-ins they don't use (see the Swing Applet example).

Licensing is 99% LGPL. Copyrights belong to the author at the top of each file (mostly me, though I am grateful to those others who have contributed). At runtime, Metawidget has no mandatory JAR dependencies - it just uses whatever is available to it.