使用Eclipse RCP進(jìn)行桌面程序開(kāi)發(fā)(一):快速起步
使用Eclipse RCP進(jìn)行桌面程序開(kāi)發(fā)(二):菜單、工具欄和對(duì)話框
使用Eclipse RCP進(jìn)行桌面程序開(kāi)發(fā)(三):視圖和透視圖
使用Eclipse RCP進(jìn)行桌面程序開(kāi)發(fā)(四):在Windows中使用Active X控件
看完這篇文章,可以實(shí)現(xiàn)如下界面:


當(dāng)我第一次看到RCP的時(shí)候,我就夢(mèng)想著有一天能夠用它開(kāi)發(fā)界面華麗的2D和3D程序,經(jīng)歷過(guò)前面的探索,今天終于可以揭開(kāi)2D繪圖的神秘面紗。在包資源管理器的插件依賴項(xiàng)中,我們一眼就可以看到org.eclipse.swt.graphics包,毫無(wú)疑問(wèn),和2D繪圖有關(guān)的類就在這個(gè)包中。還有一個(gè)org.eclipse.swt.opengl包也很引人注目,但是里面卻只有GLCanvas類和GLData類,怎么也找不到傳說(shuō)中的GL類和GLU類,也許下一篇文章我會(huì)寫(xiě)出關(guān)于3D的內(nèi)容,但也許這個(gè)計(jì)劃會(huì)夭折。
我剛開(kāi)始發(fā)現(xiàn)org.eclipse.swt.graphics包的時(shí)候,要使用包里面的類卻不是那么容易。比如,從名稱上可以看出Image類是處理圖像的,但是它的構(gòu)造函數(shù)無(wú)一例外都需要一個(gè)Device參數(shù),于是,我迷惑了,Device,我該如何取得?再比如,GC類里面含有各種繪圖的方法,但是GC的構(gòu)造函數(shù)需要Drawable參數(shù),那Drawable我又該如何獲得呢?
于是,我在網(wǎng)上搜索關(guān)于SWT 2D方面的內(nèi)容,終于,讓我看到了別人這樣構(gòu)造Image和GC:
Image img = new Image(display,"pic.gif");
GC gc = new GC(Image);
你能看出什么?為什么display是Device的子類?為什么Image是Drawabe的子類?最簡(jiǎn)單的辦法,使用Eclipse的類層次結(jié)構(gòu)視圖查看:
高,實(shí)在是高,在這里我不得不佩服SWT的設(shè)計(jì)者,在一開(kāi)始,他們就把所有的控件都設(shè)計(jì)為可繪制的,而且使用Device來(lái)抽象繪圖的設(shè)備。從圖中可以看出,所有的控件都實(shí)現(xiàn)Drawable接口,Image也實(shí)現(xiàn)Drawable接口,而Device的子類Display和Printer剛好分別代表了屏幕和打印機(jī)。所有的謎團(tuán)都在這里解決了,我們可以使用任何控件作為GC構(gòu)造函數(shù)的參數(shù)來(lái)構(gòu)造GC,然后繪圖,而所有需要Device參數(shù)的地方,我們可以根據(jù)我們需要輸出的設(shè)備是顯示器還是打印機(jī)而分別選擇Display或Printer。
在org.eclipse.swt.widgets包中,有一個(gè)Canvas類,不難看出,如果我們要繪圖,這個(gè)控件是最佳選擇了。在下面的代碼中,我們可以通過(guò)選擇不同的菜單,分別繪制橢圓,矩形,填充漸變色的矩形和一個(gè)圖像,運(yùn)行效果就是文章開(kāi)頭的圖片。
視圖CanvasView.java
?1
package
?cn.blogjava.youxia.views;
?2
?3
import
?org.eclipse.swt.widgets.Composite;
?4
import
?org.eclipse.ui.part.ViewPart;
?5
import
?org.eclipse.swt.widgets.Canvas;
?6
import
?org.eclipse.swt.SWT;
?7
import
?org.eclipse.swt.events.
*
;
?8
import
?org.eclipse.swt.graphics.Image;
?9
import
?org.eclipse.ui.PlatformUI;
10
11
public
?
class
?CanvasView?
extends
?ViewPart?
{
12
13
????
public
?Canvas?canvas;
14
????@Override
15
????
public
?
void
?createPartControl(Composite?parent)?
{
16
????????
//
?TODO?自動(dòng)生成方法存根
17
????????canvas?
=
?
new
?Canvas(parent,SWT.NONE);
18
????????????}
19
20
????@Override
21
????
public
?
void
?setFocus()?
{
22
????????
//
?TODO?自動(dòng)生成方法存根
23
24
????}
25
26
}
27
菜單項(xiàng)繪制橢圓DrawOvalAction.java的關(guān)鍵部分:
?1
public
?
void
?run(IAction?action)?
{
?2
????????
//
?TODO?自動(dòng)生成方法存根
?3
????????IViewReference[]?vfs?
=
?window.getActivePage().getViewReferences();
?4
????????IViewPart?vw;
?5
????????
for
(
int
?i
=
0
;?i
<
vfs.length;?i
++
)
{
?6
?????????????vw?
=
?vfs[i].getView(
false
);
?7
?????????????
if
(vw.getTitle().equals(
"
畫(huà)圖板
"
))
{
?8
?????????????????????GC?gc?
=
?
new
?GC(((CanvasView)vw).canvas);
?9
?????????????????????gc.drawOval(
80
,?
50
,?
100
,?
100
);
10
?????????????????????gc.dispose();
11
?????????????}
12
????????}
13
????}
菜單項(xiàng)繪制矩形DrawRectAction.java的關(guān)鍵部分:
?1
public
?
void
?run(IAction?action)?
{
?2
????????
//
?TODO?自動(dòng)生成方法存根
?3
????????IViewReference[]?vfs?
=
?window.getActivePage().getViewReferences();
?4
????????IViewPart?vw;
?5
????????
for
(
int
?i
=
0
;?i
<
vfs.length;?i
++
)
{
?6
?????????????vw?
=
?vfs[i].getView(
false
);
?7
?????????????
if
(vw.getTitle().equals(
"
畫(huà)圖板
"
))
{
?8
?????????????????????GC?gc?
=
?
new
?GC(((CanvasView)vw).canvas);
?9
?????????????????????gc.drawRectangle(
280
,?
50
,?
100
,?
100
);
10
?????????????????????gc.dispose();
11
?????????????}
12
????????}
13
14
????}
菜單項(xiàng)繪制漸變矩形DrawGradientAction.java的關(guān)鍵部分:
?1
public
?
void
?run(IAction?action)?
{
?2
????????
//
?TODO?自動(dòng)生成方法存根
?3
????????IViewReference[]?vfs?
=
?window.getActivePage().getViewReferences();
?4
????????IViewPart?vw;
?5
????????
for
(
int
?i
=
0
;?i
<
vfs.length;?i
++
)
{
?6
?????????????vw?
=
?vfs[i].getView(
false
);
?7
?????????????
if
(vw.getTitle().equals(
"
畫(huà)圖板
"
))
{
?8
?????????????????????GC?gc?
=
?
new
?GC(((CanvasView)vw).canvas);
?9
?????????????????????gc.setBackground(window.getShell().getDisplay().getSystemColor(SWT.COLOR_BLUE));
10
?????????????????????gc.fillGradientRectangle(
80
,
200
,
100
,
100
,
false
);?
11
12
?????????????????????gc.dispose();
13
?????????????}
14
????????}
15
16
????}
菜單項(xiàng)繪制圖像DrawImageAction.java的關(guān)鍵部分:
?1
public
?
void
?run(IAction?action)?
{
?2
????????
//
?TODO?自動(dòng)生成方法存根
?3
????????IViewReference[]?vfs?
=
?window.getActivePage().getViewReferences();
?4
????????IViewPart?vw;
?5
????????
for
(
int
?i
=
0
;?i
<
vfs.length;?i
++
)
{
?6
?????????????vw?
=
?vfs[i].getView(
false
);
?7
?????????????
if
(vw.getTitle().equals(
"
畫(huà)圖板
"
))
{
?8
?????????????????????GC?gc?
=
?
new
?GC(((CanvasView)vw).canvas);
?9
?????????????????????Image?img?
=
?
new
?Image(window.getShell().getDisplay(),
"
E:\\img.gif
"
);
10
?????????????????????gc.drawImage(img,?
280
,?
200
);
11
?????????????????????gc.dispose();
12
?????????????}
13
????????}
14
15
????}
上面的方法雖然實(shí)現(xiàn)了繪圖,但是還有一個(gè)問(wèn)題,就是一旦我們的窗口最小化或者被別的窗口遮擋后,圖形就會(huì)消失。原因其實(shí)很簡(jiǎn)單,一旦我們的窗口最小化或者被別的窗口遮擋后,控件就需要重畫(huà),所以我們畫(huà)的圖形就不見(jiàn)了,如果要讓控件重畫(huà)的時(shí)候也能繪制圖形,就應(yīng)該使用canvas.addPaintListener()為控件添加Paint事件的監(jiān)聽(tīng)器。示例代碼見(jiàn)下。
?1
package
?cn.blogjava.youxia.views;
?2
?3
import
?org.eclipse.swt.widgets.Composite;
?4
import
?org.eclipse.ui.part.ViewPart;
?5
import
?org.eclipse.swt.widgets.Canvas;
?6
import
?org.eclipse.swt.SWT;
?7
import
?org.eclipse.swt.events.
*
;
?8
import
?org.eclipse.swt.graphics.Image;
?9
import
?org.eclipse.ui.PlatformUI;
10
11
public
?
class
?CanvasView?
extends
?ViewPart?
{
12
13
????
public
?Canvas?canvas;
14
????@Override
15
????
public
?
void
?createPartControl(Composite?parent)?
{
16
????????
//
?TODO?自動(dòng)生成方法存根
17
????????canvas?
=
?
new
?Canvas(parent,SWT.NONE);
18
????????canvas.addPaintListener(
new
?PaintListener()?
{
19
????????????
public
?
void
?paintControl(PaintEvent?e)?
{
20
????????????????
//
畫(huà)橢圓
21
????????????????e.gc.drawOval(
80
,?
50
,?
100
,?
100
);
22
????????????????
//
畫(huà)矩形
23
????????????????e.gc.drawRectangle(
280
,?
50
,?
100
,?
100
);
24
????????????????
//
畫(huà)漸變矩形
25
????????????????e.gc.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_BLUE));
26
?????????????????e.gc.fillGradientRectangle(
80
,
200
,
100
,
100
,
false
);
27
?????????????????
//
畫(huà)圖形
28
?????????????????Image?img?
=
?
new
?Image(PlatformUI.getWorkbench().getDisplay(),
"
E:\\img.gif
"
);
29
?????????????????e.gc.drawImage(img,?
280
,?
200
);
30
31
????????}
32
????????}
);
33
????}
34
35
????@Override
36
????
public
?
void
?setFocus()?
{
37
????????
//
?TODO?自動(dòng)生成方法存根
38
39
????}
40
41
}
42
GC類的繪圖方法很多,而且可以設(shè)置不同的前景色,背景色,畫(huà)筆,畫(huà)刷等等,還可以裁減圖形,這些就靠我們慢慢探索了。