技术开发 频道

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

  Canvas 是最基本的控件类型之一,可以用它来创建定制控件或绘图。图 2 和 图 3 展示了使用 Canvas 来绘制由重叠的矩形和椭圆形组成的图片的一个例子。在这幅绘画中,一些图片被填充,而其他一些则没有被填充。颜色、大小和位置的分配是随意的。

  清单 2 展示了用于创建 Canvas 的代码。要实际地在 Canvas 上进行绘图,必须向该 Canvas 添加一个 PaintListener。每当 Canvas 需要重新绘制其客户机区域的任何部分时,都需要调用其 paintControl 方法。有两种绘制风格:

  直接绘制 —— 很简单,但内容在整个重绘期间是不稳定的。

  在进行绘制之前构建一个模型,然后再根据此模型进行重新绘制 —— 比较复杂,但很稳定。这通常是首选方法。

  清单 2. 用于创建 Canvas 的方法

1 protected Canvas createCanvas(Composite parent, int style,
2                               PaintListener pl) {
3     Canvas c = new Canvas(parent, style);
4     if (pl != null) {
5         c.addPaintListener(pl);
6     }
7     return c;
8 }
9 protected Canvas createCanvas(Composite parent, PaintListener pl) {
10     return createCanvas(parent, SWT.NONE, pl);
11 }
12

 

  作为绘制风格 2 的一个例子,可以考虑一下清单 3 中定义的简单模型:

  清单 3. PaintItems 的层次结构

1 abstract protected class PaintItem {
2     public Color color;
3     public void paint(GC gc) {
4         gc.setForeground(color);
5         gc.setBackground(color);
6     }
7 }
8 abstract protected class BaseRectItem extends PaintItem {
9     public boolean fill;
10     public Rectangle extent;
11 }
12 protected class ElipseItem extends BaseRectItem {
13     public void paint(GC gc) {
14         super.paint(gc);
15         if (fill) {
16             gc.fillOval(extent.x, extent.y,
17                         extent.width, extent.height);
18         }
19         else {
20             gc.drawOval(extent.x, extent.y,
21                         extent.width, extent.height);
22         }
23     }
24 }
25 protected class RectangleItem extends BaseRectItem {
26     public void paint(GC gc) {
27         super.paint(gc);
28         if (fill) {
29             gc.fillRectangle(extent.x, extent.y,
30                              extent.width, extent.height);
31         }
32         else {
33             gc.drawRectangle(extent.x, extent.y,
34                              extent.width, extent.height);
35         }
36     }
37 }
38

 

  这些绘制项都由 清单 4 中显示的 PaintListener 绘制。paintControl 方法是随在其上进行绘制的图形上下文(org.eclipse.swt.graphics 包中的 GC)一起提供的。您可以使用 GC 绘制文本和许多形状。此代码将重用通过 Display 类可用的标准系统颜色。由 Canvas 决定是否使用某种背景色填充其区域。gcObjects 集合包含所有需要绘制的 PaintItem 实例。数组 colorIds 是一个到选定的系统颜色的映射。

  清单 4. 用于创建 TabFolder 和 TabItem 的方法

1 new PaintListener() {
2     public void paintControl(PaintEvent e) {
3         GC gc = e.gc;
4         gc.setBackground(canvas.getDisplay().
5              getSystemColor(colorIds[0]));
6         Point cext = canvas.getSize();
7         gc.fillRectangle(0, 0, cext.x, cext.y);
8         for (Iterator i = gcObjects.iterator();
9              i.hasNext();) {
10              PaintItem pi = (PaintItem)i.next();
11              pi.paint(gc);
12         }
13    }
14 }…
15 protected static int[] colorIds = {
16     SWT.COLOR_WHITE, SWT.COLOR_BLUE, SWT.COLOR_CYAN,
17     SWT.COLOR_GRAY, SWT.COLOR_GREEN, SWT.COLOR_MAGENTA,
18     SWT.COLOR_RED, SWT.COLOR_YELLOW, SWT.COLOR_BLACK
19 };
20

 

  清单 5 中显示了一些代码,这些代码先清除绘画,然后创建由一组矩形和椭圆组成的绘画。通过 GUI 上的按钮可以激活此代码。

  清单 5. 用于处理绘制事件的方法

1 public void doClear() {
2     gcObjects.clear();
3     canvas.redraw();
4 }
5 public void doDraw() {
6     gcObjects.clear();
7     Display display = drawButton.getDisplay();
8     // create a bunch of objects
9     for (int i = 0; i < 50; i++) {
10         if (i % 2 == 0) {
11             RectangleItem ri = new RectangleItem();
12             ri.extent = new Rectangle(nextInt(500), nextInt(250),
13                                       nextInt(500), nextInt(250));
14             ri.color = display.
15                 getSystemColor(colorIds[nextInt(colorIds.length)]);
16             ri.fill = i % 3 == 0;
17             gcObjects.add(ri);
18         }
19         else {
20             ElipseItem ei = new ElipseItem();
21             ei.extent = new Rectangle(nextInt(500), nextInt(250),
22                                       nextInt(500), nextInt(250));
23             ei.color = display.
24                 getSystemColor(colorIds[nextInt(colorIds.length)]);
25             ei.fill = i % 5 == 0;
26             gcObjects.add(ei);
27         }
28     }
29     canvas.redraw();
30 }
31
0
相关文章