SWT Sash / SashForm镜像

时间:2014-06-03 12:42:33

标签: java layout swt

我尝试在水平SashForm(Parent)中实现上层和下层SashForms(Children A和B)。我希望能够拖动其中一个孩子(儿童A)的(垂直)窗扇并且让另一个孩子(儿童B)的(垂直)窗扇完全模仿A的水平位置。 为此,我尝试了一个hack创建一个暴露SashForms框格的'ModifiedSashForm':

public Sash[] getSashes() {
return sashes;

}

然后我创建了一个扩展ModifiedSashForm并覆盖

的类
public void onDragSash(Event event){

...

向听众(例如Child A)发送一条注释,表明已拖动B的腰带:     如果(sash.getParent()。的getData(WidgetData.DATA_DRAG_SOURCE).equals(WidgetData.DRAG_SOURCE.SOURCE)){             fireSashDragged(event,sashIndex);         }}

然后,孩子A将B的腰带替换为事件源(!):

if(sashes[sashIndex]!=null){
            event.widget=sashes[sashIndex];
        }

        listener.onDragSash(event);

我得到一个有点功能的gui。但是我遇到了不同步的腰带问题。代码是讨厌的,我宁愿不以这种方式屠宰SWT。 然后我尝试获得Child B的重量并将它们推入A - 但又一次出现问题 - 特别是当腰带被拉近彼此时,听众的重量顺序会翻转。

接下来我尝试使用Sash和FormLayout。示例代码如下 - 但我仍然无法使上部垂直窗扇完全模仿下部垂直窗扇的移动,反之亦然。

//基于http://www.eclipse.org/swt/snippets/ SWT Snippet107

public class SashTest {
final private List<Sash> listeners = new ArrayList<Sash>();
private Shell shell;

public static void main(String[] args) {
    new SashTest().run();

}

void run() {
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("SashTest");
    this.shell = shell;
    init();

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

void init() {

    final FormLayout form = new FormLayout();
    shell.setLayout(form);

    SashForm sashForm = new SashForm(shell, SWT.VERTICAL);
    sashForm.setLayoutData(new FormData());
    Composite comp1 = new Composite(sashForm, SWT.NONE);
    comp1.setLayout(new FormLayout());
    createTopArea(comp1);

    Composite comp2 = new Composite(sashForm, SWT.NONE);
    comp2.setLayout(new FormLayout());
    createBottomArea(comp2);

}

void createTopArea(Composite comp) {
    Button button1 = new Button(comp, SWT.PUSH);
    FormData fd_button1 = new FormData();
    fd_button1.bottom = new FormAttachment(0);
    fd_button1.right = new FormAttachment(0);
    fd_button1.top = new FormAttachment(0);
    fd_button1.left = new FormAttachment(0);
    button1.setLayoutData(fd_button1);
    button1.setText("Button 1");

    final Sash sash = new Sash(comp, SWT.VERTICAL);
    FormData fd_sash = new FormData();
    fd_sash.bottom = new FormAttachment(0);
    fd_sash.right = new FormAttachment(0);
    fd_sash.top = new FormAttachment(0);
    fd_sash.left = new FormAttachment(0);
    sash.setLayoutData(fd_sash);
    //add the upper sash to listeners for bottom sash movement
    listeners.add(sash);

    Button button2 = new Button(comp, SWT.PUSH);
    FormData fd_button2 = new FormData();
    fd_button2.bottom = new FormAttachment(0);
    fd_button2.right = new FormAttachment(0);
    fd_button2.top = new FormAttachment(0);
    fd_button2.left = new FormAttachment(0);
    button2.setLayoutData(fd_button2);
    button2.setText("Button 2");

    FormData button1Data = new FormData();
    button1Data.left = new FormAttachment(0, 0);
    button1Data.right = new FormAttachment(sash, 0);
    button1Data.top = new FormAttachment(0, 0);
    button1Data.bottom = new FormAttachment(100, 0);
    button1.setLayoutData(button1Data);

    final int limit = 20, percent = 50;
    final FormData sashData = new FormData();
    sashData.left = new FormAttachment(percent, 0);
    sashData.top = new FormAttachment(0, 0);
    sashData.bottom = new FormAttachment(100, 0);
    sash.setLayoutData(sashData);
    sash.addListener(SWT.Selection, new Listener() {
        @Override
        public void handleEvent(Event e) {
            Rectangle sashRect = sash.getBounds();
            Rectangle shellRect = shell.getClientArea();
            int right = shellRect.width - sashRect.width - limit;
            e.x = Math.max(Math.min(e.x, right), limit);
            if (e.x != sashRect.x) {
                sashData.left = new FormAttachment(0, e.x);
                shell.layout();
                notifyListeners(sashData);
            }
        }
    });

    FormData button2Data = new FormData();
    button2Data.left = new FormAttachment(sash, 0);
    button2Data.right = new FormAttachment(100, 0);
    button2Data.top = new FormAttachment(0, 0);
    button2Data.bottom = new FormAttachment(100, 0);
    button2.setLayoutData(button2Data);

}

void createBottomArea(Composite comp) {
    Button button3 = new Button(comp, SWT.PUSH);
    FormData fd_button1 = new FormData();
    fd_button1.bottom = new FormAttachment(0);
    fd_button1.right = new FormAttachment(0);
    fd_button1.top = new FormAttachment(0);
    fd_button1.left = new FormAttachment(0);
    button3.setLayoutData(fd_button1);
    button3.setText("Button 3");

    final Sash sash2 = new Sash(comp, SWT.VERTICAL);
    FormData fd_sash2 = new FormData();
    fd_sash2.bottom = new FormAttachment(0);
    fd_sash2.right = new FormAttachment(0);
    fd_sash2.top = new FormAttachment(0);
    fd_sash2.left = new FormAttachment(0);
    sash2.setLayoutData(fd_sash2);

    Button button4 = new Button(comp, SWT.PUSH);
    FormData fd_button2 = new FormData();
    fd_button2.bottom = new FormAttachment(0);
    fd_button2.right = new FormAttachment(0);
    fd_button2.top = new FormAttachment(0);
    fd_button2.left = new FormAttachment(0);
    button4.setLayoutData(fd_button2);
    button4.setText("Button 4");

    FormData button3Data = new FormData();
    button3Data.left = new FormAttachment(0, 0);
    button3Data.right = new FormAttachment(sash2, 0);
    button3Data.top = new FormAttachment(0, 0);
    button3Data.bottom = new FormAttachment(100, 0);
    button3.setLayoutData(button3Data);

    final int limit = 20, percent = 50;
    final FormData sashData2 = new FormData();
    sashData2.left = new FormAttachment(percent, 0);
    sashData2.top = new FormAttachment(0, 0);
    sashData2.bottom = new FormAttachment(100, 0);
    sash2.setLayoutData(sashData2);
    sash2.addListener(SWT.Selection, new Listener() {
        @Override
        public void handleEvent(Event e) {
            Rectangle sashRect = sash2.getBounds();
            Rectangle shellRect = shell.getClientArea();
            int right = shellRect.width - sashRect.width - limit;
            e.x = Math.max(Math.min(e.x, right), limit);
            if (e.x != sashRect.x) {
                sashData2.left = new FormAttachment(0, e.x);
                shell.layout();
            }
        }
    });

    FormData button4Data = new FormData();
    button4Data.left = new FormAttachment(sash2, 0);
    button4Data.right = new FormAttachment(100, 0);
    button4Data.top = new FormAttachment(0, 0);
    button4Data.bottom = new FormAttachment(100, 0);
    button4.setLayoutData(button4Data);

}

void notifyListeners(FormData formData){
    for(Sash sash: listeners){
        Rectangle sashRect = sash.getBounds();

        FormData sashData = formData;
        sash.setLayoutData(sashData);
        shell.layout();
    }

}

}

我是否必须编写自己的小部件来执行此操作,还是可以使用Sash / SashForm?

Baz,我在这里编辑了你的课程(评论太大了):

public class SashMirror {
public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setMinimumSize(new Point(200, 200));
    shell.setText("StackOverflow");
    shell.setLayout(new FillLayout(SWT.HORIZONTAL));
    final SashForm divider = new SashForm(shell, SWT.VERTICAL);
    divider.setLayout(new FillLayout(SWT.HORIZONTAL));

    final SashForm top = new SashForm(divider, SWT.HORIZONTAL);
    top.setLayout(new FillLayout(SWT.HORIZONTAL));

    final SashForm bottom = new SashForm(divider, SWT.HORIZONTAL);
    bottom.setLayout(new FillLayout(SWT.HORIZONTAL));

    Canvas canvasTopLeft = new Canvas(top, SWT.NONE);
    canvasTopLeft
            .setBackground(SWTResourceManager.getColor(SWT.COLOR_CYAN));
    canvasTopLeft.setLayout(new FillLayout(SWT.HORIZONTAL));

    Canvas canvasTopMiddle = new Canvas(top, SWT.NONE);
    canvasTopMiddle.setBackground(SWTResourceManager
            .getColor(SWT.COLOR_WHITE));
    canvasTopMiddle.setLayout(new FillLayout(SWT.HORIZONTAL));

    Canvas canvasTopRight = new Canvas(top, SWT.NONE);
    canvasTopRight.setBackground(SWTResourceManager
            .getColor(SWT.COLOR_BLUE));
    canvasTopRight.setLayout(new FillLayout(SWT.HORIZONTAL));

    Canvas canvasBottomLeft = new Canvas(bottom, SWT.NONE);
    canvasBottomLeft.setBackground(SWTResourceManager
            .getColor(SWT.COLOR_DARK_YELLOW));
    canvasBottomLeft.setLayout(new FillLayout(SWT.HORIZONTAL));

    Canvas canvasBottomMiddle = new Canvas(bottom, SWT.NONE);
    canvasBottomMiddle.setBackground(SWTResourceManager
            .getColor(SWT.COLOR_DARK_RED));
    canvasBottomMiddle.setLayout(new FillLayout(SWT.HORIZONTAL));

    Canvas canvasBottomRight = new Canvas(bottom, SWT.NONE);
    canvasBottomRight.setBackground(SWTResourceManager
            .getColor(SWT.COLOR_DARK_GREEN));
    canvasBottomRight.setLayout(new FillLayout(SWT.HORIZONTAL));

    top.setWeights(new int[] { 2, 2, 2 });
    bottom.setWeights(new int[] { 2, 2, 2 });

    canvasBottomLeft.addListener(SWT.Resize, new Listener() {
        @Override
        public void handleEvent(Event arg0) {
            top.setWeights(bottom.getWeights());
        }
    });

    canvasTopLeft.addListener(SWT.Resize, new Listener() {
        @Override
        public void handleEvent(Event arg0) {
            bottom.setWeights(top.getWeights());
        }
    });

    shell.pack();
    shell.open();

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

}

1 个答案:

答案 0 :(得分:3)

这完美无缺:

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

    final SashForm top = new SashForm(shell, SWT.HORIZONTAL);
    top.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    final SashForm bottom = new SashForm(shell, SWT.HORIZONTAL);
    bottom.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    Button topLeft = new Button(top, SWT.PUSH);
    topLeft.setText("Top left");
    new Button(top, SWT.PUSH).setText("Top right");
    Button bottomLeft = new Button(bottom, SWT.PUSH);
    bottomLeft.setText("Bottom left");
    new Button(bottom, SWT.PUSH).setText("Bottom right");

    topLeft.addListener(SWT.Resize, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            bottom.setWeights(top.getWeights());
        }
    });

    bottomLeft.addListener(SWT.Resize, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            top.setWeights(bottom.getWeights());
        }
    });

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

    shell.pack();
    shell.open();

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

调整大小之前:

enter image description here

调整大小后:

enter image description here

<强>更新

我注意到你实际调整大小的SashForm最终会失去同步。我通过将Listener更改为:

来“修复”此问题
topLeft.addListener(SWT.Resize, new Listener()
{
    @Override
    public void handleEvent(Event arg0)
    {
        bottom.setWeights(top.getWeights());
        // Resize the source SashForm as well to fix out of sync!
        top.setWeights(bottom.setWeights());
    }
});