swt复杂子控件的增加删除

swt中我们要删除一个子控件一般使用dispose。现在我们要实现这样的效果,按某个按钮,删除一个子控件,再按一次按钮,又把这个子控件加回来。如果删除的时候使用dispose,那增加的时候需要重新创建这个子控件,如果这个子控件非常复杂,那么删除、增加的效率会很低。用setVisible(false)方法可以隐藏控件,但是有不足之处,这个时候控件虽然不显示但依然占着位置。如下面2张图所示。

swt复杂子控件的增加删除_第1张图片

swt复杂子控件的增加删除_第2张图片


怎么样很好的实现这个功能呢?

可以使用setParent这个函数,删除子控件时,只要把子控件指定另一个父窗口,然后增加子控件的时候把子控件的父窗口设置回来就可以了。

注意public boolean setParent (Composite parent) ,这个是Control的函数,parent不能为null,setParent 调用涉及到2个Composite(即它的前后父窗口),要对这2个Composite  pack一下。

有demo如下


package test;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class ControlSwitcher {
    public static void main(String[] args) {
        Display display = new Display();
        final Shell shell = new Shell(display);
        GridLayout gl = new GridLayout();
        gl.marginWidth = gl.marginHeight = 20;
        shell.setLayout(gl);

        final Composite c1 = new Composite(shell, SWT.NONE);
        c1.setBackground(new Color(display, 255, 160, 160));
        RowLayout layout = new RowLayout(SWT.VERTICAL);
        c1.setLayout(layout);

        final Composite c2 = new Composite(c1, SWT.NONE);
        c2.setBackground(new Color(display, 160, 255, 160));
        c2.setLayout(new RowLayout());

        final Label lbl = new Label(c2, SWT.NORMAL);
        lbl.setText("Hello world");

        final Button btn = new Button(c2, SWT.PUSH);
        btn.setText("Switch");
        btn.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent arg0) {
                Composite target;
                if (btn.getParent().equals(c2)) {
                    target = c1;
                } else {
                    target = c2;
                }
                boolean success = btn.setParent(target);
                if (success) {
                    target.pack();
                    shell.pack();
                } else {
                    throw new RuntimeException("Not supported by this platform");
                }
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent arg0) {
            }
        });

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }
}




你可能感兴趣的:(swt复杂子控件的增加删除)