Sunday, November 27, 2011

How LWUIT Is Different (better) From Swing

I've been meaning to write an introduction to LWUIT for Swing developers, for quite a while so this is it. We were highly inspired by Swing when writing LWUIT and that inspiration allows Swing developers instant familiarity into LWUIT thus providing them a very easy path into mobile development without the hassle.

The best way for a Swing developer to get into mobile is just to open a LWUIT based project and start working, its just that simple! At first the use of styles might seem slightly alien but you get used to it instantly and its ridiculously familiar.

There are quite a few differences between LWUIT and Swing which came thanks to the fact that we could learn and adapt from Swing. So LWUIT is in effect better than Swing mostly thanks to it being newer. Here is a list of highlight/bullet points for Swing developers wishing to take a look at LWUIT.

What's Similar:

Component/Container hierarchy with layout managers to arrange the elements. All the old friends are there with some additional added features (GridLayout, BorderLayout, BoxLayout, FlowLayout, GroupLayout) and some new (TableLayout, LayeredLayout). Naturally LWUIT doesn't feature the whole JComponent sub hierarchy and maintains a simpler hierarchy.

You can override paint and get a graphics object to do whatever you want. LWUIT is lightweight (just like Swing) and draws everything on its own to maximize portability and flexibility

You can add/remove action listener and similar observer based patterns for various events

Dialogs can be modal, so when you use Dialog.show() or similar method the next line won't execute until the dialog is disposed. Like in Swing, this is entirely optional.

LWUIT has a glasspane, its a bit different from the Swing glasspane but very similar in functionality

List model and list cell renderer, pretty much like Swing's API with added functionality for animations and horizontal lists.

ContentPane for the body of the Form (LWUIT's root component) which is technically hidden

The LWUIT EDT requires that you interact with it over a single thread, it has a callSerially method (invokeLater), callSeriallyAndWait (invokeAndWait) and even an invokeAndBlock (foxtrot for the advanced swing users)

What's Different :

Optimized for phones/tablets both touch & feature phones. This includes support for gestures and complex key layouts

Styles & Themeing - the PLAF is much narrower in LWUIT (due to size constraints) but LWUIT makes up for it by having a Style object associated with every component. Furthermore, LWUIT allows customizing said styles with a theme that can be created visually using an open source resource editor tool!

Animations are integrated in the core of LWUIT in several levels. You can animate layouts, transitions and just arbitrary objects.

The resource file format is an integral part of LWUIT (although technically completely optional) it offers a GUI builders (optional but quite helpful), theme creator, localization etc. Unlike matisse it doesn't generate any code thus providing a more VB like experience where the UI and code are cleanly separated. The tool can be given to a designer with no coding experience

Painters - Swing tried to integrate painters after the fact and failed since the framework needs to be designed with them to begin with. We did just that. We also separated background painting from foreground painting and made it easier to override just background painting.

Deep and elaborate porting layer allowing LWUIT to be ported to any platform easily

LWUIT is truly open source - while Swing was technically open sourced, debugging/modifying Swing was not trivial since it was integrated into the JDK. This also prevented developers from incorporating fixes (or a known working version) into their build. LWUIT is bundled with the application so you can easily fix it and very easily modify code/debug to locate/fix issues. The development is easy to follow with a public viewable SVN. You can actually get commits from us as we fix issues and add features.

3 comments:

Things I loved about LWUIT:1. How simple it is - it has a really clean and simple architecture, well organized, useful integrated design patterns (observers for action handling, bridge for easy porting, flyweight for lists etc.). You can start working with it immediately, with no real prior knowledge required.2. How powerful it is - its simplicity doesn't compromise features. You can easily design great UIs and take advantage of all the excellent built in features. Its handling of styles, animations and transitions is amazing. When I worked on a Swing app. I was actually surprised at all the basic stuff it lacked compared to LWUIT and also at how complicated (albeit extensive) its API is.I'd actually like to see LWUIT's desktop port evolve to the point where it's used to build Java desktop apps.3. Open source - makes it extremely easy to not only understand the framework better but also learn from your code.4. Immediate fixes - linking directly against the SVN repository ensures almost daily enhancements and bug fixes.5. Support - the LWUIT team is very responsive and active on all mediums: e-mail, blog, forum, stack overflow.

Things that could be improved:Not much... Especially since you've added so much to LWUIT since the last time I used it (including the enhanced Resource Editor with GUI builder).However, I think Lists could have been done a bit differently. They could still be based on a flyweight pattern but instead of using a single "rubber stamp" component, a component could be allocated for every row currently on screen and recycled - as is done in Android's ListView & iOS's TableView. This would enable event handling directly within the component (as is done in regular components) and I think could also more easily enable lists with multiple row sizes, animations reflecting changes to the model (rows moving in/out) etc.Also, I must confess that I never really understood the difference between callSeriallyAndWait & invokeAndBlock. They both invoke the Runnable on the EDT and block the code without blocking the EDT until it returns. I think callSeriallyAndWait pushes the Runnable to the end of the queue while invokeAndBlock performs it immediately - am I correct?