apache pivot

I have spent a fair amount of time with apache pivot, authoring several components and peering into the guts of the system. Apache pivot is a small, UI library that demonstrates what can be done in java and how, relatively speaking, easy it is to produce something useful that is still robust. I encourage everyone to look at the project and give apache pivot a try.

Using apache pivot has brought to light a few thoughts:

  • Pivot uses skins to customize drawing behavior. Skins can be only implemented in java code. BXML is a great tool and BXML could be used to specify skins (and hence themes and all customization) using the concepts in WPF similar to templates. Templates in WPF are essentially the skins. However, pivot forces java coding and "skin" management complexity where none is needed. In fact, the entire skin concept can be removed in the spirit of WPF with no loss of control. The complexity of implementing templates is on the order of implementing a skin--and this would allow only one skin to be created for template and easier customization to occur afterwards--a huge selling point for "richness" customization. Why write multiple skins? You can call a template by several names such as defmacro (for lipsers) or templates in the "velocity" sense, however, they would allow specifying how a component will look without coding and still maintain consistency by using BXML. This feature is easy to implement and could have greatly reduced pivot's complexity in customizing while increasing consistency. Perhaps most importantly a very simple version of templates could be created and not require a full WPF-like stack to be implemented. The idea is not reproduce JSF-style lexical templates, but a true template capability that is enabled through data binding. Again, some very simple idioms would remove the hard-coded behavior in many pivot widget classes that exist today and introduce greater flexibility without always requiring java coding versus specification.
  • The visual-component hierarchy is improperly flat. Right now, all functionality is pushed into the Component for mouse, keyboard and a variety of other behaviors. The container class, a subclass of component, can hold multiple components. However, it is not necessarily true that all visuals that should be displayed, need to be components. By allowing the "container" to hold visuals and pushing the visual tree children up in the component inheritance hierarchy, it is possible to provide some breathing room to elements that are lightweight but can still be part of the visual tree. A large number of pure drawing elements could be created this way. Today, you can still create them, but they are heavier since they have to inherit from component.
  • Styles are specified, for convenience, by json strings. json strings are essentially a leaner XML so specifying styles this way is fairly convenient and fine. However, string specifications are not always the easiest way to specify styles and using object specifications will be easier. For example, using paints is difficult in pivot. Not impossible nor overly difficult, but just more difficult. Since paints are used for gradients, it is difficult to use consistent gradients conveniently specified in BXML. Some simple code can remedy this and allow gradients, and hence enhance the richness of the interface, consistently and more universally. If pivot implemented brushes, which are paints (including gradients), with relative coordinates, this would help with the use of more advanced visual enhancements.
  • The use of scripting on a "page" where a page is defined as a BXML file is intriguing. It can reduce coding (although there are other ways to reduce coding as well). Scripting provides just enough dynamic content to fill in some key gaps. However, scripting does feel very web-pagish and was definitely influenced by web programming thinking--most of which is moving away from explicit scripting (ala grails or WPF) to hiding scripting behind industrial strength components e.g. ext-gwt. I actually do not think poorly of scripting on a page as long as it is used in moderation. However, I notice that WPF does not use scripting in XAML, so I question whether it is truly needed in BXML. Without proper support, scripting in BXML is hard to reproduce in direct code creating a gap between the ability to specify programs in BXML and code in the same way
  • The parent-child tree, which carefully constructed for the component hierarchy, is not really leverage for applying styles or finding resources. Nothing prevents it from being used for this purpose, but I think its a fairly common expectation that the lexical scoping using the parent-child tree is a good thing to have available (but it does not have to be used for everything of course).
  • Extensive use of listeners makes data driven programming harder. Pivot uses an extensive listener model to communicate property changes and events. It puts everything into listeners. This makes the API scaler linear with the number of properties. WPF does this to some extent as well. I'm not against specific API for each significant property change or event, however, the API involved in pivot is more difficult. Instead of enhancing the property change listener interface slightly, which would have been easier to do and significantly easier, new listener classes are created extensively. It's not hard to flatten it but being locked into strong-referenced listeners for a simple change event and not being able to use some simple patterns makes creating data driven programs, such as robust data binding, harder. The number of listener classes most likely exceeds that in swing and I was not a big fan of some many listeners to begin with. In fact, by using a small amount of reflection, it is easy to remove probably around 1000 lines of boilerplate code from the pivot library and still have type safety. All arguments pro and con aside, it seems a bit much and there are easier ways to handle it.
  • Decorators are provided to alter the drawing of a component. They provide a convenient attachment point to essentially attach "painters" to components. However, they are completely unnecessary and introduce complexity if the visual tree issue is addressed (or even not addressed but carry more overhead) because it entirely possible and easy to wrap a component in other components (or visuals) that decorate another component and its drawing.
  • Type converters on the BeanAdapter (or BXML serializer) class could greatly reduce code sprawl. Many methods in the skin classes are actually converters to convert from strings to the specific type needed by the skin. This is because there is no central converter service used to convert values. The amount of code duplication between skin classes is high. While the duplicated
    code itself is fairly simple, convert from a string to a color, there is a tremendous amount of duplication. I estimate that a few thousand lines of code could be easily removed from skin classes if a converter mechanism was provided.
By solving many of these issues differently and more consisently, pivot could become a landing place for those in the windows world to try java technology with a familiar architecture and design. One key architectural aspect of pivot is very good, the same code base for browsers or desktop. That's a great target to have and I think it has achieved this objective quite well--regardless of what people think about java itself.

While pivot's stated goal is to make java UI programming its focus, I think by reviewing its mission and looking towards the ability to draw a robust user community, it should think about not just existing in the java world, but providing a migration path from other environments. It should also focus on more advanced UI construction versus a fairly conventional java implementation that does not advance state of the art...it needs a "hook" to capture audiences.

Otherwise, I am concerned it will be suffer the same fate as most other java UI technologies--large fragmentation making each technology too small to achieve true scale. I implemented fixes for all of the issue described above using aspectj and the library felt easier to customize and use. I was skeptical at first, but templates and parent-child resource management, consistent painting, etc. helps build better UIs. But that is my opinion only. Also, a few changes could remove at least several thousand lines of code that does not add tremendous value to the framework.

I'll continue awhile longer to work with pivot and complete some odds and ends on my extensions that address *all* of the points above. I encourage everyone to give pivot a try as I think is a good framework. I would like to see it evolve with a slightly different end-point and become a dominant framework for the java UI world.


Popular posts from this blog

zio layers and framework integration

typescript and react types

dotty+scala.js+async: interesting options