Sunday, February 28, 2010

3 Awesome iPhone Apps

At Kennard Consulting we're always coming up with ideas for new products, and today we're focussing on iPhone applications. Here's a sneak peak at some of our latest innovations. Please note these are all still at the prototype stage, so we'd appreciate your feedback as to which ones you think will be a seller!

iPool

Turn your iPhone into a complete swimming pool tester, without all the fuss of traditional tester kits.

Simply dip your iPhone briefly in the shallow end of the pool, and iPool will instantly analyze pH levels, chlorine and acidity. It will then recommend correct levels of salt, acid or buffer and connect you to iPool Online which will fulfil all your pool chemical needs at discount prices.
iTherm

Bake that perfect cake by using your iPhone as an oven thermometer! Highly accurate up to 400 degrees Celsius and more reliable than tradition oven thermometers (pictured), iTherm will display up-to-the-second temperature readings.

Includes built in cooking timer and recipe book.

iScale


Keep your weight in check wherever you are, by using your iPhone as a weighing scale. Simply place your iPhone on a flat surface and stand on it, and iScale will record your weight accurate to 100 grams.

Includes weight loss tracker and calorie counter.

Wednesday, February 24, 2010

Form Generation: Performance Impact

I was recently asked about the performance impact of using Metawidget. Metawidget dynamically generates forms at runtime, so it's expected there will be a performance impact over hard-coding those forms statically: rendering speed and memory consumption will probably get worse. Conversely, deployment size will probably get better (screens can be generated on-demand, rather than pre-compiled and shipped with the app).

Of course, everybody hates micro-benchmarks. They're easy to quote, but rarely very accurate, and almost impossible to make meaningful. The best advice is try Metawidget with your application, in your environment, to see if it performs acceptably.

That said, and with huge pinches of salt, I thought I'd give it a go. Metawidget already ships with 3 examples of 'retrofitted' applications - that is, existing applications that have been upgraded to use Metawidget. These make for great 'before and after' tests of two versions of the same application where Metawidget is the only variable.

I took the existing JBoss Seam Hotel Booking sample, the JBoss Seam DVD Store sample, and the JBoss Seam Groovy Booking sample, and wrote a Webtest to cycle over them 100 times. I then wrote a similar Webtest (some of the ids are slightly different) to cycle over the Metawidget version. These webtests are under /test/src/web/examples/faces.

Next I...
  1. took my PC (Intel Core 2 Duo 8400, 4GB RAM, Windows XP SP3)

  2. built the samples from JBoss Seam 2.2.0.GA

  3. deployed them on a fresh copy of JBoss 5.1.0.GA and Java 6 update 17

  4. set all logging to WARN (I have found logging skews the benchmarks)

  5. ran the Webtests

...and timed the result. I did this a bunch of times and it generally came to...
Seam Booking Test
(seam-booking-performance-test.xml)
test-without-metawidget7m 44s
7m 55s
7m 50s
test-with-metawidget6m 56s
6m 42s
6m 48s
Seam DVD Store Test
(seam-dvdstore-performance-test.xml)
test-without-metawidget5m 17s
5m 17s
5m 21s
test-with-metawidget 5m 40s
5m 47s
5m 38s
Seam Groovy Booking Test
(seam-groovybooking-performance-test.xml)
test-without-metawidget48m 1s
47m 50s
test-with-metawidget45m 1s
44m 6s
44m 33s

Finally I did a quick graph of the results (using GraphJam):

As you can see, the results are all over the place. The Hotel Booking and Groovy Booking samples actually run faster with Metawidget (14% faster and 7% faster, respectively), and the DVD Store sample runs slower (7% slower). The latter result is expected, the former is a surprise. I tried it on another PC just to confirm, and I'd encourage you to try it yourself.

What does this mean? As I said at the start - not very much. Does it mean your application will run faster with Metawidget? No. As they say your mileage may vary. Does it mean Metawidget probably won't have an appreciable impact on the performance of your User Interface and so you should take a look at it? Definitely :)

Feedback welcome!

Wednesday, January 27, 2010

Form Generator: SWT support

For the next release of Metawidget (v0.95), I'm going to have a go at some (long overdue) SWT support.

SWT is notorious for being difficult to work with for dynamic UIs. This largely seems to stem from the fact a Control cannot be created independent of a Composite (container): you have to specify a Control's Composite at construction time, so you can't easily remove it from a Composite temporarily, or move it from one Composite to another (eg. from outside to inside a TabFolder).

I got a huge leg up from Stefan Ackermann, who implemented a partial port of Metawidget to SWT for me, so things aren't going too bad so far. An alpha build is in SVN.

But it's early days yet. Any SWT experts who would like to lend a hand (coding or testing) are very welcome!

Monday, January 11, 2010

GUI Generator: Metawidget Video Overview

Had fun this weekend putting together a little 'video overview' of Metawidget. Music by Kevin MacLeod:

Tuesday, January 5, 2010

Automatic Interface: Metawidget v0.9

Version 0.9 of Metawidget, the automatic interface tool, is now available. Existing users should see the Migration Guide. This release includes the following enhancements:
As always, the best place to start is the Reference Documentation:

http://metawidget.org/doc/reference/en/pdf/metawidget.pdf

Your continued feedback is invaluable to us. Please download it and let us know what you think.

Metawidget 0.85 to 0.9 Migration Guide

The next release of Metawidget (v0.9) continues the refactoring work of v0.85. As such, there will be some breaking changes. We apologise for this disruption and provide this Migration Guide to help in moving from v0.85 to v0.9. All of the existing documentation and examples have already been migrated, as a reference point.

LayoutDecorators

The layout interface has been changed slightly to introduce the concept of LayoutDecorators. This allows inner layouts to be 'decorated' with outer layouts.

For example, you can decorate a GridBagLayout with a TabbedPaneLayoutDecorator to add tabs around sections. Previously this functionality was 'baked in' to GridBagLayout itself, and duplicated in other places such as MigLayout. Breaking it out allows easier maintenance, plus we can beef up the decorators themselves. For example, TabbedPaneLayoutDecorator now supports configuring tab alignment.

You can also nest LayoutDecorators in interesting ways. For example...

<tabbedPaneLayoutDecorator xmlns="java:org.metawidget.swing.layout"
   config="TabbedPaneLayoutDecoratorConfig">
   <layout>
      <tabbedPaneLayoutDecorator config="TabbedPaneLayoutDecoratorConfig">
         <layout>
            <gridBagLayout />
         </layout>
      </tabbedPaneLayoutDecorator>
   </layout>
</tabbedPaneLayoutDecorator>

...gives (ie. nested tabs)...

...whereas...

<separatorLayoutDecorator xmlns="java:org.metawidget.swing.layout"
   config="SeparatorLayoutDecoratorConfig">
   <layout>
      <tabbedPaneLayoutDecorator config="TabbedPaneLayoutDecoratorConfig">
         <layout>
            <gridBagLayout />
         </layout>
      </tabbedPaneLayoutDecorator>
   </layout>
</separatorLayoutDecorator>

...gives (ie. tabs inside a separator)...

...and finally...

<tabbedPaneLayoutDecorator xmlns="java:org.metawidget.swing.layout"
   config="TabbedPaneLayoutDecoratorConfig">
   <layout>
      <separatorLayoutDecorator config="SeparatorLayoutDecoratorConfig">
         <layout>
            <gridBagLayout />
         </layout>
      </separatorLayoutDecorator>
   </layout>
/tabbedPaneLayoutDecorator>

...gives (ie. separators inside a tab)...

Another advantage of this approach is you can decorate widgets from one widget library with widgets from another: LayoutDecorators allows mixing layouts in the same way CompositeWidgetBuilder allows mixing widgets. For example, you can use JSF's SimpleLayout but decorate it with tabs using RichFaces' TabPanelLayoutDecorator:


InspectionResultProcessors

There is now a new stage in the pipeline for processing the inspection result after the Inspectors but prior to the WidgetBuilders. Existing functionality (such as sorting by comes-after) has been moved into here, but it also opens the door for custom implementations.

In particular, it allows sorting and/or including/excluding names based on a UI parameter. For example:

<m:metawidget value="#{foo}" fields="name,age,retired"/>

We don't necessarily recommend this approach (it requires hard-coding field names so won't refactor well) but it has been a common request.

OverridenWidgetBuilder

Previously widgets were overridden by adding child widgets (with appropriate names) inside the Metawidget. This mechanism has now been factored out into an OverridenWidgetBuilder so that custom implementations can be plugged in instead if desired. Alternatively, you can remove the overridden mechanism entirely.

ReadOnlyWidgetBuilder

Previously all WidgetBuilders had two code paths: one for read-only widgets and one for non-read-only (or 'active') widgets. This has been factored out into a separate ReadOnlyWidgetBuilder so that custom implementations can be plugged in instead if desired. Alternatively, you can remove the read-only mechanism entirely.

Monday, December 21, 2009

#jsf2next: Bean Validation's Final Frontier

There's a scene in The Hitchhiker's Guide to the Galaxy that goes:

He reached out and pressed an invitingly large red button on a nearby panel. The panel lit up with the words Please do not press this button again.

Clearly this is a joke: it's funny because it's obviously bad user interface design. Yet this is precisely where we are today with Java EE 6.

Don't get me wrong: I think Java EE 6 is an awesome spec, and I think Bean Validation and JSF2 work really well together, but just like Seam's s:validateAll, the best you can do is validate the input after the user interaction:

  1. give them a text box, then afterwards tell them their input was too long

  2. give them a text box, then afterwards tell them number must be less than 100

  3. give them a date picker, then afterwards tell them date of birth must be less than today
In short - we let them press the button, then afterwards tell them they shouldn't have pressed it. Ideally, we should:

  1. give them a text box limited to a certain number of characters

  2. give them a number spinner (or slider) capped at 100

  3. give them a date picker capped to before today
In short - we should apply Bean Validation constraints to the component before the user interaction.

There are a variety of ways to achieve this, and obviously I'm biased. But whichever approach we use, I think it's the next logical step - and the final frontier in establishing validation constraints that apply all the way from the back end to the front end.