当前位置:  开发笔记 > 编程语言 > 正文

为什么SWT Composite有时需要调用resize()来正确布局?

如何解决《为什么SWTComposite有时需要调用resize()来正确布局?》经验,为你挑选了3个好方法。

有时我们会遇到一个绝对拒绝正确摆脱的SWT复合材料.当我们在复合材料上调用dispose然后用另一个替换它时,我们经常会遇到这种情况; 虽然它似乎并不严格限于这种情况.

当我们遇到这个问题时,大约50%的时间,我们可以打电话pack()layout()违规复合,一切都会好的.但是,大约50%的时间我们必须这样做:

Point p = c.getSize();
c.setSize(p.x+1, p.y+1);
c.setSize(p);

几乎每种布局管理器组合都会发生这种情况.

我希望我有一个漂亮,简单,可重复的案例,但我没有.我希望有人能认出这个问题并说:"好吧,呃,你错过了xyz ......"



1> Peter Walser..:

在我看来,布局的缓存已经过时,需要刷新.

SWT中的布局支持缓存,通常会缓存控件的首选大小,或者他们喜欢缓存的任何内容:

public abstract class Layout {
    protected abstract Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache);
    protected boolean flushCache (Control control) {...}
    protected abstract void layout (Composite composite, boolean flushCache);
}

我对SWT编程(以前的Swing程序员)比较陌生,但遇到了布局没有正确更新的类似情况.我通常能够使用其他布局方法解决它们,这也会导致布局刷新其缓存:

layout(boolean changed)

layout(boolean changed, boolean allChildren)

希望有帮助......


感谢这个回答,使我走上了正确的道路,但是要添加它,还有一个requestLayout()API,可以类似于parent.changed(new Control [] {theChangedChild})来使用。调用layout()之前的API。https://bugs.eclipse.org/bugs/show_bug.cgi?id=468854

2> Peter Walser..:

与此同时,我在运行时更改或调整控件层次结构的某些部分时,更多地了解了SWT的缺点.当应该调整其最小或首选内容大小时,还需要明确更新ScrolledComposites和ExpandBars.

我写了一个小帮助方法,为已更改的控件重新验证控件层次结构的布局:

public static void revalidateLayout (Control control) {

    Control c = control;
    do {
        if (c instanceof ExpandBar) {
            ExpandBar expandBar = (ExpandBar) c;
            for (ExpandItem expandItem : expandBar.getItems()) {
                expandItem
                    .setHeight(expandItem.getControl().computeSize(expandBar.getSize().x, SWT.DEFAULT, true).y);
            }
        }
        c = c.getParent();

    } while (c != null && c.getParent() != null && !(c instanceof ScrolledComposite));

    if (c instanceof ScrolledComposite) {
        ScrolledComposite scrolledComposite = (ScrolledComposite) c;
        if (scrolledComposite.getExpandHorizontal() || scrolledComposite.getExpandVertical()) {
            scrolledComposite
                .setMinSize(scrolledComposite.getContent().computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
        } else {
            scrolledComposite.getContent().pack(true);
        }
    }
    if (c instanceof Composite) {
        Composite composite = (Composite) c;
        composite.layout(true, true);
    }
}


是的 - 我以前必须这样做 - 这很痛苦.对于可搜索性而言,将此作为单独的问题和答案来表达并不会有什么坏处.

3> 小智..:

复合材料的布局负责布置该复合材料的子元素.因此,如果复合材料的大小没有变化,但需要更新子项的相对位置和大小,则可以调用layout()复合材料.但是,如果需要更新复合材料本身的大小或位置,则必须调用layout()其父复合(等等,直到到达shell).

经验法则:如果您添加或删除了控件,或以其他方式完成了需要重新布局的操作,请向上移动窗口小部件层次结构,直到找到带有滚动条的复合并调用layout()它.使用滚动条停止复合的原因是它的大小不会随着更改而改变 - 它的滚动条会"吸收"它.

请注意,如果需要布局的更改不是新子项或已删除的子项,则应Composite.changed(new Control[] {changedControl})在调用布局之前调用.

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有