SWT:用组件重新填充 shell 时布局损坏

SWT: Layout broken when refilling a shell with components

我想定期清除 shell 中的所有内容并重新创建其中的组件。这是我正在尝试做的最小测试用例。起初,标签是按照布局并排放置的,但是当5秒后updateThread触发时,新创建的标签全部叠加在一起,完全忽略了布局。

package testpkg;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;

public class Test {
    public static void main(String[] args){
        Display display = new Display();
        Shell testShell = new Shell(display);
        FillLayout testLayout = new FillLayout();
        testShell.setLayout(testLayout);
        for(int i = 1; i<20; i++){
            Label label = new Label(testShell, SWT.BORDER);
            label.setText("HELLO"+i);
            label.pack();
        }
        testShell.open();
        Thread updateThread = new Thread(new Runnable(){
            public void run(){
                try {Thread.sleep(5000);} catch (Exception e){};
                display.getDefault().syncExec(new Runnable(){
                    public void run(){
                        for(Control control : testShell.getChildren()){
                            control.dispose();
                        }
                        for(int i = 1; i<20; i++){
                            Label label = new Label(testShell, SWT.BORDER);
                            label.setText("HELLO"+i);
                            label.pack();
                        }
                    }
                });
            }
        });
        updateThread.start();
        while (!testShell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}

我想定期更新(可变数量的)标签,但这样做时布局完全中断。

我注意到调整 window 的大小可以解决所有问题。因此,如果我将 window 变大然后变小一秒钟,它就可以工作。

你可以把这一行放在 for 循环之后:

    testShell.layout(true);

因此最终的 运行() 方法将如下所示:

    public void run() {
      for (Control control : testShell.getChildren()) {
        control.dispose();
      }
      for (int i = 1; i < 20; i++) {
        Label label = new Label(testShell, SWT.BORDER);
        label.setText("HELLO"+i);
        label.pack();
      }
      testShell.layout(true);
    }