Tuesday, December 28, 2010

We're Hiring Again!

Here's the job ad we're posting. Following a successful first hire earlier this year, and increased investment from a leading Australian financial institution, we're hiring again. A chance to work from home, and work for me! What a dream job :)


Senior Java EE 5 (J2EE) Developer: $120,000 AUD + super
  • Small, focused team

  • Modern, well-crafted software

  • Work in city or from home
A rare opportunity to join our small consultancy team. We have recently received substantial investment from a leading Australian financial institution and we must grow to meet demand.

You will work side-by-side with one of Australia's premier Java EE developers, and be intimately involved in all design decisions.

You will be a pragmatic programmer. Software development will be in your blood: a natural instinct. You must be passionate about Open Source and Java EE. You will demonstrate advanced analytical skills; an eye for elegance and craftmanship; a passion for refactoring, unit testing, and delivering secure and robust code.

Your skills will include many of the following:
  • JBoss

  • JSF/RichFaces

  • XSL (T and FO) and XPath

  • EJB 3/JMS

  • JPA/SQL

  • Metawidget

  • HtmlUnit

  • HTML/CSS
In addition, you will have excellent communication skills and be comfortable interacting with stakeholders at all levels.

Work from home will be offered providing that you can demonstrate an appropriate working environment. You must be a citizen or permanent resident of Australia.

To help us sort applicants, include your CV and a 1 page overview highlighting your suitability for the role. Links to examples of your work (eg. web sites you have built, blogs you have written, Open Source contributions etc) will be highly regarded.

Please send your application to jobs@kennardconsulting.com.

Friday, December 17, 2010

Retrofitting a UI: GatewayWarDeployment example

Adam Bien recently asked me to create a Metawidget example for his Java EE Patterns and Best Practices Kenai Repository, based on his Real World Java EE Patterns book.

In order to demonstrate the changes typically required to incorporate Metawidget into a project (and the code savings it typically brings) I retrofitted one of Adam's original projects, his GatewayWarDeployment example. I've called mine GatewayWarDeploymentWithMetawidget.

To view the new example:
  1. Ensure you have Metawidget installed at its default location (/metawidget-1.05/metawidget.jar)

  2. Get sources for the Java EE Patterns Kenai project in NetBeans using Team > Team Server > Get Sources... (see this screencast for detailed instructions)
  3. Open the GatewayWarDeploymentWithMetawidget project
The example works just as before, but two files have been changed. The first is the managed bean, LoadView.java, which now includes Metawidget annotations and is therefore longer. The second is the UI page, createorder.xhtml, which now uses a <m:metawidget> tag and is therefore shorter:

LoadView.java
createorder.xhtml

In such a small example there is no overall saving in lines of code (larger examples have more dramatic savings). But there is still a significant reduction in duplicated declarations (field names, types, action names etc) and therefore reduced possibility of error when building (and maintaining) the UI. Note Metawidget is handling both the input boxes and the buttons, including enabling/disabling the buttons in line with the business logic. This is declared by the code:

@UiAction
@UiFacesAttribute( name = "read-only", expression = "#{load.emptyLoad}" )
public void dropLightest(){
   ...
}

Of course, this is not a great demonstration of all the features of Metawidget. More extensive examples can be found under the /examples folder of the Metawidget distribution. But hopefully it's enough to get people excited without confusing them with lots of code.

My thanks to Adam for his help and encouragement in developing this example!

Wednesday, December 15, 2010

Automatic Form Generator: Metawidget v1.05

Version 1.05 of Metawidget, the automatic form generator is now available! 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.

Tuesday, December 14, 2010

SeamForge: Latest Update

I'm growing a little uncomfortable with the direction SeamForge is taking. Here's an output from the latest build:

$ forge
   ____                          _____                   
  / ___|  ___  __ _ _ __ ___    |  ___|__  _ __ __ _  ___
  \___ \ / _ \/ _` | '_ ` _ \   | |_ / _ \| '__/ _` |/ _ \  \\
   ___) |  __/ (_| | | | | | |  |  _| (_) | | | (_| |  __/  //
  |____/ \___|\__,_|_| |_| |_|  |_|  \___/|_|  \__, |\___|
                                                |___/     

[no project] $ new-project

Greetings, Professor Falken. Would you like to play a game?

Wednesday, December 1, 2010

Rant: Who Designs These UI Frameworks Anyway?

I started a lively discussion over on Javalobby ranting about UI framework APIs.

Specifically: how come hardly any UI frameworks define their widgets in terms of interfaces, as opposed to abstract base classes? I listed off a dozen mainstream UI frameworks that do this, and was fortunate to get dozens of people responding with their thoughts. The key outcomes were:

  • Some UI frameworks (albeit a minority) are interface-based. Examples include ItsNat, Vaadin
  • Other frameworks have considered being interface-based (Swing), but on balance decided to use abstract classes. Neither is optimal: "when I was working on the Swing team at Sun Microsystems back in the early days of Java. Some people on the team were of the opinion that Component should be an interface and others that it was best as an abstract class. But really, neither sounded like a good choice"
  • Abstract base classes limit future use cases. This is dangerous because "anything of strategic importance will be used in ways that the original designer cannot anticipate"
  • The problem with a 'monolithic' interface is that it is cumbersome to evolve: "You will soon have IComponent, IComponent_v2, IComponent_v3"
  • The problem with 'granular' interfaces is that you often have to pass around many of them together: "I found it to get problematic as I'd pass around something like (Sizable, Locatable) and then deep in the heart of the framework I realised I needed Focusable also, and I then had to go back up the stack chain and add it to all parameters"
  • Java does not have a good way to bundle several 'granular' interfaces together, but other languages may (Scala traits): "It's not yet possible to write Component the way I really want to write it. To do that, you'd have to change Java."
Finally, I would like to apologise to any who were offended by the somewhat incendiary tone of my article. It was pitched as a 'rant' in order to encourage responses, but in no way was I suggesting the UI frameworks I listed were anything but successful - or that their creators were anything but intelligent, brilliant people.

Thursday, November 25, 2010

Metawidget: Collections Support Part 2 (More Advanced)

In my last post I looked at some quirks of using the ICEfaces PanelTabSet with Metawidget. Specifically, because PanelTabSet stores the selectedIndex of the current tab inside the component, the component cannot succesfully be destroyed and recreated.

To work around this we looked at using Metawidget's COMPONENT_ATTRIBUTE_NOT_RECREATABLE to preserve the selectedIndex at the expense of some dynamicism. We further looked at using JSF's binding attribute to try and claw back some of that dynamicism.

However, a different approach entirely would be to stop PanelTabSet storing selectedIndex internally! It turns out ICEfaces provides an API for this. The only question is where else to store selectedIndex, but keeping it inside the current request seems to work nicely. So:

  1. Forget all about COMPONENT_ATTRIBUTE_NOT_RECREATABLE and the binding attribute (and related mMetawidget inside the managed bean)

  2. Change the line in the IceFacesTabsWidgetBuilder that says...

    panelTabSet.getAttributes().put( UIMetawidget.COMPONENT_ATTRIBUTE_NOT_RECREATABLE, true );

    ...to say...

    panelTabSet.setValueExpression( "selectedIndex", expressionFactory.createValueExpression( elContext, "#{param['tab-" + attributes.get( NAME ) + "']}", Object.class ) );
So now you get fully dynamic tabs at the same time as tab switching working! This technique only applies in those cases where the UIComponent thoughtfully exposes such an API, but in such cases it's very useful.

Hope that helps!

Wednesday, November 24, 2010

Metawidget: Collections Support Part 2 (Advanced)

In my previous post, I showed how to render a Collection as one item per tab. This is pretty easy in most frameworks, but ICEfaces presents a challenge because:
  1. The ICEfaces PanelTabSet doesn't have an option to switch tabs on the client-side, using just JavaScript and CSS to show/hide the tabs (RichFaces has switchType="client")

  2. The ICEfaces PanelTabSet stores its tab state inside the component, so when doing server-side switching you cannot destroy and recreate the component or the tabs won't switch
In my last post I resolved this by setting COMPONENT_ATTRIBUTE_NOT_RECREATABLE on the PanelTabSet. I noted this would allow the user to switch tabs, at the expense of making the tabs themselves less dynamic. But a couple people wanted to know how to get the best of both worlds: how to switch tabs and have them be dynamic.

There are a few answers to this question:
  1. There is still quite a lot of dynamicism, even with COMPONENT_ATTRIBUTE_NOT_RECREATABLE set. Metawidget is smart enough to work around the COMPONENT_ATTRIBUTE_NOT_RECREATABLE components, and still recreates their siblings and even their children. As the project from the previous post shows, you can have an 'Edit' button that makes the components (both inside and outside the tab) turn from read-only labels into input boxes

  2. The COMPONENT_ATTRIBUTE_NOT_RECREATABLE only applies during POST requests. Re-rendering the page afresh as a GET request works fine. So if your user clicks a link to navigate into the page with the TabPanelSet on it, no problem
But there is a further case: what if I want to be able to add tabs with a POST request? Here we need something new. We need to be able to tell Metawidget: don't recreate the tabs normally (else we won't be able to switch between them), but do recreate them when I click 'add tab'.

I have put together a complete project you can download from here. It'll produce something that looks like this:


The trick is to use JSF's binding attribute. As I blogged previously, this is a little-used but very useful feature of JSF that allows programmatic control over your components. So in your page you do:

<m:metawidget value="#{headerDemo}" binding="#{headerDemo.metawidget}"/>

And in your managed bean you do:

public UIMetawidget getMetawidget() {

   return mMetawidget;
}

public void setMetawidget( UIMetawidget metawidget ) {

   mMetawidget = metawidget;
}

@UiAction
@UiComesAfter( "details" )
public void addTab() {

   mDetails.add( new Detail( mDetails.size(), "Detail #" + mDetails.size() ) );
   mMetawidget.getChildren().clear();
}

Hope that helps!