注意!这个答案基于 Eclipse RAP,它的行为可能与常规 SWT 不同。
几天前,我正在为完全相同的问题苦苦挣扎。我在同一页上有两个ScrolledComposite
s,我需要左边的一个不会占用比需要更多的空间(即使空间可用)。
在尝试不同的解决方案时,我注意到 a 的行为ScrolledComposite
取决于其LayoutData
如下:
- 如果
layoutData
设置为new GridData(SWT.LEFT, SWT.TOP, false, true)
,则ScrolledComposite
无论父Composite
大小更改如何,都将保持其预期大小。
- 如果
layoutData
设置为new GridData(SWT.LEFT, SWT.TOP, true, true)
,则将ScrolledComposite
根据父级的大小变化缩小/扩展Composite
。这还包括扩展到所需的更大宽度(意味着列保持相等)。
基于这种行为,我能够通过向父级添加一个调整大小的侦听器来解决问题,该侦听器根据父级Composite
更改layoutData
左侧ScrolledComposite
的Composite size
。
下面的例子说明了这种方法:
public class LayoutingScrolledComposites extends AbstractEntryPoint {
public void createContents( Composite parent ) {
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
parent.setLayout(new GridLayout(2, false));
ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
Composite c1 = new Composite(sc1, SWT.BORDER);
sc1.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
c1.setLayout(new GridLayout(3, false));
sc1.setContent(c1);
Label l1 = new Label (c1, SWT.BORDER);
l1.setText("Some text");
l1 = new Label (c1, SWT.BORDER);
l1.setText("Some text");
l1 = new Label (c1, SWT.BORDER);
l1.setText("Some text");
c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
ScrolledComposite sc2 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
sc2.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
Composite c2 = new Composite(sc1, SWT.BORDER);
c2.setLayout(new GridLayout(3, false));
sc2.setContent(c2);
Label l2 = new Label (c2, SWT.BORDER);
l2.setText("Some text");
l2 = new Label (c2, SWT.BORDER);
l2.setText("Some text");
l2 = new Label (c2, SWT.BORDER);
l2.setText("Some text");
c2.setSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
parent.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event e) {
int sc1_x = sc1.getContent().getSize().x;
int sc2_x = sc2.getContent().getSize().x;
//Enable/Disable grabExcessHorizontalSpace based on whether both sc's would fit in the shell
if (LayoutingScrolledComposites.this.getShell().getSize().x > sc1_x+sc2_x) {
if (((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) {
//sc1 does not change width in this mode
((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=false;
}
} else {
if (!((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) {
//sc1 changes width in this mode
((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=true;
}
}
parent.layout(); //Needed so that the layout change would take effect during the same event
}
});
}
}
然而,这种方法在我看来确实有点过于“hackish”的解决方案。因此,我希望看到更好的方法。