技术开发 频道

了解TabFolder、Canvas和其他多种控件

  SWT 支持几种输入离散值的方法。Scale 允许在(通常很小的)整数范围内挑选一个值。Slider 允许使用类似滚动条的方法在(可能很大的)整数范围内挑选一个值。Spinner 允许挑选(通过向前/撤退按钮)或键入一个(可能为小数的)数字。注意,Spinner 是 Eclipse V3.1 中的一个新特性。ProgressBar 类似于一个只输出的 Slider,因为可以用它来展示增量活动(进度)。

  通常,这些控件允许您提供最小值、最大值和初始值。除了 ProgressBars 之外,这些控件还支持增量值和页面增量值,Sliders 还支持 thumb 宽度。图 4 展示了一个 GUI,它在控件组内包含一个 Slider、一个 Spinner 和一个 Scale,在这些控件的下方是一个 ProgressBar。紧贴在进度条上的是一个(居中的)Label,它展示了进度条的值。

  图 4. 控件的例子

  必须将所有这些控件定义为以下两种相互排斥的样式之一:

  HORIZONTAL —— 水平地布置控件。

  VERTICAL —— 垂直地布置控件。

  Spinners 支持其他一些可选样式:

  WRAP —— 从高值向低值换行排列。

  READ_ONLY —— 不允许键入输入值。

  ProgressBars 支持其他一些可选样式:

  SMOOTH —— 更新不是在截然不同的步骤中进行的。

  INDETERMINATE —— 没有预先确定步骤数的范围;进度条只是在时间上重复。

  要创建这些控件,可以使用清单 6-9 中所示的代码。将通过 registerCallback 方法,使用 Java 反射将 SelectionListeners 添加到这些控件中。每当控件的值发生更改时,都会调用此侦听器。

  清单 6. 用于创建 Slider 的方法

1 protected Slider createSlider(Composite parent, int style,
2                               int min, int current, int max,
3                               int inc, int pageinc, int thumb,
4                               String callback) {
5     Slider s = new Slider(parent, style);
6     if (min >= 0) {
7         s.setMinimum(min);
8     }
9     if (max >= 0) {
10         s.setMaximum(max);
11     }
12     if (current >= 0) {
13         s.setSelection(current);
14     }
15     if (inc >= 1) {
16         s.setIncrement(inc);
17     }
18     if (pageinc >= 1) {
19         s.setPageIncrement(pageinc);
20     }
21     if (thumb >= 1) {
22         s.setThumb(thumb);
23     }
24     if (callback != null) {
25         registerCallback(s, this, callback);
26     }
27     return s;
28 }
29 protected Slider createVSlider(Composite parent,
30                                int min, int current, int max,
31                                int inc, int pageinc, int thumb,
32                                String callback) {
33     return createSlider(parent, SWT.VERTICAL, min, current, max,
34                         inc, pageinc, thumb, callback);
35 }
36 protected Slider createHSlider(Composite parent,
37                                int min, int current, int max,
38                                int inc, int pageinc, int thumb,
39                                String callback) {
40     return createSlider(parent, SWT.HORIZONTAL, min, current, max,
41                         inc, pageinc, thumb, callback);
42 }
43

 

  清单 7. 用于创建 Spinner 的方法

1 protected Spinner createSpinner(Composite parent, int style,
2                                 int min, int current, int max,
3                                 int inc, int pageinc, String callback) {
4     Spinner s = new Spinner(parent, style);
5     if (min >= 0) {
6         s.setMinimum(min);
7     }
8     if (max >= 0) {
9         s.setMaximum(max);
10     }
11     if (current >= 0) {
12         s.setSelection(current);
13     }
14     if (inc >= 1) {
15         s.setIncrement(inc);
16     }
17     if (pageinc >= 1) {
18         s.setPageIncrement(pageinc);
19     }
20     if (callback != null) {
21         registerCallback(s, this, callback);
22     }
23     return s;
24 }
25

 

  清单 8. 用于创建 Scale 的方法

1 protected Scale createScale(Composite parent, int style,
2                             int min, int current, int max,
3                             int inc, int pageinc) {
4     Scale s = new Scale(parent, style);
5     if (min >= 0) {
6         s.setMinimum(min);
7     }
8     if (max >= 0) {
9         s.setMaximum(max);
10     }
11     if (current >= 0) {
12         s.setSelection(current);
13     }
14     if (inc >= 1) {
15         s.setIncrement(inc);
16     }
17     if (pageinc >= 1) {
18         s.setPageIncrement(pageinc);
19     }
20     return s;
21 }
22 protected Scale createVScale(Composite parent,
23                              int min, int current, int max,
24                              int inc, int pageinc) {
25     return createScale(parent, SWT.VERTICAL, min, current, max,
26                        inc, pageinc);
27 }
28 protected Scale createHScale(Composite parent,
29                              int min, int current, int max,
30                              int inc, int pageinc) {
31     return createScale(parent, SWT.HORIZONTAL, min, current, max,
32                        inc, pageinc);
33 }
34

 

  清单 9. 用于创建 ProgressBar 的方法

1 protected ProgressBar createProgressBar(Composite parent, int style,
2                                         int min, int current, int max) {
3     ProgressBar pb = new ProgressBar(parent, style);
4     if (min >= 0) {
5         pb.setMinimum(min);
6     }
7     if (max >= 0) {
8         pb.setMaximum(max);
9     }
10     if (current >= 0) {
11         pb.setSelection(current);
12     }
13     return pb;
14 }
15 protected ProgressBar createVProgressBar(Composite parent,
16                                          int min, int current, int max) {
17     return createProgressBar(parent, SWT.VERTICAL, min, current, max);
18 }
19 protected ProgressBar createHProgressBar(Composite parent,
20                                          int min, int current, int max) {
21     return createProgressBar(parent, SWT.HORIZONTAL, min, current, max);
22 }
23

 

  您可以查询或设置这些控件的当前值。考虑一下清单 10 中定义的线程,该线程将更新 图 4 中的标签、进度条和滑块。此线程在选中“Automatic Update”按钮(即代码中的 modeButton)时启动。

  清单 10. 用于更新控件的线程

1 protected class BarUpdater extends Thread {
2     protected int delay;
3     protected Display display;
4     public BarUpdater(Display display) {
5         this.display = display;
6     }
7     public void run() {
8         try {
9             while (true) {
10                 try {
11                     if (!display.isDisposed()) {
12                         display.syncExec(new Runnable() {
13                                 public void run() {
14                                     if (!modeButton.isDisposed() &&
15                                         !scale.isDisposed()) {
16                                         delay = modeButton.getSelection()
17                                                ? scale.getSelection() : -1;
18                                     }
19                                 }
20                         });
21                         if (delay >= 0) {
22                             Thread.sleep(delay);
23                             if (!display.isDisposed()) {
24                                 display.syncExec(new Runnable() {
25                                     public void run() {
26                                         if (!bar.isDisposed()) {
27                                             int v = bar.getSelection() + 1;
28                                             if (v > bar.getMaximum()) {
29                                                 v = bar.getMinimum();
30                                             }
31                                                     bar.setSelection(v);
32                                             if (!slider.isDisposed()) {
33                                                 slider.setSelection(v);
34                                             }
35                                             if (!valueLabel.isDisposed()) {
36                                                 valueLabel.setText(
37                                                        Integer.toString(v));
38                                             }
39                                         }
40                                     }
41                                 });
42                             }
43                         }
44                     }
45                     Thread.sleep(100);
46                 }
47                 catch (InterruptedException ie) {
48                 }
49             }
50         }
51         catch (Exception e) {
52              e.printStackTrace();
53         }
54     }
55 }
56

 

  注意,此代码小心地进行检查,看各种控件在使用之前是否已经就绪。在异步 GUI 操作中,这很关键。还会注意到,所有 GUI 访问都是在一个 syncExec(或其同类 asyncExec)方法中进行的。每当在与创建 GUI 所在的线程不同的线程上访问 GUI 时,都需要这样做。

0
相关文章