SWT Shell会根据孩子的大小调整大小

时间:2013-11-25 22:07:47

标签: java swt eclipse-rcp jface

我正在处理此Composite画布,其中可添加和删除其他Composite

我对整个布局概念如何处于迷雾状态的理解。

当孩子被添加到容器中时,考虑到容器中有GridData填充父级,父母是否也应该知道孩子的大小调整?由于贝壳(顶级父母),儿童在布置容器后仍然隐藏。

如果问题太模糊,请不要犹豫,询问更多细节。另外,请尽量不要将我指向了解SWT中的布局文章。

/**
 * 
 * @author ggrec
 *
 */
public class SSCCE
{

    // ==================== 2. Instance Fields ============================

    private Composite componentContainer;

    private int componentCount = 0;

    // ==================== 3. Static Methods =============================

    public static void main(final String[] args)
    {
        new SSCCE();
    }

    // ==================== 4. Constructors ===============================

    private SSCCE()
    {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(1, false));

        createContents(shell);

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

    // ==================== 5. Creators ===================================

    private void createContents(final Composite parent)
    {
        parent.setLayout(new GridLayout());
        parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        final Button button = new Button(parent, SWT.PUSH);
        button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        button.setText("Add New Component");

        button.addSelectionListener(new SelectionAdapter()
        {
            @Override public void widgetSelected(final SelectionEvent e)
            {
                addNewComponent();

                componentContainer.layout();
            }
        });

        componentContainer = new Composite(parent, SWT.BORDER);
        componentContainer.setLayout(new GridLayout());
        componentContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    }

    // ==================== 6. Action Methods =============================

    private void addNewComponent()
    {
        final Composite component = new Composite(componentContainer, SWT.BORDER);
        component.setLayout(new FillLayout());
        component.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        final Label label = new Label(component, SWT.NONE);
        label.setText( String.valueOf(componentCount++) );
    }
}

有趣的事实: 这个问题与文章有关to this other one, that was posted 9 minutes ago。有人要么是通灵的,要么是跟踪我。

3 个答案:

答案 0 :(得分:11)

要让Shell调整大小,您需要布局所有内容并重新计算其大小:

shell.layout(true, true);

final Point newSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);  

shell.setSize(newSize);

根据更改的内容,您可以在shell layout()的{​​{1}}上调用Composite

答案 1 :(得分:3)

这里可能解决你问题的秘诀就是告诉父母孩子们已经调整了大小。所以,不,他们不会自动知道它已经发生了。

解决这个问题的方法是调用:

Parent.layout(true)

来自swt api的

public void layout(boolean changed)
  

如果接收器有布局,则要求布局布局(即设置接收器的子节点的大小和位置)。如果参数为true,则布局不得依赖于已缓存的有关直接子节点的任何信息。如果它是假的,布局可以(可能)通过假设接收器的子节点自上次布局以来没有改变状态来优化它正在进行的工作。如果接收器没有布局,则什么也不做。

     

如果因调用布局而调整子项大小,则resize事件将调用子项的布局。布局将在接收器的窗口小部件树中向下级联所有子窗口小部件,直到遇到未调整大小的子窗口。请注意,由于调整大小而导致的布局不会刷新任何缓存的信息(与布局(false)相同)。

     

注意:布局与绘画不同。如果孩子被移动或调整大小以使父母中的某个区域暴露出来,那么父母将会画画。如果没有孩子受到影响,父母将不会画画。

Parameters:
    changed - true if the layout must flush its caches, and false otherwise
Throws:
    SWTException -
    ERROR_WIDGET_DISPOSED - if the receiver has been disposed
    ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver

因此,在您的情况下,无论何时添加复合体的父级都调用layout()函数可以帮助您。

答案 2 :(得分:0)

正如你所说,我们两个问题都很相似,我发布的解决方案就是我所取得的成就。 如果这有助于你,请告诉我。

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Combo;


public class DynamicDialog extends Dialog {
   private Composite composite_2;


    /**
     * Create the dialog.
     * @param parentShell
     */
    public DynamicDialog(Shell parentShell) {
        super(parentShell);
    }

    /**
     * Create contents of the dialog.
     * @param parent
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite container = (Composite) super.createDialogArea(parent);
        container.setLayout(new FillLayout(SWT.HORIZONTAL));

        ScrolledComposite scrolledComposite = new ScrolledComposite(container, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        scrolledComposite.setExpandHorizontal(true);
        scrolledComposite.setExpandVertical(true);

        final Composite composite = new Composite(scrolledComposite, SWT.NONE);
        composite.setLayout(new GridLayout(1, false));
        scrolledComposite.setContent(composite);
        scrolledComposite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

        Composite composite_1 = new Composite(composite, SWT.NONE);
        composite_1.setLayout(new GridLayout(2, false));
        GridData gd_composite_1 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_composite_1.heightHint = 49;
        gd_composite_1.widthHint = 427;
        composite_1.setLayoutData(gd_composite_1);

        Label lblDefault = new Label(composite_1, SWT.NONE);
        lblDefault.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblDefault.setText("Default:");

        Combo combo = new Combo(composite_1, SWT.NONE);
        combo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));

        composite_2 = new Composite(composite, SWT.NONE);
        composite_2.setLayout(new GridLayout(4, false));
        GridData gd_composite_2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        /*gd_composite_2.heightHint = 32;
        gd_composite_2.widthHint = 426;*/
        composite_2.setLayoutData(gd_composite_2);

        Composite composite_3 = new Composite(composite, SWT.NONE);
        composite_3.setLayout(new GridLayout(1, false));
        GridData gd_composite_3 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_composite_3.heightHint = 38;
        gd_composite_3.widthHint = 427;
        composite_3.setLayoutData(gd_composite_3);

        Button btnAdd = new Button(composite_3, SWT.NONE);
        btnAdd.setText("Add");
        btnAdd.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {


                Label label2 = new Label(composite_2, SWT.NONE);
                label2.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
                        false, 1, 1));
                label2.setText("1");

                Text text_12 = new Text(composite_2, SWT.BORDER);
                text_12.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
                        false, 1, 1));

                Text text13 = new Text(composite_2, SWT.BORDER);
                text13.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
                        false, 1, 1));

                Button btnDelete = new Button(composite_2, SWT.NONE);
                btnDelete.setText("delete");
                composite_2.layout(true);


                composite_2.layout();
                // Point p = composite.getSize();
                // composite.setSize(SWT.DEFAULT,SWT.DEFAULT);
                // composite.setSize(p);

                composite.layout();


            }
        });






        return container;
    }

    /**
     * Create contents of the button bar.
     * @param parent
     */
    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
                true);
        createButton(parent, IDialogConstants.CANCEL_ID,
                IDialogConstants.CANCEL_LABEL, false);
    }

    /**
     * Return the initial size of the dialog.
     */
    @Override
    protected Point getInitialSize() {
        return new Point(450, 300);
    }

public static void main(String[] args){

    Shell shell =  new Shell(new Display());
    //shell.setLayout(new FillLayout());
    DynamicDialog dd = new DynamicDialog(shell);
    dd.open();

}
}