Posted on 2006-12-01 15:33 
京山游侠 阅读(13836) 
评论(7)  编辑  收藏  所属分类: 
拥抱Eclipse RCP 
			 
			
		 
		
		
				
						使用Eclipse RCP进行桌面程序开发(一):快速起步
				
				
				
						使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框
				
				
				
						使用Eclipse RCP进行桌面程序开发(三):视图和透视图
				
				
				
						使用Eclipse RCP进行桌面程序开发(四):在Windows中使用Active X控件
				
				
		
		看完这篇文章,可以实现如下界面:


当我第一次看到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的类层次结构视图查看:
		
				 
		
		高,实在是高,在这里我不得不佩服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;
				package
				 cn.blogjava.youxia.views;
				 2
				
						 
						
				
				 3
				
						 import
				 org.eclipse.swt.widgets.Composite;
				
				import
				 org.eclipse.swt.widgets.Composite;
				 4
				
						 import
				 org.eclipse.ui.part.ViewPart;
				
				import
				 org.eclipse.ui.part.ViewPart;
				 5
				
						 import
				 org.eclipse.swt.widgets.Canvas;
				
				import
				 org.eclipse.swt.widgets.Canvas;
				 6
				
						 import
				 org.eclipse.swt.SWT;
				
				import
				 org.eclipse.swt.SWT;
				 7
				
						 import
				 org.eclipse.swt.events.
				*
				;
				
				import
				 org.eclipse.swt.events.
				*
				;
				 8
				
						 import
				 org.eclipse.swt.graphics.Image;
				
				import
				 org.eclipse.swt.graphics.Image;
				 9
				
						 import
				 org.eclipse.ui.PlatformUI;
				
				import
				 org.eclipse.ui.PlatformUI;
				10
				
						 
						
				
				11
				
						 
						 public
				 
				class
				 CanvasView 
				extends
				 ViewPart
				
				public
				 
				class
				 CanvasView 
				extends
				 ViewPart 
				
						 {
				
				
						{
						12
						
								 
								
						
						13
						
								 public
						 Canvas canvas;
    
						public
						 Canvas canvas;
						14
						
								 @Override
    @Override
						15
						
								 
								 public
						 
						void
						 createPartControl(Composite parent)
    
						public
						 
						void
						 createPartControl(Composite parent) 
						
								 {
						
						
								{
								16
								
										 //
								 TODO 自动生成方法存根
        
								//
								 TODO 自动生成方法存根
								
										
								
								17
								
										 canvas 
								=
								 
								new
								 Canvas(parent,SWT.NONE);
								
								        canvas 
								=
								 
								new
								 Canvas(parent,SWT.NONE);
								18
								
										 }
            }
						
						
								
						
						19
						
								 
								
						
						20
						
								 @Override
    @Override
						21
						
								 
								 public
						 
						void
						 setFocus()
    
						public
						 
						void
						 setFocus() 
						
								 {
						
						
								{
								22
								
										 //
								 TODO 自动生成方法存根
        
								//
								 TODO 自动生成方法存根
								
										
								
								23
								
										 
								
								
										
								
								24
								
										 }
    }
						
						
								
						
						25
						
								 
								
						
						26
						
								 }
}
				
				
						
				
				27
				
						 
				
		 
		菜单项绘制椭圆DrawOvalAction.java的关键部分:
		
				 1
				 
				 public
				 
				void
				 run(IAction action)
				public
				 
				void
				 run(IAction action) 
				
						 {
				
				
						{
						 2
						
								 //
						 TODO 自动生成方法存根
        
						//
						 TODO 自动生成方法存根
						
								
						
						 3
						
								 IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						
						        IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						 4
						
								 IViewPart vw;
        IViewPart vw;
						 5
						
								 
								 for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
        
						for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
						
								 {
						
						
								{
								 6
								
										 vw 
								=
								 vfs[i].getView(
								false
								);
             vw 
								=
								 vfs[i].getView(
								false
								);
								 7
								
										 
										 if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
             
								if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
								
										 {
								
								
										{
										 8
										
												 GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
                     GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
										 9
										
												 gc.drawOval(
										80
										, 
										50
										, 
										100
										, 
										100
										);
                     gc.drawOval(
										80
										, 
										50
										, 
										100
										, 
										100
										);
										10
										
												 gc.dispose();
                     gc.dispose();
										11
										
												 }
             }
								
								
										
								
								12
								
										 }
        }
						
						
								
						
						13
						
								 }
    }
				
		 
		菜单项绘制矩形DrawRectAction.java的关键部分:
		
				 1
				 
				 public
				 
				void
				 run(IAction action)
				public
				 
				void
				 run(IAction action) 
				
						 {
				
				
						{
						 2
						
								 //
						 TODO 自动生成方法存根
        
						//
						 TODO 自动生成方法存根
						
								
						
						 3
						
								 IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						
						        IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						 4
						
								 IViewPart vw;
        IViewPart vw;
						 5
						
								 
								 for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
        
						for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
						
								 {
						
						
								{
								 6
								
										 vw 
								=
								 vfs[i].getView(
								false
								);
             vw 
								=
								 vfs[i].getView(
								false
								);
								 7
								
										 
										 if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
             
								if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
								
										 {
								
								
										{
										 8
										
												 GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
                     GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
										 9
										
												 gc.drawRectangle(
										280
										, 
										50
										, 
										100
										, 
										100
										);
                     gc.drawRectangle(
										280
										, 
										50
										, 
										100
										, 
										100
										);
										10
										
												 gc.dispose();
                     gc.dispose();
										11
										
												 }
             }
								
								
										
								
								12
								
										 }
        }
						
						
								
						
						13
						
								 
								
						
						14
						
								 }
    }
				
		 
		菜单项绘制渐变矩形DrawGradientAction.java的关键部分:
		
				 1
				 
				 public
				 
				void
				 run(IAction action)
				public
				 
				void
				 run(IAction action) 
				
						 {
				
				
						{
						 2
						
								 //
						 TODO 自动生成方法存根
        
						//
						 TODO 自动生成方法存根
						
								
						
						 3
						
								 IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						
						        IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						 4
						
								 IViewPart vw;
        IViewPart vw;
						 5
						
								 
								 for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
        
						for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
						
								 {
						
						
								{
								 6
								
										 vw 
								=
								 vfs[i].getView(
								false
								);
             vw 
								=
								 vfs[i].getView(
								false
								);
								 7
								
										 
										 if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
             
								if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
								
										 {
								
								
										{
										 8
										
												 GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
                     GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
										 9
										
												 gc.setBackground(window.getShell().getDisplay().getSystemColor(SWT.COLOR_BLUE));
                     gc.setBackground(window.getShell().getDisplay().getSystemColor(SWT.COLOR_BLUE));
										10
										
												 gc.fillGradientRectangle(
										80
										,
										200
										,
										100
										,
										100
										,
										false
										);
                     gc.fillGradientRectangle(
										80
										,
										200
										,
										100
										,
										100
										,
										false
										); 
										11
										
												 
												
										
										12
										
												 gc.dispose();
                     gc.dispose();
										13
										
												 }
             }
								
								
										
								
								14
								
										 }
        }
						
						
								
						
						15
						
								 
								
						
						16
						
								 }
    }
				
		 
		菜单项绘制图像DrawImageAction.java的关键部分:
		
				 1
				 
				 public
				 
				void
				 run(IAction action)
				public
				 
				void
				 run(IAction action) 
				
						 {
				
				
						{
						 2
						
								 //
						 TODO 自动生成方法存根
        
						//
						 TODO 自动生成方法存根
						
								
						
						 3
						
								 IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						
						        IViewReference[] vfs 
						=
						 window.getActivePage().getViewReferences();
						 4
						
								 IViewPart vw;
        IViewPart vw;
						 5
						
								 
								 for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
        
						for
						(
						int
						 i
						=
						0
						; i
						<
						vfs.length; i
						++
						)
						
								 {
						
						
								{
								 6
								
										 vw 
								=
								 vfs[i].getView(
								false
								);
             vw 
								=
								 vfs[i].getView(
								false
								);
								 7
								
										 
										 if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
             
								if
								(vw.getTitle().equals(
								"
								画图板
								"
								))
								
										 {
								
								
										{
										 8
										
												 GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
                     GC gc 
										=
										 
										new
										 GC(((CanvasView)vw).canvas);
										 9
										
												 Image img 
										=
										 
										new
										 Image(window.getShell().getDisplay(),
										"
										E:\\img.gif
										"
										);
                     Image img 
										=
										 
										new
										 Image(window.getShell().getDisplay(),
										"
										E:\\img.gif
										"
										);
										10
										
												 gc.drawImage(img, 
										280
										, 
										200
										);
                     gc.drawImage(img, 
										280
										, 
										200
										);
										11
										
												 gc.dispose();
                     gc.dispose();
										12
										
												 }
             }
								
								
										
								
								13
								
										 }
        }
						
						
								
						
						14
						
								 
								
						
						15
						
								 }
    }
				
		 
		
				
上面的方法虽然实现了绘图,但是还有一个问题,就是一旦我们的窗口最小化或者被别的窗口遮挡后,图形就会消失。原因其实很简单,一旦我们的窗口最小化或者被别的窗口遮挡后,控件就需要重画,所以我们画的图形就不见了,如果要让控件重画的时候也能绘制图形,就应该使用canvas.addPaintListener()为控件添加Paint事件的监听器。示例代码见下。
		
				 1
				 package
				 cn.blogjava.youxia.views;
				package
				 cn.blogjava.youxia.views;
				 2
				
						 
						
				
				 3
				
						 import
				 org.eclipse.swt.widgets.Composite;
				
				import
				 org.eclipse.swt.widgets.Composite;
				 4
				
						 import
				 org.eclipse.ui.part.ViewPart;
				
				import
				 org.eclipse.ui.part.ViewPart;
				 5
				
						 import
				 org.eclipse.swt.widgets.Canvas;
				
				import
				 org.eclipse.swt.widgets.Canvas;
				 6
				
						 import
				 org.eclipse.swt.SWT;
				
				import
				 org.eclipse.swt.SWT;
				 7
				
						 import
				 org.eclipse.swt.events.
				*
				;
				
				import
				 org.eclipse.swt.events.
				*
				;
				 8
				
						 import
				 org.eclipse.swt.graphics.Image;
				
				import
				 org.eclipse.swt.graphics.Image;
				 9
				
						 import
				 org.eclipse.ui.PlatformUI;
				
				import
				 org.eclipse.ui.PlatformUI;
				10
				
						 
						
				
				11
				
						 
						 public
				 
				class
				 CanvasView 
				extends
				 ViewPart
				
				public
				 
				class
				 CanvasView 
				extends
				 ViewPart 
				
						 {
				
				
						{
						12
						
								 
								
						
						13
						
								 public
						 Canvas canvas;
    
						public
						 Canvas canvas;
						14
						
								 @Override
    @Override
						15
						
								 
								 public
						 
						void
						 createPartControl(Composite parent)
    
						public
						 
						void
						 createPartControl(Composite parent) 
						
								 {
						
						
								{
								16
								
										 //
								 TODO 自动生成方法存根
        
								//
								 TODO 自动生成方法存根
								
										
								
								17
								
										 canvas 
								=
								 
								new
								 Canvas(parent,SWT.NONE);
								
								        canvas 
								=
								 
								new
								 Canvas(parent,SWT.NONE);
								18
								
										 
										 canvas.addPaintListener(
								new
								 PaintListener()
        canvas.addPaintListener(
								new
								 PaintListener() 
								
										 {
								
								
										{
										19
										
												 
												 public
										 
										void
										 paintControl(PaintEvent e)
            
										public
										 
										void
										 paintControl(PaintEvent e) 
										
												 {
										
										
												{
												20
												
														 //
												画椭圆
                
												//
												画椭圆
												
														
												
												21
												
														 e.gc.drawOval(
												80
												, 
												50
												, 
												100
												, 
												100
												);
												
												                e.gc.drawOval(
												80
												, 
												50
												, 
												100
												, 
												100
												);
												22
												
														 //
												画矩形
                
												//
												画矩形
												
														
												
												23
												
														 e.gc.drawRectangle(
												280
												, 
												50
												, 
												100
												, 
												100
												);
												
												                e.gc.drawRectangle(
												280
												, 
												50
												, 
												100
												, 
												100
												);
												24
												
														 //
												画渐变矩形
                
												//
												画渐变矩形
												
														
												
												25
												
														 e.gc.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_BLUE));
												
												                e.gc.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_BLUE));
												26
												
														 e.gc.fillGradientRectangle(
												80
												,
												200
												,
												100
												,
												100
												,
												false
												);
                 e.gc.fillGradientRectangle(
												80
												,
												200
												,
												100
												,
												100
												,
												false
												);
												27
												
														 //
												画图形
                 
												//
												画图形
												
														
												
												28
												
														 Image img 
												=
												 
												new
												 Image(PlatformUI.getWorkbench().getDisplay(),
												"
												E:\\img.gif
												"
												);
												
												                 Image img 
												=
												 
												new
												 Image(PlatformUI.getWorkbench().getDisplay(),
												"
												E:\\img.gif
												"
												);
												29
												
														 e.gc.drawImage(img, 
												280
												, 
												200
												);
                 e.gc.drawImage(img, 
												280
												, 
												200
												);
												30
												
														 
														
												
												31
												
														 }
        }
										
										
												
										
										32
										
												 }
								
								);
        }
								
								);
								33
								
										 }
    }
						
						
								
						
						34
						
								 
								
						
						35
						
								 @Override
    @Override
						36
						
								 
								 public
						 
						void
						 setFocus()
    
						public
						 
						void
						 setFocus() 
						
								 {
						
						
								{
								37
								
										 //
								 TODO 自动生成方法存根
        
								//
								 TODO 自动生成方法存根
								
										
								
								38
								
										 
								
								
										
								
								39
								
										 }
    }
						
						
								
						
						40
						
								 
								
						
						41
						
								 }
}
				
				
						
				
				42
				
						 
				
		 
		GC类的绘图方法很多,而且可以设置不同的前景色,背景色,画笔,画刷等等,还可以裁减图形,这些就靠我们慢慢探索了。