京山游俠

          專注技術,拒絕扯淡
          posts - 50, comments - 868, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          使用Eclipse RCP進行桌面程序開發(一):快速起步
          使用Eclipse RCP進行桌面程序開發(二):菜單、工具欄和對話框
          使用Eclipse RCP進行桌面程序開發(三):視圖和透視圖
          使用Eclipse RCP進行桌面程序開發(四):在Windows中使用Active X控件

          看完這篇文章,可以實現如下界面:
          rcp32.JPG

          rcp33.JPG


          當我第一次看到RCP的時候,我就夢想著有一天能夠用它開發界面華麗的2D和3D程序,經歷過前面的探索,今天終于可以揭開2D繪圖的神秘面紗。在包資源管理器的插件依賴項中,我們一眼就可以看到org.eclipse.swt.graphics包,毫無疑問,和2D繪圖有關的類就在這個包中。還有一個org.eclipse.swt.opengl包也很引人注目,但是里面卻只有GLCanvas類和GLData類,怎么也找不到傳說中的GL類和GLU類,也許下一篇文章我會寫出關于3D的內容,但也許這個計劃會夭折。

          我剛開始發現org.eclipse.swt.graphics包的時候,要使用包里面的類卻不是那么容易。比如,從名稱上可以看出Image類是處理圖像的,但是它的構造函數無一例外都需要一個Device參數,于是,我迷惑了,Device,我該如何取得?再比如,GC類里面含有各種繪圖的方法,但是GC的構造函數需要Drawable參數,那Drawable我又該如何獲得呢?

          于是,我在網上搜索關于SWT 2D方面的內容,終于,讓我看到了別人這樣構造Image和GC:
          Image img = new Image(display,"pic.gif");
          GC gc = new GC(Image);
          你能看出什么?為什么display是Device的子類?為什么Image是Drawabe的子類?最簡單的辦法,使用Eclipse的類層次結構視圖查看:

          rcp31.JPG

          高,實在是高,在這里我不得不佩服SWT的設計者,在一開始,他們就把所有的控件都設計為可繪制的,而且使用Device來抽象繪圖的設備。從圖中可以看出,所有的控件都實現Drawable接口,Image也實現Drawable接口,而Device的子類Display和Printer剛好分別代表了屏幕和打印機。所有的謎團都在這里解決了,我們可以使用任何控件作為GC構造函數的參數來構造GC,然后繪圖,而所有需要Device參數的地方,我們可以根據我們需要輸出的設備是顯示器還是打印機而分別選擇Display或Printer。

          在org.eclipse.swt.widgets包中,有一個Canvas類,不難看出,如果我們要繪圖,這個控件是最佳選擇了。在下面的代碼中,我們可以通過選擇不同的菜單,分別繪制橢圓,矩形,填充漸變色的矩形和一個圖像,運行效果就是文章開頭的圖片。

          視圖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?自動生成方法存根
          17 ????????canvas? = ? new ?Canvas(parent,SWT.NONE);
          18 ????????????}

          19
          20 ????@Override
          21 ???? public ? void ?setFocus()? {
          22 ???????? // ?TODO?自動生成方法存根
          23
          24 ????}

          25
          26 }

          27

          菜單項繪制橢圓DrawOvalAction.java的關鍵部分:

          ?1 public ? void ?run(IAction?action)? {
          ?2 ???????? // ?TODO?自動生成方法存根
          ?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( " 畫圖板 " )) {
          ?8 ?????????????????????GC?gc? = ? new ?GC(((CanvasView)vw).canvas);
          ?9 ?????????????????????gc.drawOval( 80 ,? 50 ,? 100 ,? 100 );
          10 ?????????????????????gc.dispose();
          11 ?????????????}

          12 ????????}

          13 ????}

          菜單項繪制矩形DrawRectAction.java的關鍵部分:

          ?1 public ? void ?run(IAction?action)? {
          ?2 ???????? // ?TODO?自動生成方法存根
          ?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( " 畫圖板 " )) {
          ?8 ?????????????????????GC?gc? = ? new ?GC(((CanvasView)vw).canvas);
          ?9 ?????????????????????gc.drawRectangle( 280 ,? 50 ,? 100 ,? 100 );
          10 ?????????????????????gc.dispose();
          11 ?????????????}

          12 ????????}

          13
          14 ????}

          菜單項繪制漸變矩形DrawGradientAction.java的關鍵部分:

          ?1 public ? void ?run(IAction?action)? {
          ?2 ???????? // ?TODO?自動生成方法存根
          ?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( " 畫圖板 " )) {
          ?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 ????}

          菜單項繪制圖像DrawImageAction.java的關鍵部分:

          ?1 public ? void ?run(IAction?action)? {
          ?2 ???????? // ?TODO?自動生成方法存根
          ?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( " 畫圖板 " )) {
          ?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 ????}


          上面的方法雖然實現了繪圖,但是還有一個問題,就是一旦我們的窗口最小化或者被別的窗口遮擋后,圖形就會消失。原因其實很簡單,一旦我們的窗口最小化或者被別的窗口遮擋后,控件就需要重畫,所以我們畫的圖形就不見了,如果要讓控件重畫的時候也能繪制圖形,就應該使用canvas.addPaintListener()為控件添加Paint事件的監聽器。示例代碼見下。

          ?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?自動生成方法存根
          17 ????????canvas? = ? new ?Canvas(parent,SWT.NONE);
          18 ????????canvas.addPaintListener( new ?PaintListener()? {
          19 ???????????? public ? void ?paintControl(PaintEvent?e)? {
          20 ???????????????? // 畫橢圓
          21 ????????????????e.gc.drawOval( 80 ,? 50 ,? 100 ,? 100 );
          22 ???????????????? // 畫矩形
          23 ????????????????e.gc.drawRectangle( 280 ,? 50 ,? 100 ,? 100 );
          24 ???????????????? // 畫漸變矩形
          25 ????????????????e.gc.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_BLUE));
          26 ?????????????????e.gc.fillGradientRectangle( 80 , 200 , 100 , 100 , false );
          27 ????????????????? // 畫圖形
          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?自動生成方法存根
          38
          39 ????}

          40
          41 }

          42

          GC類的繪圖方法很多,而且可以設置不同的前景色,背景色,畫筆,畫刷等等,還可以裁減圖形,這些就靠我們慢慢探索了。


          評論

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖  回復  更多評論   

          2006-12-01 22:37 by lovejava[匿名]
          謝謝,太有幫助了。

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖  回復  更多評論   

          2006-12-04 16:01 by 心內求法
          寫得相當清楚!

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖[未登錄]  回復  更多評論   

          2007-06-03 05:08 by james
          好,不頂不行

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖[未登錄]  回復  更多評論   

          2007-08-29 16:56 by 森林
          畫一條線,如何刪除啊?謝謝!

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖  回復  更多評論   

          2007-08-30 15:48 by 海邊沫沫
          用XOR模式再畫一條同樣的線

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖  回復  更多評論   

          2007-11-09 20:19 by metaphy
          非常好。正看這些東西看得迷糊,解疑了很多

          # re: 使用Eclipse RCP進行桌面程序開發(五):2D繪圖  回復  更多評論   

          2012-03-07 16:03 by kane
          但是加了paintListener之后程序一運行就把四個圖像都畫出來了,這顯然是不合理的啊 怎么解決?
          主站蜘蛛池模板: 萨迦县| 平昌县| 徐汇区| 邹城市| 西盟| 青冈县| 菏泽市| 盐源县| 满洲里市| 珠海市| 紫阳县| 赤壁市| 礼泉县| 饶平县| 泰兴市| 获嘉县| 营山县| 丘北县| 昌吉市| 富民县| 阳山县| 会东县| 泸州市| 田林县| 新昌县| 绥棱县| 宣汉县| 淅川县| 伊吾县| 政和县| 合水县| 龙游县| 年辖:市辖区| 清水河县| 安化县| 晋宁县| 潞西市| 泽普县| 佛学| 沁源县| 上高县|