??xml version="1.0" encoding="utf-8" standalone="yes"?> 在我们创建领域模型前Q我们有必要了解一下我们的模型用来表达什么内宏V?所以我先解释一下在q个pd文章中要实现应用?假设Eclipsel织邀请你~写一个让他们理贡献者和目的应用程序?
我们需要创Z个模型来表达客户提供的信息。他们有可能如下图? 让我们进一步的看看q个模型? fundation是这个模型的根,他拥有两个列表属性? Eclipse目拥有很多属性,比如目开始和l束旉、项目的主页的url{等。下面列出我们最感兴的? 当一个用hZ个项目的贡献者(CommitterQ时Q这徏立了一个committership。他拥有一个开始时间和l束旉。另外我们还要记录下下面的属性?
贡献者或目领导人的信息。我们关pȝ信息如下Q? 下面q张cdl出了关于上面模型的全貌? 正如你所看到的,我把许多关系设成了双向关pR?As you noticed I modeled many of the relations as
bidirectional relations.
q个q不是严D求所有地斚w要这P因ؓ有的地方可以通过eComtainer来获取他的父二Ӏ就像project-subproject一栗?
但是包含关系Qcontainment
relationshipQ在使用databinding的情况下׃太合适了。因Z子到父亲时没有对应featureQ只能通过调用eContainer()Ҏ来获得?
EMF提供了一个编辑器来创Z的Ecore-Modelq把它保存成XMI格式。我们可以用它来创徏试数据。下囑ְ是一个例子?/p>
除了q些内容外我q找C三本书: W一本和W二本是在是Z Birt 2.1?/p>
W三本书是基于Birt 2.2 有了q些东西基本可以上路了。但是我又一惻I如果有点例子更好了。例子肯定是有的。官方就有,q等什么呢q不赶紧L?/p>
到里面随便找吧。肯定有你合适的?/p>
下面要做的事情就是分析好你的需求,好好用birt来表C的内容了?/p>
问:目图标报错Q?font face="Times New Roman, serif">Problems
试图有一条错误显C?#8220;Java
compiler level does not match the version of the installed Java
project facet.”?/p>
{:q个是因?font face="Times New Roman, serif">Facted
Project中的Java版本讑֮与项目的Java版本讑֮不一致?/p>
?font face="Times New Roman, serif">Drawing Q? Modify: Modify Faceted Project中所C,q个时候项目的Java的版本ؓ5.0。如果项目的Java
Compiler的设|如Drawing Q? Java C: Java Compiler中所C的讄。就是会出现问题中所q的错误。修改的方式很简单,只要l一一下他们的讄。让他们保持一致就OK了?/p>
q个数据库是Mysql
5.0. q个数据表在Navicat中的设计视图如下图?/p>
q种问题不光出现在mysql数据库中Q在oracle 10g的数据库中我也发CcM的情c?/p>
发现他不能正常的昄Clob和Blobq两U类型?/p>
文中提到的代?a title="castexception_src" href="http://m.tkk7.com /Files/JetGeng/castexception.zip">castexception_src
~译好了包括不同的版本org.gunn.castexception.supplier插g文g?a title="castexception_bin" href="http://m.tkk7.com/Files/JetGeng/castexception_bin.rar">castexception_bin
]]>
projects:
像EMF,Techonlogy,Platformq样的顶U项目?
persons:
参加一个或多个目的h?
subprojects:
一个项目可以拥有多个子目。子目本n也可以拥有多个子目?
parent:
目有一个父Ԍ除了目外)。这意味着目和子目Qproject-subprojectQ的关系是一个双向的关系?
projectleads
一个项目有多个目领导人?
committers
一个项目可以拥有多个A献者?
project:
和committership相关的项目。项目和committership是一个双向的关系?
person:
参加目的h?
committerships:
用于保存和h相关的所有的committerships.q说明h和committership是一个双向关pR?
]]>
]]>
我所使用?/span>DTP的版本是dtp-sdk_1.0_200612211。我通过Data Source Explorer来浏览数据库是发现有的字D늚cd不能正确昄?br>
在Sql plus中这个表的描qCؓQ?br>
知道怎么回事的兄弟们Q帮忙告诉我一声。先谢谢了?br>
]]>
]]>
首先要在模型上支持,能够保存q接的信息。对于不同的目有不同的要求。我们通过两个例子可以看一Ҏ?/font>
1?/font>http://www13.plala.or.jp/observe/GEF/CZ中的GEF6.zip Q下面称q个例子?/font>HelloWoldQ?/font>
q行的结果入下图所C:
它的模型可以使用如下的类图来表示Q?/font>
用来描述Connection的分别是LineConnectionModel?/font>ArrowConnectionModelq两个类。这两个cȝ父类和图形模型(HellowModelQ相兟?/font>
2?/font>IBMU皮书中?/font>GEF范例(下面U这个例子ؓworkflow)
q行效果如下图:
他的模型可用下面的类图描qͼ
其实q接的模型应该很单,他只要能保存他的两端的对象就好了。图形模型(?/font>HelloWold中的HelloModelQ能够保持与他相兌的连接(HelloWold中的LineConnectionModel?/font>ArrowConnectionModelQ?/font>
看完?/font>ModelQ我们下面就可以看看EditPart部分了?/font>
要看EditPart当然是要看最关键的了。也是和连接直接关联的EditPart了。分别察看了和连接相关的EditPartQ发C们都会实C个叫org.eclipse.gef.NodeEditPart的接口。如下图所C:
?/font>nodeEditPart中有四个Ҏ需要实现。通过q个四个Ҏ的名字就可以看出他们?/font>Anchor2密切相关。下面就来看看这几个Ҏ的具体功能:
ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection);
当需要画q接的时候,通过q个Ҏ获取q接的源锚点。不这个锚点在什么位|,他取得以后直接就用它作ؓ源点了?/font>
ConnectionAnchor getSourceConnectionAnchor(Request request);
当在准备创徏q接的时候,通过Request来获取新q接的源锚点?/font>
另外的两个就不再啰嗦了。是Z获得目标的锚炏V?/font>
但是我们肯定看到?/font>HelloWold?/font>Workflow中的q接有点不一栗?/font>HelloWold中直接是囑օ上的Q?/font>workflow是通过q接基本囑օ上面的一个子囑օ而连接的。简单来说就是他们连接的anchor有点不一Pq样׃出现执行l果的不同?/font>
下面来看看他们到底是怎么实现的。根据上面提到的。锚点的获取是通过getSourceConnectionAnchor?/font>getTargetConnectionAnchorҎ来获取的。我们只需要好好比对一下他们这几个Ҏ的不同就可以了?/font>
HelloWold中的getSourceConnectionAnchor
public ConnectionAnchor getSourceConnectionAnchor(Request request) {
returnnew ChopboxAnchor(getFigure());
}
q里q单的创徏一? ChopboxAnchor 好了。这个就可以直接q到?/span>Figure上了?/span>
?/font>workflow中这个情늨微有一点复杂了。先不说Q还是看看他? getSourceConnectionAnchor 是怎么实现的?/font>
public ConnectionAnchor getSourceConnectionAnchor(
ConnectionEditPart connection) {
Connection edge = (Connection) connection.getModel();
return getNodeFigure().getConnectionAnchor(edge.getSource().getName());
}
/**
*returnsananchorgivenitsname
*
*@paramportNamenameoftheanchor
*@returntheanchorwiththename<code>portName</code>
*/
public ConnectionAnchor getConnectionAnchor(String portName) {
return (ConnectionAnchor)connectionAnchors.get( portName );
}
protected Hashtable connectionAnchors = new Hashtable(7);
/**
*Addaninputportanditsanchor
*
*@paramportName
*uniquenametorefertotheport
*/
publicvoid addInput(String portName) {
InputPortFigure inputPort = new InputPortFigure();
add(inputPort);
PortConnectionAnchor anchor = new PortConnectionAnchor(inputPort);
getTargetConnectionAnchors().add(anchor);
connectionAnchors.put(portName, anchor);
}
通过q几个方法可以看出它是在dInput时候就创徏好了一个和PortFigure 相关Anchorq把它保存v来。在要用的时候就把它取出来。这样就搞定了?/font>
具体的可以参考这两个例子的代码。好了,打完收工?/font>
参考文?/font>
IBM U皮?/font>
问题在这里出来:当没有出现滚动条的时候一切都很正常,当一出现滚动条就L没有办法拖动了。最后才发现DragSourceEvent中的坐标是按照屏q来得,?/span>EditPartViewer 中的坐标是按照他的那?/span>viewer来得。这个地斚w要{换一下?/span>
q个转换的动作发现在jfireQ?/span>org.nightlabs.editor2d.util.EditorUtil https://svn.jfire.org/svn/main/trunk/org.nightlabs.editor2d/src/org/nightlabs/editor2d/util/EditorUtil.javaQ中有现成的。不多说了,拿来用吧?/p>
]]>
说干干了。定义一?font face="Times New Roman, serif">ActionQ和快捷键帮定就不多说了。生?font face="Times New Roman, serif">build.xml通过你自己喜Ƣ的代码生成技术(个h喜欢?font face="Times New Roman, serif">JET4Q定义模板ƈ生成代码?/p>
下面在自动执?/span>Ant脚本的时候卡了一会壳。看到?/span>以编E方式调?Apache Ant
?/span>2 觉得问题已经解决了。不q这U方式是?/span>Eclipse q行?/span>VM中执行,也就是说会把Eclipse 挂住。我希望辑ֈ的效果是?/span>org.eclipse.ant.ui插g辑ֈ的效果一栗最好是去调用他了。他是在eclipse默认集成的,直接依赖于他不会有什么问题。看了他plugin.xml发现了一个好东西?/span>org.eclipse.debug.core.launchConfigurationTypes?/font>Q所以我想我创Z?/span>ILaunchConfigurationType 用它来实实例化一?/font>ILaunchConfigurationWorkingCopy是不是就可以搞定?/font>。上|?/font>google了一下有个兄弟写完了q个部分的工?/font>1。把他的代码攑ֈ一个插仉面简单的跑了一下,果然可行。爽Q?br />
参考文档:
Eclipse 3.1 Update to “How to run ANT files programmatically?/font>
以编E方式调?Apache AntQ?/span>http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0502_gawor/0502_gawor.htmlQ?/span>
代码范例http://dev.eclipse.org/mhonarc/lists/platform-ant-dev/msg01053.html
http://www.eclipse.org/articles/Article-JET/jet_tutorial1.html
PlatformUI.getWorkbench().getActiveWorkbenchWindow()
?/p>
Q?/span>?font face="Times New Roman, serif">PlugincMQ?
getDefault().getWorkbench().getActiveWorkbenchWindow()
。一般情况下q两个方?span lang="zh-CN">?/span>能够很好的工作。但是突然有一天发C不能工作了。郁h都不行了。察看了一下变?span lang="zh-CN">Q?span lang="zh-CN">如下?/span>Q?/span>?img src="http://m.tkk7.com/images/blogjava_net/jetgeng/Eclipse/display.jpg" alt="display.jpg" border="0" height="291" width="752" />
q个activatedWindow明明有啊Q怎么取不到呢?/p>
打开代码一看,看到 org.eclipse.ui.internal.Workbench cM?/span> getActiveWorkbenchWindow Ҏ?/span>
E序跑到 Display.getCurrent() q一l句q我掉铑֭Q返回了一?/font> null Q。就是他Q就是他了!到网?/font> google 了一下。看看在什么状况下他会q回一?/font> null. ?/font> http://wiki.eclipse.org/index.php/FAQ_How_do_I_get_a_Display_instance%3F 扑ֈ了?/font>
他说Q?/font> Display 永远和创Z的线E联pd一Pq且一个线E拥有一个活动的 Display 。在创立 Display 的线E中可可以通过 Display.getCurrent() 获得当前zd?/font> Display 。如果出了这个线E就看不到这?/font> Display 了。如果有的线E不拥有 Display Q那它的 Display.getCurrent() 只能得?/font> null 了?/font>
回头看了一下我的代码,我是在新建的U程中启动了调用了这个方法。难怪他不给面子呢!
参考文献:
http://wiki.eclipse.org/index.php/FAQ_How_do_I_get_a_Display_instance%3F
http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/Display.html
现在只是看了
在项目中单的使用了一下他作ؓ查询的工兗感觉他真的很不错,在下一D|间将会重点去了解他?/p>
后来?span lang="zh-CN">惛_?/span>我需要从囑Ş~辑器中拖拽对象?/span>swt控g中又该怎么做?br />l过一D|间的探烦Q终于搞定了?/span>
C如下q程Q希望对需要的朋友有点帮助?/p>
首先有了《从SWT控g中托拽对象到GEF~辑器中》文中对addDropTargetListenerҎ使用的经历,很快q定我需要对GraphicalViewerd一?/span>DragSourceListener?/span>
想着到这个地Ҏ应该可以很快收工了。但是添加完了以后发?span lang="zh-CN">原来的拖动功能都没有?/span>Q这个怎么回事。谁在后面搞鬹{?/font>
l过一D|间的狂搜滥烦l于扑ֈ了问题的关键。因?font face="Times New Roman, serif">GEF不允许同时有两个zd DragSource ?/p>
它本w已l拥有一?font face="Times New Roman, serif">DragSource了(~辑器内部的托拽Q,我们q时候添加一个就会存在多
DragSource了。当我添加一个新?font face="Times New Roman, serif">DragSource时候我们新家的DragSource׃被认为是默认?font face="Times New Roman, serif">DragSource?/p>
他以前的DragSource失效了。这不是我像看到的?/p>
怎么处理。看C一个牛人的解决Ҏ?/p>
What I made to fix the problem was to only allow my DragSource to act under certain
conditions (in my application this happens when you click and drag the mouse AND
the SHIFT key is pressed). So when the SHIFT key is not pressed my DragSource does
nothing and the editor's internal drag and drop works fine?br />
public void dragStart(DragSourceEvent event)
{
...
if (!condition.isValid())
event.doit = false;
...
}
我尝试了一下这U状况,一下就搞定了?/span>
在我的项目中Q由于还有一些数据需要{化?font size="2">呵呵Q感觉不错?br />
参考文档:
http://dev.eclipse.org/newslists/news.eclipse.tools.gef/msg15754.html
一般情况下GEFE序都是采用如下的界面:
新徏对象的操作时通过拖拽Palette中元素到~辑而获得。但是有时候可能需要从SWTQ操作系l拖一些元素到GEF~辑器中来?/p>
下面我就把创L拖拽q程大概的描qC下:
1、定义拖拽源Q?font face="Times New Roman, serif">DragSourceQ?/p>
2、定义拖拽目标的监听Q?font face="Times New Roman, serif">DropTargetQ?/p>
到这里对于一般的拖拽其实是可以完工了?/p>
q个部分可以参?font face="Times New Roman, serif">weidagang2046的专栏的?/a>DND入门学习?/a>
但是要能?font face="Times New Roman, serif">GraphicalViewerq个对象扮演?/font>DropTarget我们q需要做点其他的工作?/font>GraphicalViewerq个cLw提供了一?/font>addDropTargetListenerҎ。看到这个方法是不是一늋喜啊。如果有也是应该的,因ؓq个Ҏ是我们解决前面提出问题的关键?/font>
好了看看他的声明吧!
public void addDropTargetListener(TransferDropTargetListener listener)
他这个参数居然不?/font> DropTargetListener 。这?/font> TransferDropTargetListener 是一个什么玩意啊Q?/font>
?/font> help 中查刎ͼ
A DropTragetListener
that handles one type of SWT Transfer
.
The purpose of a TransferDropTargetListener is to:
Determine enablement for a Drop operation. Enablement is often a function drop location, and/or criteria.
When enabled, optionally showing feedback on the DropTarget.
Performing the actualy Drop
DelegatingDropAdapter
allows these functions to be implemented separately for unrelated
types of Drags. DelegatingDropAdapter then combines the function of
each TransferDropTargetListener, while allowing them to be
implemented as if they were the only DragSourceListener.
偷下懒,׃译了?/font>
创徏如下cL实现q个接口Q?/font>
public class TreeNodeTransferDropTargetListener extends
AbstractTransferDropTargetListener {
public TreeNodeTransferDropTargetListener(EditPartViewer editPartViewer) {
// 改类默认是处? TextTransfer cd的拖拽事?/font>
super (editPartViewer,TextTransfer.getInstance());
// TODO Auto-generated constructor stub
}
@Override
protected void updateTargetRequest() {
}
}
我们q个拖拽x让他执行一?/font>
create
命o。所以下面就是要重蝲他的
createTargetRequest()
用来处理
create
对象的请求(
CreateRequestion
Q?/font>
CreateRequetion
需要用到一个类Q帮助我们创建对象的工厂cR?/font>
GEF
l了我们q样的一个接?/font>
CreationFactory
。下面我们取实现他就好了?/p>
package
org.eclipse.gef.examples.shapes.rcp.views;
import
org.eclipse.gef.examples.shapes.model.EllipticalShape;
import
org.eclipse.gef.requests.CreationFactory;
public
class
TypeCreationFactory
implements
CreationFactory {
public
Object getNewObject() {
//
TODO
Auto-generated method stub
EllipticalShape
label =
new
EllipticalShape();
return
label;
}
public
Object getObjectType() {
return
EllipticalShape.
class
;
}
}
注意Q这里的
getNewObject
是返回要创徏cȝ一个对象实例?/font>
GetObjectType
需要返回需要创建对象的cR这个可不要搞反了?/font>
q样我们可以把我们?
TreeNodeTransferDropTargetListener
cM?/font>
createTargetRequest
Ҏ加上了?/font>
private
TypeCreationFactory factory = new
TypeCreationFactory();
protected
Request createTargetRequest() {
CreateRequest
request =
new
CreateRequest();
request.setFactory(
factory
);
return
request;
}
好了q个时候不要客气了Q加?/font>
protected
void
handleDragOver() {
getCurrentEvent().
detail
= DND.
DROP_MOVE
|DND.
DROP_COPY
;
super
.handleDragOver();
}
@Override
protected
void
handleDrop() {
//String
s = (String)getCurrentEvent().data;
//factory.setText(s);
super
.handleDrop();
}
q样的方法吧?/font>
q样q个功能完成了?/font>
参考文献:
http://m.tkk7.com/weidagang2046/archive/2006/09/05/67707.html
http://www.eclipse.org/articles/Article-GEF-dnd/GEF-dnd.html
]]>
看到一个例子中看到?
-- 1所C的功能?/p>
其中?font face="Times New Roman, serif">-1中的q线是自适应的会保持该线D|最短的Q其实他是用的ShortestPathConnectionRouterQ这个时候我q不知道,我是一个新手大家见W了Q。经q一番调查以后发现原来是?font face="Times New Roman, serif">EditPart中的refreshVisualsҎ中有如下代码?/p>
代码--1
ConnectionLayer cLayer
=
(ConnectionLayer) getLayer(LayerConstants.CONNECTION_LAYER);
FanRouter router
=
new
FanRouter();
router.setSeparation(
30
);
spRouter
=
new
ShortestPathConnectionRouter(getFigure());
router.setNextRouter(spRouter);
cLayer.setConnectionRouter(router);
}
当时q啊,他肯定是在给一个特定的Layer加上一个什么玩意。然后就通过q个玩意来完成对于\径的计算Q其实这些东西完全是从代码的字面意思而得到的Q。我q些东西加到我的代码中了。但是我q行的效果还是没有v作用。他依旧是以前的那幅得行。我抓,抓也没有用。就是达不到我要的效果?/p>
q试一下的x我打开了我?font face="Times New Roman, serif">ConnectionEditPart(是q线的那?font face="Times New Roman, serif">EditPart),发现?font face="Times New Roman, serif">createFigure中我是这么写的?/p>
代码 -- 2
connection.setConnectionRouter(
new
BendpointConnectionRouter(){
public
void
route(Connection conn) {
GraphAnimation.recordInitialState(conn);
if
(
!
GraphAnimation.playbackState(conn))
super
.route(conn);
}
});
很明显我在这里给connection赋了一?font face="Times New Roman, serif">ConnectionRouter。最l其效果的是q一?font face="Times New Roman, serif">ConnectionRouter起作用了?/p>
Md刚掉他就万事大吉了?/p>
到这里代码部分其实就完了。但是他背后的还有一Ҏ事?/p>
q里有三个角Ԍ
1?font face="Times New Roman, serif">Connection
2?font face="Times New Roman, serif">ConnectionAnchor.
3
?/span>
ConnectionRouter
q个cL用来昄两点之间的线D?/span>
(Line),
他的L和终Ҏ通过
ConnectionAnchor
来定义的。至于他的其他点是通过
ConnectionRouter
计算讄的。从q个地方来看
ConnectionRouter
是一个负责计的工具cR这样完全可以让所有的
Connection
使用一?/font>
ConnectionRouter
实例Q这是今天最要记下的部分Q?/font>
?/font>
gef
中他׃ؓ我们提供了这L机制。下面的q段话是
Gef
help
中的一句话。他p明了q个道理?/font>
A
convenient way to share the router with all connections and to place
connections above the drawing is to use a
ConnectionLayer
.
The layer has a connection router property which it shares with every
child that's a connection. You can update this property and easily
change every connection's router at once.
q个道理要{换成代码的话是代码
?
1
了?/font>
q个东西很简单。希望对像我一L新手有点帮助?/font>
关于q个例子中用的原理八进制讲的很清楚了。我׃啰嗦了。我把自己读这部分代码的笔记记下来?/p>
Jmerger
使用初步
(
?/font>
)
前面一提C他基本的概念和能完成的功能。在q一里我们来看看他的用条件和使用Ҏ?/font>
使用条gQ应?/font>
org.eclipse.jdt.core
Q提供基本的语法分析Q?/font>
org.eclipse.core.runtime
Q提供基本的
URI
{)
org.eclipse.ui
Q提供进度条Q我qCq个。其他可能还有)?/font>
看到他要使用q么?/font>
Eclipse
的东ѝ我d的打消了?/font>
Eclipse
外用他的打(如果谁有好的解决Ҏ记得l我发一份。在下感Ȁ不尽Q?/font>
我们下面来看看如何定制他的合ƈ规则是如何定义的吧。我先做法是找了一个例子。看看他是如何工作的?/font>
我的
Merge.xml
如下Q?/font>
清单
2
Q?/font>
<? xml version = "1.0" encoding = "UTF-8" ?>
< merge:options xmlns:merge = "http://www.eclipse.org/org/eclipse/emf/codegen/jmerge/Options" >
< merge:dictionaryPattern
name = "generatedMember"
select = "Member/getComment"
match = "\s*@\s*(gen)erated\s*\n" />
<!-- if target is generated, transfer -->
<!-- change to sourceMarkup if the source is the standard -->
< merge:pull
targetMarkup = "^gen$"
sourceGet = "Method/getBody"
targetPut = "Method/setBody" />
</ merge:options >
q行前的
Source
Q?/font>
Java
Source A
Q?
?/font>
分源代码?/font>
/**
*
Source javadoc 13
*
<!-- begin-user-doc -->
*
Source user javadoc 14
*
<!-- end-user-doc -->
*
Source javadoc 15
*
@return source
*
@generated
*/
public
boolean isID()
{
//
begin-user-code
System.out.println("Source
user code 1");
//
end-user-code
System.out.println("Source
code 2");
return
id == "source";
}
q行?/font>
Target(Java
Source B)
部分的源代码为:
/**
* Source javadoc 13
* <!-- begin-user-doc -->
*
Target user javadoc 16
* Target user javadoc 17
* <!--
end-user-doc -->
* Source javadoc 15
* @return source
* @generated
*/
public boolean isID()
{
//This
is my owner code
System.out.print("Will be replace");
// begin-user-code
System.out.println("Target user
code 2");
// end-user-code
System.out.println("Source code 2");
return id ==
"source";
}
/**
* Target javadoc 19
* <!-- begin-user-doc -->
*
Target user javadoc 20
* Target user javadoc 21
* <!--
end-user-doc -->
* Target javadoc 22
* @param target
* @generated NOT
*/
public void setID(boolean value)
{
//This Jet Code
System.out.println("Not be
replaced!");
id = value ? "target" :
"source";
System.out.println("Target code
4");
}
注意Q?/font>
isID
Ҏ
注释里有?/font>
@generated?/font>
q一行。?
setID
Ҏ的注释中?/font>
@generated
NOT
?/font>
q行后的l果是(
Result
of merge
Qؓ
/**
* Source javadoc 13
* <!-- begin-user-doc -->
*
Target user javadoc 16
* Target user javadoc 17
* <!--
end-user-doc -->
* Source javadoc 15
* @return source
* @generated
*/
public boolean isID()
{
//
begin-user-code
System.out.println("Source
user code 1");
//
end-user-code
System.out.println("Source
code 2");
return
id == "source";
}
//
使用?/font>
Source
部分的代码?/font>
/**
* Target javadoc 19
* <!-- begin-user-doc -->
*
Target user javadoc 20
* Target user javadoc 21
* <!--
end-user-doc -->
* Target javadoc 22
* @param target
* @generated NOT
*/
public void setID(boolean value)
{
//This Jet Code
System.out.println("Not be
replaced!");
id = value ? "target" :
"source";
System.out.println("Target code
4");
}
//
l持原来
Target
中的代码没有变化?/font>
q样我们׃隄?/font>
<
merge:dictionaryPattern
…?>
D?/font>
是定义了一个匹配模式。具体的q个匚w模式要做的动作就是在
<
merge:pull
targetMarkup = "^gen$"
sourceGet = "Method/getBody"
targetPut = "Method/setBody" />
D中定义了。猜想他只是?/font> Source 部分的内容直接输出到 Target 那里M?/font>
如果我们觉得需要做点什么过滤。比如说想保?/font>
Target
中一个特定的内容。这一个我们可以通过
merge:pull
?/font>
sourceTransfer
属性来讄?/font>
现在来看一个例子:
?/font>
merge:pull
节点修改?/font>
<
merge:pull
targetMarkup = "^gen$"
sourceTransfer = "(\s*//\s*begin-user-code.*?//\s*end-user-code\s*)\n"
sourceGet = "Method/getBody"
targetPut = "Method/setBody" />
注意Q添加了一?
sourceTransfer,
他的?/font>
值是一个正则表辑ּ。匹配的是被
?font face="Courier New, monospace">//
begin-user-code?
和?/font>
//
end-user-code?/font>
包围住的所有的字符?/font>
Target
的代码ؓQ?span lang="zh-CN">我们现在只是x
isID
Ҏ
Q?/font>
?/font>
/**
* Source javadoc 13
* <!-- begin-user-doc -->
*
Target user javadoc 16
* Target user javadoc 17
* <!--
end-user-doc -->
* Source javadoc 15
* @return source
* @generated
*/
public boolean isID()
{
//
begin-user-code
System.out.println("Source
user code 1");
System.out.println("This
will not be replaced!");
//
end-user-code
System.out.print("this
will be replaced!");
System.out.println("Source
code 2");
return
id == "source";
}
h意看一下红色部分的两行代码?/font>
合ƈ后的代码为:
/**
* Source javadoc 13
* <!-- begin-user-doc -->
*
Target user javadoc 16
* Target user javadoc 17
* <!--
end-user-doc -->
* Source javadoc 15
* @return source
* @generated
*/
public boolean isID()
{
//
begin-user-code
System.out.println("Source
user code 1");
System.out.println("This will not be
replaced!");
//
end-user-code
System.out.println("Source code 2");
return
id == "source";
}
在?/font>
//
begin-user-code
?/font>
和?/font>
//
end-user-code
?/font>
外的代码全部被替换成了。这样就起到了过滤的效果?/font>
如上图:我的目的是想注释掉节?font face="Times New Roman, serif">merge:pull。于是在1?font face="Times New Roman, serif">3的位|分别加上了注释的开始和关闭?font face="Times New Roman, serif">tag。但是却发现了一个奇怪的问题。他认ؓ注释C|?font face="Times New Roman, serif">2q束了。而位|?font face="Times New Roman, serif">2的?font face="Times New Roman, serif">-->?/font>是作Z个用引号“引”v来的值存在的啊。我qL了?br />
我用的版本?font face="Times New Roman, serif">Eclipse
3.2M3
?/span>EMF框架中最l会Ҏ模型生成代码Q还可以反复生成。还能你自q辑的内容不丢失。够好玩的吧。那么这部分是怎么实现的呢Q看q一?/span>EMF介绍可以知?/span>EMF是通过JET完成代码生成的动作的。在?/span>使用 Eclipse Modeling Framework q行建模》这个系列的文章可以了解到q一炏V在该系列文章的W三部分q可以了解到使用JMerge 可以实现“成的代码插入现有的代码中,或者允总后的开发h员来定制所生成的代码,而不需要在重新生成代码旉新编写Q何内宏V”这L功能?/span>
他是通过创徏Junit 试cM例子的。他说过的东西我׃啰嗦了。我只是把我个h在看了他文章后的一些东西整理一下?/p>
好,现在q入正题?/p>
首先我们来说一?font face="Times New Roman, serif">JMergeq个名字?font face="Times New Roman, serif">Mergeq个单词是合q的意思。前面加了一个?font face="Times New Roman, serif">J?/font>不用多说Q肯定表C?font face="Times New Roman, serif">Java了(完全是参?font face="Times New Roman, serif">Junit,log4j…?/font>Q。那么我大?
猜测q个工具是用来合q?font face="Times New Roman, serif">Java代码的。既然是合ƈ应该符合下图描q的动作?img src="http://m.tkk7.com/images/blogjava_net/jetgeng/Jmerge-Name.jpg" alt="Jmerge-Name.jpg" border="0" height="227" width="488" />
合ƈ肯定是把两个东西和成一个。所以图中的Java Source A ?font face="Times New Roman, serif">Java Source B分别代表需要合q的部分了。最后的Result of Merge是合ƈ后的那一个结果了。应为我们合q的?font face="Times New Roman, serif">Java代码。这些代码如何合qӞ也就是我们期望的合ƈl果是什么样的。图中的Rule of merge是代表的这部分信息?/p>
在下面?font face="Times New Roman, serif">Jmerge的代码中
清单 1.
调用 JMerge
2 JMerger merger = getJMerger();
3
4 // set source
5 merger.setSourceCompilationUnit(
6 merger.createCompilationUnitForContents(generated));
7
8 // set target
9 merger.setTargetCompilationUnit(
10 merger.createCompilationUnitForInputStream(
11 new FileInputStream(target.getLocation().toFile())));
12
13 // merge source and target
14 merger.merge();
15
16 // extract merged contents
17 InputStream mergedContents = new ByteArrayInputStream(
18 merger.getTargetCompilationUnit().getContents().getBytes());
19
20 // overwrite the target with the merged contents
21 target.setContents(mergedContents, true, false, monitor);
22 //
23
24 //
25 private JMerger getJMerger() {
26 // build URI for merge document
27 String uri =
28 Platform.getPlugin(PLUGIN_ID).getDescriptor().getInstallURL().toString();
29 uri += "templates/merge.xml";
30
31 JMerger jmerger = new JMerger();
32 JControlModel controlModel = new JControlModel( uri );
33 jmerger.setControlModel( controlModel );
34 return jmerger;
35 }
我们可以很容易的扑և它们的对应物?/p>
我们先从JMerger的创建开始看起吧?/p>
uri += "templates/merge.xml";
JMerger jmerger = new JMerger();
JControlModel controlModel = new JControlModel( uri );
jmerger.setControlModel( controlModel );
q里用一个名ZؓZؓ?/span>merge.xml
的文件作ZؓZؓ输输?/span>input
参数创创H新Z一?/span>JControlModel
对象。传?/span>
传给JMerger
对象。做完这些后又调调用?
setSourceCompilationUnit
?
setTargetCompilationUnit
Ҏ。他们们?/span>
们的cȝ
cd都是IDOMCompilationUnit
Q用
q的朋友都会知道他就代表了一?/span>Java
文g
Q。很荣荣Ҏ׃惌v他们
们肯定就?/span>Java
Source A
?/span>Java
Source B
了至?/span>Rule
of merge
可以通过
q调?/span>
merger.merge()
后的
getContents
Q)Ҏ?/span>
?/span>获得
除了q种调用
方式外还有一个更
?/span>
的调用方式:
String
contents = merger.execute(null, new String[] { mergeXML,
source,target });
看了
execute
实现后就
不难
发现他的q?/span>
是用的W一
U?br />
关于具体如何定制合ƈ规则
和用条件打在下一中写?br />
很久想了如何在RcpE序中?/span>Spring。让Spring容器来管理我?/span>rcpE序中的Beans。看?/span>web目中用了spring后带来的好处Q最直接的就是看C码量了Q就一脸的憧憬。想我的好日子什么时候才会来啊?/span>
有这个憧憬后我就开始考虑改如何做了。大家肯定都知道如果?/span>eclipse rcpE序中用直接?/span>spring?/span>beanfactory无论你是使用方式都会说找不到配置文g的。这个其中的原因?/span>Eclipse 的每个插仉使用他们自己的类加蝲器(class loadQ?/span>
说明Q?/span>eclipse中类的详l的装蝲q程可以产考?/span>Contributing to eclipse 中文版?/span>p44?/span>
所以说能够正确的找?/span>bean的配|文件成了一个难题?/span>
q有一个问题就是如何管?/span>BeanFactory也是一个问题?/span>
既然提出了这两个问题Q那q一个一个的面对啊?/span>
W一个问题的解决方式。只要通过一个插件中的类可以获得?/span>
我试了一下通过如下代码可以切换class load
最头疼的问题就是如何来理spring?/span>BeanFactory。如果在每个Plugincȝl承c里都加上对beanfactory的创建。想想都是很恶心的事情。就个事情一直停滞不前。搞的我快郁h掉了?/span>
在快死q没有死的时候看C一个叫EclipseSpring目Q?/span>http://sourceforge.net/projects/eclipse-spring/Q。一看超爽。他直接把我惛_的事情直接给做了?/span>
下面我们来看看一下他的发布包里代的那个例子。这个例子很单。就只是提供了一?/span>view?/span>View里显CZ个条问候语?br />呵呵Q是不是很界面太单了。这个我们就不说了。我们来说说他这个示例中到底是怎么实现的?/span>
先看看他?/span>plugin.xml文g把?br />看看那个org.eclipse.ui.view那个扩展炏V是不是有点奇怪啊。他的类?/span>net.sourceforge.eclipsespring.SpringExtensionFactory:example/userNameViewq个样子的。一a看上d不是一个类。而是一个类代了点参数?/span>
不过可以断定他就是上图显C的view了?/span>
在看看上面那个扩展点
<extension
point="net.sourceforge.eclipsespring.beanFactoryContributors">
<beanFactoryContributor
class="net.sourceforge.eclipsespring.example.spring.BeanFactoryContributor"
id="example"/>
</extension>
q个扩展点干吗用的啊。嗯是一个问题?/span>
插g文g下面除了一?/span>plugin.xml文g外。还有一?/span>bean.xml的文件?br />q下一看,明白了她׃?/span>spring需要的配置文g。ƈ包括了对view的申明?/span>
?/span>net.sourceforge.eclipsespring.beanFactoryContributorsq个名字可以看出他是?/span>beanFactory做了一个扩展?/span>
去这个类看一下,是怎么回事?/span>
只是发现?br />E微回顾一下。在一?/span>plugin中要?/span>BeanFactoryContributorQ?/span>spring配置文g合上net.sourceforge.eclipsespring插g可以?/span>spring了?/span>
关于在这个过E中beanFactory如何创徏Q和扩展点如何被调用。我会在下一里说明。今天想睡了,虽然有点早。呵?/span>前一D|间说d把给朋友做的E序uid来的。一直拖到现在。真是有点不好意思。好了闲话就不说了?/span>
下图是我做出来的界面。现在看hq很_糙?br>q个E序主要d是l护一些船只的资料。然后能够迅速的查询些资料。这样就会出Cl护和查询这两大块。根据这L情况设计Z上图的界面?/span>
上图的界面包括三个部分:l 功能DQ一?/span>ViewQ。呵呵,很基本的一个功能导航?/span>
l 船舶搜烦Q一?/span>ViewQ。提供船舶查询功能?/span>
l 船舶l护Q一?/span>EditorsQ。用于添加和修改船舶信息?/span>
q里布局部分?/span>createInitialLayout中完成的?/span>
q个在前几天?/span>blog中就可以扑ֈ代码?/span>
不过有一点还是要提一下就?/span>IfolderLayout中的createFolderҎ中的各个参数?/span>
public void addView(String viewId,
int relationship,
float ratio,
String refId)
refId
-
the id of the reference part; either a view id, a folder id, or the special
editor area id returned by getEditorArea
最后一个参数表C我们添加的那个View相对于part的id?o:p>
如果我的代码是:
//add navigate view
IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.3f, editorArea);
left.addView(View.ID);
//Add Search part
IFolderLayout button = layout.createFolder("button", IPageLayout.BOTTOM, 0.6f, "left");
button.addView(SearchView.ID);
效果会是

如果代码写成呵呵Q大家不要见W。我刚开始学Q这部分的内宏V?/span>
q有是找了一?/span>DatePicker控g
http://sourceforge.net/projects/swt-datepicker q个控g使用h挺容易的。只要一句话可以了?br>很早很早听?/span>RCP了。也很想来玩玩,但是一直没有找到好的点子来l手。不q近D|间有个老朋友要求帮他做个小东西。他现在的需求很单。我怕他以后有要加什么内宏V所以就想用RCP来做。刚好用他来好好学习一下,要不都不好意思在bbs.rcp.cn混了?/span>
找了本书Q?/span>Eclipse Rich Client Platform Designing Coding and Packaging Java Applications》)按照书中的例子看了v来?/span>
了解基本的:
AbstractUIPluginQ?/span>
WorkbenchWindowAdvisorQ?/span>
WorkbenchAdvisorQ?/span>
ActionBarAdvisorQ?/span>
IperspectiveFactory?/span>ViewPart几个cR?/span>
收获最大的是看到yipsilon?/span>bbs.rcp.cn中关于布局的帖子?/span>
Ҏq段代码做出如下界面Q?/span>
前两天在|上看到一个需要把outline最大化的需求。我想啊这?/span>Ctrl +M不就的了Q呵呵,q个快捷我经常用。快成了条g反射了)。在往下看发现他的需求要求用~程实现。唉q个时候我?/span>Ctrl + Mq不上了?/span>
然后我就?/span>tmdQ这个功能既?/span>Eclipse本n已经实现了,那么肯定回有这L代码。我需要做的就是把q段代码扑և来。好了,定q个目标好办了?/span>
下面得惛_法怎么把这个功能地位到Eclipse源码中了。我现在知道得就只是Ctrl + M可以唤醒q部分得功能。其他的׃么都不知道了。那我怎么定位到这部分的源码呢。天哪。我该怎么办啊?/span>
后来理了一理想hEclipse中对于快捷键的实现。他们都是通过accelerator来定义的。?/span>accelerator后面一般回对应C?/span>action。这?/span>action会真真的来完成这个快捷键所要完成的功能。这样一惻I心里有了一点底。那么现在就把目标锁定到扑ֈ相应?/span>action的实现就完成了。对于找出相应的action的方法是通过扑ֈCtrl+M向对应的accelerator?/span>
那么q个action会在什么地方实现呢。我打开?/span>Plug-in Registry视图来随便看看。看看能有什么意外收莗?br>
q真巧在发现了有org.eclipse.uiq个插g。再点进ȝC?/span>Extensions?/span>
居然?/span>Maximize Active view or
Editorq个扩展炏V大胆猜?/span>org.eclipse.ui会提供一个关于?/span>Maximize Active View or
Editor”的实现。ؓ了证实我的猜惻I我打开?/span>org.eclipse.ui?/span>plugin.xml文g。看到有下面q一Dc?br>
q一D证实了我的猜想?/span>
下面如果能找到那各类实现了这?/span>command?/span>ok了。找q个比较容易了。呵c只要看看那各类里面?br>setActionDefinitionId("org.eclipse.ui.window.maximizePart");
q样的代码就可以搞定了?/span>
最后查?/span>org.eclipse.ui.internal. MaximizePartAction在他的构造函C发现了这L代码?br>
?/span>3.2中我发现了一个很有方便功能,用来完成q个功能?br>
选中目中的jre,通过右键带回菜单Q?/span>
选中Configure后就会有如下的对话框Q?br>
通过Alernate jar可以达Cؓ该项目设?/span>jre了?/span>
q样是不是很爽啊。呵c?
Viewer是逻辑对象Q或叫做领域模型Q和昄对象之间的一个桥梁。他的主要的d是Ҏ逻辑对象来填充窗体组件。一般需要三个类来完?/span>Business Object 在窗体组件中的显C。我们这里同q?/span>TableView来演C部分的功能?/span>
TableViewer的责L用特定的对象填充?/span>TableH体lg中。是我们最l在H体要看到的对象。如下图所C的一部分Q?br>?/span>IStructuredContentProvider?/span>ITableLabelProvider的实现类是用来帮?/span>TableViewer来完成这个Q务的?/span>
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
IStructuredContentProvider的Q务是“根据给定的对象Q返回一个对应的领域对象?/span>1。是通过Q?/span>public Object[] getElements(Object arg0)2Ҏ实现的?/span>2?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
ITableLabelProvider 的Q务是“返回展现领域对象的所需的图标和文字”。这两个d分别是通过public Image getColumnImage(Object element, int columnIndex);?/span>public String getColumnText(Object element, int columnIndex);q两个方法实现的。他们的传入参数都是Q?/span>Object element, int columnIndex?/span>Element表示当前行所要展现的数据对象Q?/span>columnIndex表示的当前处理的列号Q他是从零开始记的?/span>
知道了他们之间分配的职能后,我们可以看看他们是怎么协作的了。在TableView的需要显C的输入对象改变了(调用?/span>setInputҎ可以触发待显C领域对象的改变Q,q就会触?/span>TableView?/span>InputChange事gQ这时?/span>TableView׃去调用他本n?/span>refresh3Ҏ。最l会?/span>getRawChildrenҎ中调?/span>IStructuredContentProvider实现cM?/span>getElementsҎ或的一?/span>Object[]。供以后创徏Item时用。整个调用过E可以用下面?/span>strack图来表示Q?br>在更?/span>Item的时候提供每?/span>TableView需要的Text?/span>Image好了。他们最l在TableViewer?/span>doUpdateItemҎ中调?/span>ITableLabelProvider?/span>getColumnText?/span>getColumnImageҎ?/span>
下面是我CZ中的代码Q?/span>
TableLabelPrivateQ?img src="http://m.tkk7.com/images/blogjava_net/jetgeng/tablelable.gif" alt="tablelable.gif" border="0" height="359" width="895">Viewer也都是采?/span>ContentProvide?/span>LabelProvide的协作方式来工作?/span>
其他?/span>
参考文献:
1?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
Contributing to Eclipse 中文?/span> Page 2902?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
org.eclipse.jface.viewers. IStructuredContentProvider.java3?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
q个Ҏl承?/span>StructuredViewer。可参?/span>StructuredViewer.java