Deconstructing generic components
Eelco posted almost a year ago about how important it is that components are easy to write in Wicket, and how greater prospects for pre-fab component libraries are a poor reason to favor any other framework. (The components in them are often worthless.) I knew he was right, but I guess I had to learn on my own why it is that generic components are so troublesome.
To be clear, what I’m calling components for the moment are chunky user interface controls that do more than manipulate or represent a single variable; in Wicket this is usually a Panel subclass with markup. You could have calculator component, a calendar component, or (if you believe your salesperson) a weblog-in-a-box component.
Making specific components in Wicket is easy. My own informal method is not to worry about them until I’m making a new page with some visual element repeated from an old page. Snip, snip: take code from the old page class and HTML from its template to make a new Panel subclass. Resolve anonymous subclass dependencies or any other ties back to the page’s structure and you’re done. The component looks exactly the same on both pages and everyone is happy.
But generic components are different. They’re expected to be flexible. Customizable. They’re supposed to be able to do everything a user might reasonably expect. And what they can’t do, client programmers should be able to extend them to do.
That would be a tall order even if we were talking about code alone. But we’re talking about a visual representation too. What if I provide a component that internally arranges elements A, B, and C in a column and you really want to add something between A and B but the only extension point I see fit to provide is at the end? Too bad for everyone I guess.
Maybe there’s some really great way to resolve this for HTML that we haven’t hit upon it yet, but I doubt it. Consider Cocoa and its Interface Builder, a best in class framework for a problem domain (bitmapped interfaces) that predates HTML. Notice something in this image? The controls available on the palette are extremely basic. (There’s a column view and color picker on other pages, but you get the point.) Cocoa gives you the building blocks—you make the widget.
It’s not that decent generic components are impossible. They’re just very time consuming to make. Why should Apple spend its own programmers’ time building complicated, business-y components so that lazy, uncreative programmers can snap them together into mediocre applications? That would do nothing for the platform. Instead, Apple spends its resources improving the small building blocks (adding things like Core Animation) so that talented and motivated programmers can make innovative new applications.
Similarly, it would’t seem to be worth my time in Databinder or the Wicket programmers’ time in Wicket to make Panel subclasses. No matter what we say in the documentation, users will expect them to be flexible. And indeed they should! The components are provided as if they might be good for something. In Databinder I have the AuthDataPage and its panels; Wicket has the DataTable panel in extensions. People write to the forum and listserv asking how to customize these things all the time and the answer is almost always “just don’t use it.” What were we thinking, including them in first place?
I suppose we were thinking that panels are really great, which they are, and that we can show people how great they are by including some in the libraries. But that doesn’t show how great panels are, it actually makes them look opaque and confusing. Worse, because Java programmers have been conditioned to expect do-everything magic-bullet components, they see these JARed panels and make all the wrong assumptions. The point of Wicket, its innate flexibility and genius, is lost to them (or at least delayed).
Within Wicket, a calendar widget for date fields is the only generic component I would make an exception for, mostly because people reviewing the framework will freak out if it’s not there. Unfortunately the quirky DatePicker is further proof that no open source programmer wants to improve generic components beyond the minimum that works for that programmer. Not that I’m complaining, I could contribute to it myself—but then it works well enough for me too.
In Databinder I’m going to extract AuthDataPage and its panels from the library. I can almost as easily generate those as project sources in a Maven archetype, and the result will be much more useful for everyone. As I’ve threatened to do before, I will someday rewrite the baseball example without DataTable. As for the ajax SearchPanel, perhaps it’s small and simple enough to survive the culling.
Also, I’m cancelling the planned Databinder guerilla marketing campaign involving green folders outlined by LEDs. Please do not call the police.