SWT中添加滚动条

By | 2018年4月12日

1. 使用ScrolledComposite

  • 创建一个scrolledComposite,不设置layout。Style: SWT.H_SCROLL | SWT.V_SCROLL表示有滚动条。
  • ScrolledComposite –> setContent(Control)方法,将内容添加进来。
  • ScrolledComposite –> setAlwaysShowScrollBars(boolean),true表示一直显示滚动条,默认在需要时显示。
ScrolledComposite sc = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);

Composite content = new Composite(sc, SWT.BORDER);
content.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_RED));
GridLayoutFactory.swtDefaults().numColumns(5).applyTo(content);

for (int i = 0; i < 25; ++i) {
    Button btn = new Button(content, SWT.FLAT);
    btn.setText("Button " + i);
    GridDataFactory.swtDefaults().applyTo(btn);
}

sc.setContent(content);

此时,内容根本无法显示,因为内容没大小。

1.1. 设置内容的大小显示滚动条

当设置了内容大小,当ScrollComposite变小时,如果小于内容大小,就会显示滚动条。

/*
 * Method 1: Set the content size.
 */
content.setSize(content.computeSize(SWT.DEFAULT, SWT.DEFAULT));

image

1.2. 内容占满ScrolledComposite

设置让内容占满整个ScrolledComposite,给ScrolledComposite设置min size,当小于这个size时,显示滚动条。

这个有点像浏览器的滚动条感觉,效果较1.1.更好些。

/*
 * Method 2: Set the minimum size of ScrolledComposite.
 * Make content fill horizontally and vertically.
 */
sc.setMinSize(content.computeSize(SWT.DEFAULT, SWT.DEFAULT));
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);

image

1.3. 内容RowLayout wrap时仅显示垂直滚动条

如果内容时RowLayout,且wrap时,宽度不够时,显示在下一行。此时只需要显示垂直滚动条,水平滚动条是不需要的。

此时不能用1.2.的方法,设置Content占满ScrolledComposite,会导致Wrap失效。

只能用1.1.动态根据ScrolledComposite的宽度,计算content的高度,重新设置content的size。

ScrolledComposite sc = new ScrolledComposite(parent, SWT.V_SCROLL);

Composite content = new Composite(sc, SWT.BORDER);
content.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_RED));
RowLayoutFactory.swtDefaults().applyTo(content);

for (int i = 0; i < 35; ++i) {
    Button btn = new Button(content, SWT.FLAT);
    btn.setText("Button " + i);
}

sc.setContent(content);

sc.addListener(SWT.Resize, event -> {
    content.setSize(content.computeSize(sc.getSize().x, SWT.DEFAULT));
});

image

2. 使用ScrolledForm

首先声明,使用ScrolledForm添加滚动条比ScrolledComposite简单很多,而且还具有Form的特性。

ScrolledForm是对Form的封装,但是它可以具有滚动条。

  • ScrolledForm.getForm(),返回封装的Form。
  • ScrolledForm.getBody(),返回Form的body。
  • Form常用的方法,ScrolledForm都有定义,如果没有就直接getForm(),直接对其操作。
  • ScrolledForm.setAlwaysShowScrollBars(boolean),true则始终显示滚动条。

ScrolledForm显示滚动条的原理

根据内容的最小大小而定的,例如如果内容大小为(400, 300),宽度小于400则显示水平滚动条,高度小于300则显示垂直滚动条。

2.1. 计算部分内容宽度

默认ScrolledForm会计算所有内容的宽度,将其设置为显示滚动条的临界点。

如果内容里,有个控件自己有滚动条,需要将该控件的内容去掉,不包含在计算滚动条的临界点。否则此控件的滚动条就无效了,因为ScrolledForm将该控件里的内容也计算在自己滚动条的里面了。

例如,Table有很多列,ScrolledForm会显示滚动条来显示所有列,Table没机会显示滚动条。

image

我们只需要在给Table添加Column之前,调用下ScrolledForm的reflow(true)方法,便可将Table里的列,排除在计算滚动条之外。

scrolledForm.reflow(true);

// Add column after calling reflow.
for (int i = 0; i < 10; ++i) {
    TableColumn column = new TableColumn(table, SWT.NONE);
    column.setText("Column " + i);
    column.setWidth(80);
}

image

此时,table在显示滚动条来显示所有列,ScrolledForm仅在必要小时,显示滚动条。

image

2.2. reflow(boolean)分析

调用reflow(boolean)方法, 会将当前ScrolledForm中已经添加的控件,作为计算Scroll Bar显示的临界点。如果不加的话,就是ScrolledForm中的所有内容。

  • true,重新收集ScrolledForm中的元素,作为新的计算Scroll Bar显示的临界点。
  • false,不用更改之前收集的元素,仅仅是根据之前收集的元素,重新计算一下size,来调整滚动条。每次ScrolledForm大小改变时,都会直行reflow(false)来调整滚动条。

注:所谓显示Scroll Bar的临界点,即最小size,小于这个size,则显示滚动条。

3. 代码

展示2种方法,用ScrolledComposite显示滚动条:
https://github.com/tadckle/rcp/blob/master/rcp3/rcp3.study/src/rcp3/study/composite/ScrolledCompositeUsage1.java

RowLayout wrap中,仅显示垂直滚动条:
https://github.com/tadckle/rcp/blob/master/rcp3/rcp3.study/src/rcp3/study/composite/ScrolledCompositeUsage2.java

ScrolledForm的使用:
https://github.com/tadckle/rcp/blob/master/rcp3/rcp3.study/src/rcp3/study/composite/ScrolledFormUsage.java