2

我的应用程序有一个带两个孩子的 SashForm。我希望左孩子在调整窗口大小时保持相同的大小。我希望 Eclipse 对 Package Explorer 和主编辑器做同样的事情。当您调整窗口大小时,只有文本编辑器会改变大小。但是,Package Explorer 仍然可以通过 sash 调整大小。

我尝试使用以下

sashForm.addControlListener(new ControlAdapter() {
    @Override
    public void controlResized(ControlEvent e) {
        int width = sashForm.getClientArea().width;
        int[] weights = sashForm.getWeights();
        weights[1] = width - weights[0];
        sashForm.setWeights(weights);
    }
});

问题是左侧尺寸的宽度要么缩小到 0,要么扩大太多。看起来权重在调用此方法之前已更新。

如果我将 weights[0] 设置为等于某个常数,它会执行我想要的操作。

4

3 回答 3

3

我设法运行了一个示例,它应该让您了解如何解决您的问题。问题是,SashForm使用权重而不是像素。因此,您必须根据父大小计算左孩子必须占据的百分比,并将其余部分分配给右孩子。

在我的代码示例中,您可以指定左孩子的宽度并为右孩子设置最小尺寸,以便SashForm始终显示两者。

private static final int MIN_WIDTH_LEFT = 100;
private static final int MIN_WIDTH_RIGHT = 50;

public static void main(String[] args)
{
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("StackOverflow");
    shell.setLayout(new FillLayout());

    final SashForm form = new SashForm(shell, SWT.HORIZONTAL);

    Button button = new Button(form, SWT.PUSH);
    button.setText("Left");

    Button buttonR = new Button(form, SWT.PUSH);
    buttonR.setText("Right");

    form.setWeights(new int[] {1, 2});

    shell.addListener(SWT.Resize, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            int width = shell.getClientArea().width;
            int[] weights = form.getWeights();

            if(width >= MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT)
            {
                weights[0] = 1000000 * MIN_WIDTH_LEFT / width;
                weights[1] = 1000000 - weights[0];
            }
            else
            {
                weights[0] = 1000000 * MIN_WIDTH_LEFT / (MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT);
                weights[1] = 1000000 * MIN_WIDTH_RIGHT / (MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT);
            }

            System.out.println(width + " " + Arrays.toString(weights));

            form.setWeights(weights);
        }
    });

    shell.pack();

    shell.setSize(600, 400);
    shell.open();
    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

这是它的样子:

启动:

在此处输入图像描述

调整大小后:

在此处输入图像描述

当减小窗口大小直到它太小而无法显示两个最小尺寸时:

在此处输入图像描述

正如您在这种情况下所看到的,左孩子的最小尺寸被忽略,仍然能够显示两个孩子。

于 2013-06-21T12:45:45.117 回答
3

这是我能想到的最好的解决方案。

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class Main {
private static int leftWidth, oldWeight;

public static void main(String[] args) {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("StackOverflow");
    shell.setLayout(new FillLayout());
    shell.setSize(600, 400);

    final SashForm form = new SashForm(shell, SWT.HORIZONTAL);

    final Button button = new Button(form, SWT.PUSH);
    button.setText("Left");

    button.addListener(SWT.Resize, new Listener() {
        @Override
        public void handleEvent(Event arg0) {
            int[] weights = form.getWeights();
            // oldWeights is used to distinguish between a window resize and
            // a sash move
            if (oldWeight != weights[0]) {
                System.out.println("Weights changed!");
                oldWeight = weights[0];
                leftWidth = (int) Math.round((double) form.getClientArea().width
                        * (double) weights[0]
                        / (double) (weights[0] + weights[1]));
            }
        }
    });

    Button buttonR = new Button(form, SWT.PUSH);
    buttonR.setText("Right");

    form.setWeights(new int[] { 200, 800 });
    leftWidth = 200;

    form.addListener(SWT.Resize, new Listener() {
        @Override
        public void handleEvent(Event arg0) {
            int width = form.getClientArea().width;
            int[] weights = form.getWeights();

            double perChange = (double) leftWidth / (double) width;

            weights[0] = (int) (perChange * 1000.0);
            weights[1] = 1000 - weights[0];

            // oldWeights must be set before form.setWeights
            oldWeight = weights[0];
            form.setWeights(weights);
        }
    });

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

由于舍入问题而调整窗口大小时,窗扇会跳跃约 1 像素,但它似乎符合我的要求。

这是一个非常hacky的解决方案,我想知道是否有更好的解决方案。如果您使窗口小于左按钮,它也会崩溃,但这很容易修复。

于 2013-06-21T17:14:32.053 回答
0

必须重写 SashForm 才能获得这种行为。 new SashForm(Composite parent, int style)是旧行为;new SashForm(Composite parent, int style, false)使用以像素为单位指定的宽度/高度。

未使用 SashForm 的两个以上 Composite 子项进行测试,如果您setLength在使用新行为时不这样做,则会出现奇怪的行为,但不会破坏 SashForm 的现有用途

例如:

public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
final SashForm form = new SashForm(shell, SWT.HORIZONTAL);
Button button = new Button(form, SWT.PUSH);
button.setText("Left");
Button buttonR = new Button(form, SWT.PUSH);
buttonR.setText("Right");
form.setLengths(new int[] { 250, 25 });
shell.pack();
shell.setSize(600, 400);
shell.open();
while (!shell.isDisposed())
{
    if (!display.readAndDispatch())
        display.sleep();
}
display.dispose();
}

第一个按钮将默认为 250 像素,第二个是其余的外壳

SashForm.java:

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;

public class SashForm extends Composite {

    /**
    * The width of all sashes in the form.
    */
    public int SASH_WIDTH = 3;

    int sashStyle;
    final private boolean weighted;
    Sash[] sashes = new Sash[0];
    // Remember background and foreground
    // colors to determine whether to set
    // sashes to the default color (null) or
    // a specific color
    Color background = null;
    Color foreground = null;
    Control[] controls = new Control[0];
    Control maxControl = null;
    Listener sashListener;
    static final int DRAG_MINIMUM = 20;

public SashForm(Composite parent, int style) {
    super(parent, checkStyle(style));
    super.setLayout(new SashFormLayout());
    sashStyle = ((style & SWT.VERTICAL) != 0) ? SWT.HORIZONTAL : SWT.VERTICAL;
    if ((style & SWT.BORDER) != 0) sashStyle |= SWT.BORDER;
    if ((style & SWT.SMOOTH) != 0) sashStyle |= SWT.SMOOTH;
    sashListener = new Listener() {
        public void handleEvent(Event e) {
            onDragSash(e);
        }
    };
    weighted = true;
}
public SashForm(Composite parent, int style, boolean weighted) {
    super(parent, checkStyle(style));
    super.setLayout(new SashFormLayout());
    sashStyle = ((style & SWT.VERTICAL) != 0) ? SWT.HORIZONTAL : SWT.VERTICAL;
    if ((style & SWT.BORDER) != 0) sashStyle |= SWT.BORDER;
    if ((style & SWT.SMOOTH) != 0) sashStyle |= SWT.SMOOTH;
    sashListener = new Listener() {
        public void handleEvent(Event e) {
            onDragSash(e);
        }
    };
    this.weighted = weighted;
}
static int checkStyle (int style) {
    int mask = SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
    return style & mask;
}
Sash createSash() {
    Sash sash = new Sash(this, sashStyle);
    sash.setBackground(background);
    sash.setForeground(foreground);
    sash.setToolTipText(getToolTipText());
    sash.addListener(SWT.Selection, sashListener);
    return sash;
}

@Override
public int getOrientation() {
    //checkWidget();
    return (sashStyle & SWT.VERTICAL) != 0 ? SWT.HORIZONTAL : SWT.VERTICAL;
}
/**
 * Returns the width of the sashes when the controls in the SashForm are 
 * laid out.
 * 
 * @return the width of the sashes
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.4
 */
public int getSashWidth() {
    checkWidget();
    return SASH_WIDTH;
}
@Override
public int getStyle() {
    int style = super.getStyle();
    style |= getOrientation() == SWT.VERTICAL ? SWT.VERTICAL : SWT.HORIZONTAL;
    if ((sashStyle & SWT.SMOOTH) != 0) style |= SWT.SMOOTH;
    return style;
}
/**
 * Answer the control that currently is maximized in the SashForm.  
 * This value may be null.
 * 
 * @return the control that currently is maximized or null
 */
public Control getMaximizedControl(){
    //checkWidget();
    return this.maxControl;
}

public int[] getWeights() {
    checkWidget();
    Control[] cArray = getControls(false);
    int[] ratios = new int[cArray.length];
    for (int i = 0; i < cArray.length; i++) {
        Object data = cArray[i].getLayoutData();
        if (data != null && data instanceof SashFormData) {
            ratios[i] = (int)(((SashFormData)data).weight * 1000 >> 16);
        } else {
            ratios[i] = 200;
        }
    }
    return ratios;
}
Control[] getControls(boolean onlyVisible) {
    Control[] children = getChildren();
    Control[] result = new Control[0];
    for (int i = 0; i < children.length; i++) {
        if (children[i] instanceof Sash) continue;
        if (onlyVisible && !children[i].getVisible()) continue;

        Control[] newResult = new Control[result.length + 1];
        System.arraycopy(result, 0, newResult, 0, result.length);
        newResult[result.length] = children[i];
        result = newResult;
    }
    return result;
}
boolean getWeighted() {
    return weighted;
}
void onDragSash(Event event) {
    Sash sash = (Sash)event.widget;
    int sashIndex = -1;
    for (int i= 0; i < sashes.length; i++) {
        if (sashes[i] == sash) {
            sashIndex = i;
            break;
        }
    }
    if (sashIndex == -1) return;

    Control c1 = controls[sashIndex];
    Control c2 = controls[sashIndex + 1];
    Rectangle b1 = c1.getBounds();
    Rectangle b2 = c2.getBounds();

    Rectangle sashBounds = sash.getBounds();
    Rectangle area = getClientArea();
    boolean correction = false;
    if (getOrientation() == SWT.HORIZONTAL) {
        correction = b1.width < DRAG_MINIMUM || b2.width < DRAG_MINIMUM;
        int totalWidth = b2.x + b2.width - b1.x; 
        int shift = event.x - sashBounds.x;
        b1.width += shift;
        b2.x += shift;
        b2.width -= shift;
        if (b1.width < DRAG_MINIMUM) {
            b1.width = DRAG_MINIMUM;
            b2.x = b1.x + b1.width + sashBounds.width;
            b2.width = totalWidth - b2.x;
            event.x = b1.x + b1.width;
            event.doit = false;
        }
        if (b2.width < DRAG_MINIMUM) {
            b1.width = totalWidth - DRAG_MINIMUM - sashBounds.width;
            b2.x = b1.x + b1.width + sashBounds.width;
            b2.width = DRAG_MINIMUM;
            event.x = b1.x + b1.width;
            event.doit = false;
        }
        Object data1 = c1.getLayoutData();
        if (data1 == null || !(data1 instanceof SashFormData)) {
            data1 = new SashFormData();
            c1.setLayoutData(data1);
        }
        Object data2 = c2.getLayoutData();
        if (data2 == null || !(data2 instanceof SashFormData)) {
            data2 = new SashFormData();
            c2.setLayoutData(data2);
        }
        ((SashFormData)data1).weight = (((long)b1.width << 16) + area.width - 1) / area.width;
        ((SashFormData)data1).length = b1.width;
        ((SashFormData)data2).weight = (((long)b2.width << 16) + area.width - 1) / area.width;
        ((SashFormData)data2).length = b2.width;
    } else {
        correction = b1.height < DRAG_MINIMUM || b2.height < DRAG_MINIMUM;
        int totalHeight = b2.y + b2.height - b1.y;
        int shift = event.y - sashBounds.y;
        b1.height += shift;
        b2.y += shift;
        b2.height -= shift;
        if (b1.height < DRAG_MINIMUM) {
            b1.height = DRAG_MINIMUM;
            b2.y = b1.y + b1.height + sashBounds.height;
            b2.height = totalHeight - b2.y;
            event.y = b1.y + b1.height;
            event.doit = false;
        }
        if (b2.height < DRAG_MINIMUM) {
            b1.height = totalHeight - DRAG_MINIMUM - sashBounds.height;
            b2.y = b1.y + b1.height + sashBounds.height;
            b2.height = DRAG_MINIMUM;
            event.y = b1.y + b1.height;
            event.doit = false;
        }
        Object data1 = c1.getLayoutData();
        if (data1 == null || !(data1 instanceof SashFormData)) {
            data1 = new SashFormData();
            c1.setLayoutData(data1);
        }
        Object data2 = c2.getLayoutData();
        if (data2 == null || !(data2 instanceof SashFormData)) {
            data2 = new SashFormData();
            c2.setLayoutData(data2);
        }
        ((SashFormData)data1).weight = (((long)b1.height << 16) + area.height - 1) / area.height;
        ((SashFormData)data2).weight = (((long)b2.height << 16) + area.height - 1) / area.height;
    }
    if (correction || (event.doit && event.detail != SWT.DRAG)) {
        c1.setBounds(b1);
        sash.setBounds(event.x, event.y, event.width, event.height);
        c2.setBounds(b2);
    }
}

@Override
public void setOrientation(int orientation) {
    checkWidget();
    if (orientation == SWT.RIGHT_TO_LEFT || orientation == SWT.LEFT_TO_RIGHT) {
        super.setOrientation(orientation);
        return;
    }
    if (getOrientation() == orientation) return;
    if (orientation != SWT.HORIZONTAL && orientation != SWT.VERTICAL) {
        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    }
    sashStyle &= ~(SWT.HORIZONTAL | SWT.VERTICAL);
    sashStyle |= orientation == SWT.VERTICAL ? SWT.HORIZONTAL : SWT.VERTICAL;
    for (int i = 0; i < sashes.length; i++) {
        sashes[i].dispose();
        sashes[i] = createSash();
    }
    layout(false);
}
@Override
public void setBackground (Color color) {
    super.setBackground(color);
    background = color;
    for (int i = 0; i < sashes.length; i++) {
        sashes[i].setBackground(background);
    }
}
@Override
public void setForeground (Color color) {
    super.setForeground(color);
    foreground = color;
    for (int i = 0; i < sashes.length; i++) {
        sashes[i].setForeground(foreground);
    }
}

@Override
public void setLayout (Layout layout) {
    checkWidget();
    return;
}

public void setMaximizedControl(Control control){
    checkWidget();
    if (control == null) {
        if (maxControl != null) {
            this.maxControl = null;
            layout(false);
            for (int i= 0; i < sashes.length; i++){
                sashes[i].setVisible(true);
            }
        }
        return;
    }

    for (int i= 0; i < sashes.length; i++){
        sashes[i].setVisible(false);
    }
    maxControl = control;
    layout(false);
}

public void setSashWidth(int width) {
    checkWidget();
    if (SASH_WIDTH == width) return;
    SASH_WIDTH = width;
    layout(false);
}
@Override
public void setToolTipText(String string) {
    super.setToolTipText(string);
    for (int i = 0; i < sashes.length; i++) {
        sashes[i].setToolTipText(string);
    }
}

public void setWeights(int[] weights) {
    checkWidget();
    Control[] cArray = getControls(false);
    if (weights == null || weights.length != cArray.length) {
        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    }

    int total = 0;
    for (int i = 0; i < weights.length; i++) {
        if (weights[i] < 0) {
            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
        }
        total += weights[i];
    }
    if (total == 0) {
        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    }
    for (int i = 0; i < cArray.length; i++) {
        Object data = cArray[i].getLayoutData();
        if (data == null || !(data instanceof SashFormData)) {
            data = new SashFormData();
            cArray[i].setLayoutData(data);
        }
        ((SashFormData)data).weight = (((long)weights[i] << 16) + total - 1) / total;
    }

    layout(false);
}

public void setLengths(int[] lengths) {
    checkWidget();
    Control[] cArray = getControls(false);
    if (lengths == null || lengths.length != cArray.length) {
        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    }

    int total = 0;
    for (int i = 0; i < lengths.length; i++) {
        if (lengths[i] < 0) {
            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
        }
        total += lengths[i];
    }
    if (total == 0) {
        SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    }
    for (int i = 0; i < cArray.length; i++) {
        Object data = cArray[i].getLayoutData();
        if (data == null || !(data instanceof SashFormData)) {
            data = new SashFormData();
            cArray[i].setLayoutData(data);
        }
        ((SashFormData)data).length = lengths[i];
    }

    layout(false);
}
}

SashFormData.java:

class SashFormData {

    long weight;
    int length;

String getName () {
    String string = getClass ().getName ();
    int index = string.lastIndexOf ('.');
    if (index == -1) return string;
    return string.substring (index + 1, string.length ());
}

@Override
public String toString () {
    return getName()+" {length="+length+", weight="+weight+"}"; //$NON-NLS-2$
}
}

SashFormLayout.java:

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

class SashFormLayout extends Layout {
    @Override
    protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
        SashForm sashForm = (SashForm)composite;
        Control[] cArray = sashForm.getControls(true);
        int width = 0;
        int height = 0;
        if (cArray.length == 0) {       
            if (wHint != SWT.DEFAULT) width = wHint;
            if (hHint != SWT.DEFAULT) height = hHint;
            return new Point(width, height);
        }
        // determine control sizes
        boolean vertical = sashForm.getOrientation() == SWT.VERTICAL;

        if (sashForm.getWeighted()) {
            int maxIndex = 0;
            int maxValue = 0;
            for (int i = 0; i < cArray.length; i++) {
                if (vertical) {
                    Point size = cArray[i].computeSize(wHint, SWT.DEFAULT, flushCache);
                    if (size.y > maxValue) {
                        maxIndex = i;
                        maxValue = size.y;
                    }
                    width = Math.max(width, size.x);
                } else {
                    Point size = cArray[i].computeSize(SWT.DEFAULT, hHint, flushCache);
                    if (size.x > maxValue) {
                        maxIndex = i;
                        maxValue = size.x;
                    }
                    height = Math.max(height, size.y);
                }
            }
            // get the ratios
            long[] ratios = new long[cArray.length];
            long total = 0;
            for (int i = 0; i < cArray.length; i++) {
                Object data = cArray[i].getLayoutData();
                if (data != null && data instanceof SashFormData) {
                    ratios[i] = ((SashFormData)data).weight;
                } else {
                    data = new SashFormData();
                    cArray[i].setLayoutData(data);
                    ((SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;

                }
                total += ratios[i];
            }
            if (ratios[maxIndex] > 0) {
                int sashwidth = sashForm.sashes.length > 0 ? sashForm.SASH_WIDTH + sashForm.sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
                if (vertical) {
                    height += (int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
                } else {
                    width += (int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
                }
            }
        } else {
            int maxIndex = 0;
            int maxValue = 0;
            for (int i = 0; i < cArray.length; i++) {
                if (vertical) {
                    Point size = cArray[i].computeSize(wHint, SWT.DEFAULT, flushCache);
                    if (size.y > maxValue) {
                        maxIndex = i;
                        maxValue = size.y;
                    }
                    width = Math.max(width, size.x);
                } else {
                    Point size = cArray[i].computeSize(SWT.DEFAULT, hHint, flushCache);
                    if (size.x > maxValue) {
                        maxIndex = i;
                        maxValue = size.x;
                    }
                    height = Math.max(height, size.y);
                }
            }
            // get the lengths
            int[] lengths = new int[cArray.length];
            long total = 0;
            for (int i = 0; i < cArray.length; i++) {
                Object data = cArray[i].getLayoutData();
                if (data != null && data instanceof SashFormData) {
                    lengths[i] = ((SashFormData)data).length;
                } else {
                    data = new SashFormData();
                    cArray[i].setLayoutData(data);
                    ((SashFormData)data).length = sashForm.getOrientation() == SWT.HORIZONTAL ? cArray[i].getSize().x : cArray[i].getSize().y;
                }
                total += lengths[i];
            }
            if (lengths[maxIndex] > 0) {
                int sashwidth = sashForm.sashes.length > 0 ? sashForm.SASH_WIDTH + sashForm.sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
                if (vertical) {
                    height += total + (cArray.length - 1) * sashwidth;
                } else {
                    width +=  total + (cArray.length - 1) * sashwidth;
                }
            }
        }
        width += sashForm.getBorderWidth()*2;
        height += sashForm.getBorderWidth()*2;
        if (wHint != SWT.DEFAULT) width = wHint;
        if (hHint != SWT.DEFAULT) height = hHint;
        return new Point(width, height);
    }

    @Override
    protected boolean flushCache(Control control) {
        return true;
    }

    @Override
    protected void layout(Composite composite, boolean flushCache) {
        SashForm sashForm = (SashForm)composite;
        Rectangle area = sashForm.getClientArea();
        if (area.width <= 1 || area.height <= 1) return;

        Control[] newControls = sashForm.getControls(true);
        if (sashForm.controls.length == 0 && newControls.length == 0) return;
        sashForm.controls = newControls;

        Control[] controls = sashForm.controls;

        if (sashForm.maxControl != null && !sashForm.maxControl.isDisposed()) {
            for (int i= 0; i < controls.length; i++){
                if (controls[i] != sashForm.maxControl) {
                    controls[i].setBounds(-200, -200, 0, 0);
                } else {
                    controls[i].setBounds(area);
                }
            }
            return;
        }

        // keep just the right number of sashes
        if (sashForm.sashes.length < controls.length - 1) {
            Sash[] newSashes = new Sash[controls.length - 1];
            System.arraycopy(sashForm.sashes, 0, newSashes, 0, sashForm.sashes.length);
            for (int i = sashForm.sashes.length; i < newSashes.length; i++) {
                newSashes[i] = sashForm.createSash();
            }
            sashForm.sashes = newSashes;
        }
        if (sashForm.sashes.length > controls.length - 1) {
            if (controls.length == 0) {
                for (int i = 0; i < sashForm.sashes.length; i++) {
                    sashForm.sashes[i].dispose();
                }
                sashForm.sashes = new Sash[0];
            } else {
                Sash[] newSashes = new Sash[controls.length - 1];
                System.arraycopy(sashForm.sashes, 0, newSashes, 0, newSashes.length);
                for (int i = controls.length - 1; i < sashForm.sashes.length; i++) {
                    sashForm.sashes[i].dispose();
                }
                sashForm.sashes = newSashes;
            }
        }
        if (controls.length == 0) return;
        Sash[] sashes = sashForm.sashes;

        if (sashForm.getWeighted()) {
            // get the ratios
            long[] ratios = new long[controls.length];
            long total = 0;
            for (int i = 0; i < controls.length; i++) {
                Object data = controls[i].getLayoutData();
                if (data != null && data instanceof SashFormData) {
                    ratios[i] = ((SashFormData)data).weight;
                } else {
                    data = new SashFormData();
                    controls[i].setLayoutData(data);
                    ((SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;

                }
                total += ratios[i];
            }
            int sashwidth = sashes.length > 0 ? sashForm.SASH_WIDTH + sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
            if (sashForm.getOrientation() == SWT.HORIZONTAL) {
                int width = (int)(ratios[0] * (area.width - sashes.length * sashwidth) / total);
                int x = area.x;
                controls[0].setBounds(x, area.y, width, area.height);
                x += width;
                for (int i = 1; i < controls.length - 1; i++) {
                    sashes[i - 1].setBounds(x, area.y, sashwidth, area.height);
                    x += sashwidth;
                    width = (int)(ratios[i] * (area.width - sashes.length * sashwidth) / total);
                    controls[i].setBounds(x, area.y, width, area.height);
                    x += width;
                }
                if (controls.length > 1) {
                    sashes[sashes.length - 1].setBounds(x, area.y, sashwidth, area.height);
                    x += sashwidth;
                    width = area.width - x;
                    controls[controls.length - 1].setBounds(x, area.y, width, area.height);
                }
            } else {
                int height = (int)(ratios[0] * (area.height - sashes.length * sashwidth) / total);
                int y = area.y;
                controls[0].setBounds(area.x, y, area.width, height);
                y += height;
                for (int i = 1; i < controls.length - 1; i++) {
                    sashes[i - 1].setBounds(area.x, y, area.width, sashwidth);
                    y += sashwidth;
                    height = (int)(ratios[i] * (area.height - sashes.length * sashwidth) / total);
                    controls[i].setBounds(area.x, y, area.width, height);
                    y += height;
                }
                if (controls.length > 1) {
                    sashes[sashes.length - 1].setBounds(area.x, y, area.width, sashwidth);
                    y += sashwidth;
                    height = area.height - y;
                    controls[controls.length - 1].setBounds(area.x, y, area.width, height);
                }

            } 
        } else {
            // get the lengths
            int[] lengths = new int[controls.length];
            for (int i = 0; i < controls.length; i++) {
                Object data = controls[i].getLayoutData();
                if (data != null && data instanceof SashFormData) {
                    lengths[i] = ((SashFormData)data).length;
                } else {
                    data = new SashFormData();
                    controls[i].setLayoutData(data);
                    ((SashFormData)data).length = sashForm.getOrientation() == SWT.HORIZONTAL ? controls[i].getSize().x : controls[i].getSize().y;
                }
            }
            int sashwidth = sashes.length > 0 ? sashForm.SASH_WIDTH + sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
            if (sashForm.getOrientation() == SWT.HORIZONTAL) {
                int width = lengths[0];
                int x = area.x;
                controls[0].setBounds(x, area.y, width, area.height);
                x += width;
                for (int i = 1; i < controls.length - 1; i++) {
                    sashes[i - 1].setBounds(x, area.y, sashwidth, area.height);
                    x += sashwidth;
                    width = lengths[i];
                    controls[i].setBounds(x, area.y, width, area.height);
                    x += width;
                }
                if (controls.length > 1) {
                    sashes[sashes.length - 1].setBounds(x, area.y, sashwidth, area.height);
                    x += sashwidth;
                    width = area.width - x;
                    controls[controls.length - 1].setBounds(x, area.y, width, area.height);
                }
            } else {
                int height = lengths[0];
                int y = area.y;
                controls[0].setBounds(area.x, y, area.width, height);
                y += height;
                for (int i = 1; i < controls.length - 1; i++) {
                    sashes[i - 1].setBounds(area.x, y, area.width, sashwidth);
                    y += sashwidth;
                    height = lengths[i];
                    controls[i].setBounds(area.x, y, area.width, height);
                    y += height;
                }
                if (controls.length > 1) {
                    sashes[sashes.length - 1].setBounds(area.x, y, area.width, sashwidth);
                    y += sashwidth;
                    height = area.height - y;
                    controls[controls.length - 1].setBounds(area.x, y, area.width, height);
                }

            }
        }
    }
}
于 2016-04-19T17:40:40.550 回答