Slim Down SWT FormLayout Usage

Home  >>  Common  >>  Slim Down SWT FormLayout Usage

Slim Down SWT FormLayout Usage

On March 31, 2014, Posted by , In Common,Eclipse, By ,,,, , With 2 Comments

Always on the quest for efficiency I reconsidered the usability of SWT FormLayout lately. Although it is one of my favored core layouts with respect to flexibility, I had to recognize that it is only reluctantly used by most of my fellow workers. Proposing it for an appropriate task sometimes actually seems to inflict real physical pain, considering the facial reactions…

Indeed, upon closer examination one have to admit that the usage is at least a bit cumbersome. Not so much the layout itself as the FormData configuration for each control under its reach. The following snippet shows a simple use case that – well, I will not spoil the enjoyment of finding out by yourself what it does:

Label label = new Label( composite, SWT.NONE );
FormData labelData = new FormData();
label.setLayoutData( labelData );
labelData.top = new FormAttachment( 0 );
labelData.right = new FormAttachment( 100 );
labelData.bottom = new FormAttachment( 100 );
labelData.left = new FormAttachment( 0 );

Of course everyone is able to figure out the functionality of the code. But it really has the notion of actually figuring it out – and I guess this is part of the problem. So how about programming this less verbose but nevertheless more expressive in the following way:

Label label = new Label( composite, SWT.NONE );
attach( label ).atTop().atRight().atBottom().atLeft();

While it is definitely more compact, expressiveness is, at least to some extend, in the eye of the beholder and depends strongly on the metaphor one have of the task at hand. In my imagination FormLayout basically attachs the control boundaries at certain reference points, i.e. the top side atTop, meaning it always keeps the top side of the control at the upper bound of the parent’s client area.

Or it attachs a control atTopTo another control, meaning the control’s upper side is always aligned to the bottom of the other control. Furthermore a side can be attached to a percentage range from the respective client area bound, which all could be expressed like this:

attach( control ).atLeftTo( otherControl ).fromTop( 20 );

With this mindset I developed a little utility class I called FormDatas to put the outlined ideas into practice. The class provides a static method attach to create a new instance of FormData, which is registered at the control given as parameter. The layout data instance is returned wrapped by a FormDatas object to enable the fluent interfaces style of the configuration methods1.

Additionally there are overloaded method variants to handle e.g. the notion of margin or alignment. The margin is based on the underlying Attachment#offset attribute, but actually respects the side of the attachment. Therefore a margin of 5 atRight corresponds to the offset of -5 of an Attachment that has been assigned to the FormData#right attribute with a numerator of 100:

attach( label ).atRight( 5 );

is short for

FormData formData = new FormData();
label.setLayoutData( formData );
formData.right = new FormAttachment( 100, -5 );

Alignment is backed by the Attachment#alignment attribute and uses the corresponding SWT constants. To adjust a control’s top attachment to the center of another control for example use the following code:

attach( control ).atTopTo( otherControl, MARGIN, SWT.CENTER );

And here is yet another scenario that shows how to work with a width hint instead of opposing side attachments:

attach( control ).atTop().atRight().atBottom().withWidth( WIDTH );

It is important to mention that the FormDatas implementation does not cover all possibilities of FormData and FormAttachment. But as I was able to replace all use cases in a current project, I hopefully managed to meet the more common ones.

From the IDE point of view the best way to integrate the FormDatas is to configure it as favorite. This way the FormDatas.attach(Control) method is available via content assist that automatically handles static imports and the like.

attach-content-assist

If you want to have a look at FormDatas by yourself there is a GitHub gist containing the implementation. However keep in mind that I did not spent any time on documentation, parameter verification or the like. In this regard the utility is a pretty rough cut version that might evolve over time.

https://gist.github.com/fappel/9867945

The gist contains the FormDatas and a JUnit test case, as the implementation is meant to be used in production environment and therfore should be tested.

Last but not least if you can think of better metaphors and/or a API methods feel free to share them here – names are almost always one of the most difficult things, so I would be happy to have some inspiration.


  1. FormDatas#attach(Control) is basically a factory method. Because of this it might look a bit strange returning actually an instance of FormDatas. However introducing a new type just for the sake of the fluent interfaces style also seemed a bit odd to me – so if you have a better idea…
Follow me

Frank Appel

Frank is a stalwart of agile methods and test driven development in particular. He understands software development as a craftsmanship based on a well-balanced mix of knowledge and the experience of the daily work.

fappel@codeaffine.com
Follow me

Latest posts by Frank Appel (see all)

2 Comments so far:

  1. Ralf Sternberg says:

    Yes, that’s the way to write SWT code! I’ve once created a similar implementation here. In contrast to your’s it doesn’t try to create english prose, but provides a direct mapping of the SWT API, so you can reuse SWT knowledge and documentation. You’d just write formData( control ).top( 20 ).left( otherControl );.

    I like how your approach leads to more expressive code. However, in case of attaching to another control, I think the naming does not fit perfectly. For example, in attach( control ).atTop();, “top” seems to refer to the top of the container, because you attach the control to the top. In contrast, attach( control ).atTopTo( otherControl ); attaches the top of control to the adjacent side of otherControl. In this case, “top” refers to the top of the control.

    BTW, I believe that the correct phrasal verb is “to attach to”, not “to attach at”. So perhaps replacing “atTop” with “toTop” and “atTopTo” with “topTo” etc. would make it clearer? OTOH, the first form wouldn’t be a prefix of the second form anymore which limits tool support.

    • Frank Appel says:

      Thanks Ralf for your valuable input. I think you are right and it is ‘attach to’, which unfortunately does not make it easier ;-) I also agree that ‘atTop’ and ‘atTopTo’ refer to different sides of a coin and I did not find it perfect by myself. As I said, names are the most difficult part…

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>