我刚刚意识到 Composite.changed(Control[] children)。几年前我读过一篇广泛的文章:
http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html
本文还提到调用 Composite.layout(boolean changed, boolean all) 来更新布局:“调用 layout() 与调用 layout(true) 相同,后者告诉 ColumnLayout 在设置子元素的边界之前刷新其缓存。” 这都是正确的,从那以后我一直在做的事情。但这不是人们想要的,因为当您想要更新布局时,它基本上会破坏布局缓存的好处,因为一个或几个控件已经改变了需求。
想象一下,您在 GridLayout 中有一堆 StyledText 小部件,您需要更改其中一个的大小。在 StyledText 上调用 computeSize() 非常昂贵。而不是这个:
错误的:
parent.layout(true);
...它对所有孩子调用 computeSize(),即使他们的要求没有改变。你应该做这个:
对:
parent.changed(new Control[] { theChangedChild });
然后要么
rootComposite.layout(false, true);
或者
parent.layout(false);
不是很直观。layout() 的参数命名不当。与其称它为“已更改”,不如将其称为“ignoreCache”之类的。直观的事情是在发生变化时传递“true”。相反,您需要传递“false”,但在执行之前使用 changed() 使已更改控件的缓存无效...
请注意,调用 changed() 还将递归地使仅父控件的缓存在其自己的父控件中无效,这完全有意义。因此,当您调用 layout() 时,您应该在根组合(通常是 Shell)上调用它,并且 all=true,除非您知道更改控件的父级的大小将或不能响应更改。