Saturday, January 07, 2023

Using Nebula TextAssist from Glimmer DSL for SWT

Recently, I received a support request concerning Glimmer DSL for SWT (JRuby Desktop Development GUI Framework) and the use of Nebula Custom Widgets, specifically the text_assist widget (auto-complete text field). 

For a quick background about Nebula, it is a collection of 55+ enterprise-grade high-quality SWT (Standard Widget Toolkit) custom widgets, including a progress circle, a password revealer, and an oscilloscope. Thanks to Glimmer DSL for SWT, they are usable from Ruby.




The support request mentioned that the text_assist custom widget was not working. It was because its Nebula implementation does not follow the SWT convention of always supporting a constructor that only takes (parent, style) arguments. This convention is actually universal in all widgets included in SWT out of the box. It is taken advantage of by Glimmer DSL for SWT to automate wiring of widgets between parents and children without having to pass arguments explicitly. The wiring is done automatically by simply nesting a child keyword (e.g. label) under a parent keyword (e.g. composite). Unfortunately, this convention is broken by the text_assist widget API, as documented in the TextAssist Nebula widget page:

“There is a big difference with other SWT widget : there is no constructor TextAssist(Composite parent, int style).

The only constructor available is public TextAssist(final Composite parent, final int style, final TextAssistContentProvider contentProvider)”
As such, nesting text_assist directly under a parent without passing arguments breaks.

The fix is very simple though. Glimmer DSL for SWT follows the 80/20 rule, which is common in Rails. That means, it automates 80% of the cases with convention over configuration for ultra-high productivity, and yet it still supports the remaining 20% of the cases (e.g. SWT widget not following API convention) through direct configuration. 

In the case of the Nebula text_assist custom widget, given that its API deviates from the standard convention, you can still use it by simply passing constructor arguments for text_assist directly in order to have it work as expected by its API. 

Let us demonstrate with an example.



Animated screenshot:




The shell widget (aka window) parent proxy Ruby object (wrapper of SWT Java object) is grabbed from the parent block variable (or any variable the parent is assigned to) before invoking the swt_widget method on it to grab the wrapped SWT Java object and pass it as per the expectation of the text_assist widget API (normally, all of this is done automatically for you with standard convention SWT widgets).   

Remember Shoes (the old Ruby desktop gem)? One of its biggest issues was lack of simple extensibility via high quality custom widgets. On the other hand, Glimmer DSL for SWT not only supports custom widgets written in Ruby, but also supports the entire Eclipse ecosystem and custom widgets written in Java, like Nebula.

Please support the most productive desktop development framework in Ruby (including productivity benefits not found in any web framework) by building applications in Glimmer DSL for SWT (or other Glimmer GUI DSLs)!

Happy Glimmering!

No comments: