I have just become aware of Composite.changed(Control[] children). There is an extensive article which I read a couple years ago:
http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html
This article also mentions to call Composite.layout(boolean changed, boolean all) to update the layout: "Calling layout() is the same as calling layout(true) which tells the ColumnLayout to flush its caches before setting the bounds of the children." That is all correct and what I have been doing ever since. But it is not what one wants, since it basically defeats the benefit of the layout cache when you want to update the layout because one or a few controls have changed requirements.
Imagine you have a bunch of StyledText widgets in a GridLayout and you need to change the size of one of them. Calling computeSize() on StyledText is very expensive. Instead of this:
Wrong:
parent.layout(true);
... which calls computeSize() on all children, even though their requirements have not changed. You should do this:
Right:
parent.changed(new Control[] { theChangedChild });
Then either
rootComposite.layout(false, true);
or
parent.layout(false);
Not very intuitive. The parameter to layout() is just badly named. Instead of calling it "changed" it should have been called "ignoreCache" or something. The intuitive thing is to pass "true" when something changed. Instead you need to pass "false", but invalidate the cache for just the changed Control with changed() before you do...
Note that calling changed() will also recursively invalidate the cache for just the parent Control in its own parent, which totally makes sense. So when you call layout(), you should call it on the root composite (most often the Shell) with all=true, unless you know that the size of the parent of the changed control will or can not change in response.