八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  232 随笔 :: 0 文章 :: 3000 评论 :: 11 Trackbacks

现在假设要把原来GefPractice例子里的矩形图元节点换成用椭圆形表示,都需要做哪些改动呢?很显然,首先要把原来继承RectangleFigure的NodeFigure类改为继承Ellipse:

public class NodeFigure extends Ellipse /*RectangleFigure*/{
    
}

这样修改后可以看到编辑器中的图元已经变成椭圆形了。但如果用户点选一个图元,表示选中的边框(选择框)仍然是矩形的,如图1所示:


图1 椭圆形的节点和矩形选择框

如果觉得矩形的选择框不太协调,可以通过覆盖DiagramLayoutEditPolicy的createChildEditPolicy()方法修改。缺省情况下这个方法返回一个ResizableEditPolicy,我们要定义自己的子类(EllipseResizableEditPolicy)来替代它作为返回值。

EllipseResizableEditPolicy里需要覆盖ResizableEditPolicy的两个方法,createSelectionHandles()方法决定“控制柄”(ResizeHandle)和“选择框”(MoveHandle)的相关情况,我们的实现如下:

protected List createSelectionHandles() {
    List list 
= new ArrayList();
    
//添加选择框
    
//ResizableHandleKit.addMoveHandle((GraphicalEditPart) getHost(), list);
    list.add(new MoveHandle((GraphicalEditPart) getHost()) {
        
protected void initialize() {
            
super.initialize();
            setBorder(
new LineBorder(1) {
                
public void paint(IFigure figure, Graphics graphics, Insets insets) {
                    tempRect.setBounds(getPaintRectangle(figure, insets));
                    
if (getWidth() % 2 == 1) {
                        tempRect.width
--;
                        tempRect.height
--;
                    }
                    tempRect.shrink(getWidth() 
/ 2, getWidth() / 2);
                    graphics.setLineWidth(getWidth());
                    
if (getColor() != null)
                        graphics.setForegroundColor(getColor());
                    
//用椭圆形替代矩形
                    
//graphics.drawRectangle(tempRect);
                    graphics.drawOval(tempRect);
                }
            });
        }
    });
    
    
//添加控制柄
    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.EAST);
    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.SOUTH);
    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.WEST);
    ResizableHandleKit.addHandle((GraphicalEditPart) getHost(), list, PositionConstants.NORTH);
    
return list;
}

createDragSourceFeedbackFigure()方法决定用户拖动图形时,随鼠标移动的半透明图形(即“鬼影”)的形状和颜色,因此我们覆盖这个方法以显示椭圆形的鬼影。

protected IFigure createDragSourceFeedbackFigure() {
    
//用椭圆替代矩形
    
//RectangleFigure r = new RectangleFigure();
    Ellipse r = new Ellipse();
    FigureUtilities.makeGhostShape(r);
    r.setLineStyle(Graphics.LINE_DOT);
    r.setForegroundColor(ColorConstants.white);
    r.setBounds(getInitialFeedbackBounds());
    addFeedback(r);
    
return r;
}

经过以上这些修改,可以看到选择框和鬼影都是椭圆的了,如图2所示。


图2 与节点形状相同的选择框和鬼影

点此下载工程,此工程修改自GEF应用实例中的GefPractice,目标文件的扩展名改为.gefpracticeel。

posted on 2006-06-26 23:15 八进制 阅读(3244) 评论(52)  编辑 收藏 所属分类: EclipseGEF

评论

#1楼  2006-06-27 15:30 julius [未注册用户]
您好!
再次麻烦你了,我想有这么个应用,就是在palette面板上选择某一个模型在editor中创建一个对象时,我想当鼠标在editor中点击graphicalViewer时,弹出一个选择对话框,不知怎么实现
比如说,我要在editor中用到图片,想弹出图片选择对话框,然后选择创建各种imgeFigure,

  回复  引用    

#2楼  2006-07-17 16:20 tz [未注册用户]
我想GefPractice例子的基础上,再添加一个新的节点。例如:以前的例子已经存在一个矩形的节点了,现在我想要添加一个新的三角形或圆形的节点。应该怎样做了。请回复,谢谢。
  回复  引用    

#3楼 [楼主] 2006-07-17 21:28 八进制      
模型里增加新的元素,然后增加相应的editpart和figure等等,参考矩形的代码很容易实现。
  回复  引用  查看    

#4楼  2006-07-18 11:40 tz [未注册用户]
已经实现了,谢谢您的提示
  回复  引用    

如何实现一个图片的图元呢?我急需呀
  回复  引用    

#6楼  2006-07-28 15:52 Attaguy [未注册用户]
您好!
有个问题想请教,如果图元不是椭圆(因为椭圆刚好能与矩形的四边相切),而是不规则的多边形的时候,如何实施这个多边形的各个端点被选中?即选中这个多边形时,选择的边框也是一个多边形?
一直在想办法解决这个问题,还请帮忙,谢谢!
另外,八进制有没有画直线的示例代码?这个问题也困扰我好久了
  回复  引用    

#7楼 [楼主] 2006-07-29 17:14 八进制      
我想应该是在createSelectionHandles()里想办法计算得到多边形的各个顶点。
  回复  引用  查看    

#8楼  2006-09-15 18:13 Beginner [未注册用户]
你好,我想请教一个问题:

想以Shape的例子来学习整个GMF过程包含基础建模部份
但网上怎么搜都搜不到Shape原来的模 (类别图)
我是不是可以逆向工程将原来的Shape代码生成类别图
再使用GMF导入这个类别图来实现这个例子呢?
这样做结果可以和Shape一样吗?

  回复  引用    

如何使用自定义的图元啊?发现这个确实是重要的需求。
  回复  引用    

如果这个多边形是不规则的,并且顶点多于8个.常顶点又是凹凸不平的话,能实现选择框和图形相同吗?
因为自己现在也遇到类似问题,平常RECTANGLE只有8个端点,能不能在createSelectionHandles()增加端点数目.

  回复  引用    

#11楼 [楼主] 2006-10-23 13:04 八进制      
可以的,只要通过跟踪代码在GEF里找到需要覆盖的方法就能实现,GEF是一个很灵活的框架。
  回复  引用  查看    

如何拖入一个图片进去呢?

我想用图片代替那些图无,毕竟图片要好看些,而且代表的意义要丰富些

谢谢了...
  回复  引用    

#13楼 [楼主] 2006-12-07 10:36 八进制      
在editpart的createFigure()里返回org.eclipse.draw2d.ImageFigure
  回复  引用  查看    

#14楼  2006-12-07 10:59 Kidder [未注册用户]
请问一下大侠,如果我想在一个图里面绘制一个嵌套的图,比如说在一个大图形里,我要拖放另一个图形到那个大图形上,一移动鼠标,那个图标就变小存放在那个大图形的右上角,像这样的功能怎么做啊?
谢谢大侠了
  回复  引用    

我定义了两个图元模型,都是用图片代替,现在实现图片在编辑器中的可任意拖动.

这两个模型的editorpart有一个父控制器,如下,createEditPolicies()方法中,将两个模型中的Policy安装了上去

public class CollectionEditPart extends AbstractGraphicalEditPart
{
protected IFigure createFigure()
{
Layer figure = new Layer();
figure.setLayoutManager(new XYLayout());
return figure;
}

@Override
protected void createEditPolicies()
{
installEditPolicy("frame",new FramecomXYLayoutEditPolicy());
installEditPolicy("org",new OrgcomXYLayoutEditPolicy());
}

protected List getModelChildren()
{
return ((CollectionModel)getModel()).getChildren();
}
}


但是问题来了,
installEditPolicy("frame",new FramecomXYLayoutEditPolicy());
installEditPolicy("org",new OrgcomXYLayoutEditPolicy());

在这两个Policy中,我注释掉其中任意一个 installEditPolicy();另一个图片在editor中就可以随意拖动,但是两个同时要求满足随便拖动的功能就不行,这是为什么呢?
  回复  引用    

#16楼 [楼主] 2006-12-12 13:42 八进制      
kidder: 你要修改大图形的layout,和相应的editpolicy。
陌上飘尘: 我建议你用一个xylayouteditpolicy处理,因为两个图元都是随意拖动。
  回复  引用  查看    

#17楼  2006-12-13 03:20 Ziying [未注册用户]
你好, 八进制
我现在正在做一个Eclipse的plugin, 结合GEF和UML的功能.既,通过user给的图形和input operator 来 generate code.
目前GEF part 的基本形态我都差不多完成了.

但是,在图形之间的连接还不完善.
我希望output能从指定的图形上方中间位置出来. input要连接到图形左边或者右边.
请问, 有什么办法可以做到这些???
  回复  引用    

#18楼  2006-12-14 10:30 jacky9881 [未注册用户]
我想问一下,如何让Figure显示的文字能支持换行。
  回复  引用    

#19楼 [楼主] 2006-12-14 10:30 八进制      
使用自定义的anchor,你可以参考ChopboxAnchor的实现
  回复  引用  查看    

#20楼 [楼主] 2006-12-14 10:32 八进制      
To jacky9881: 见http://www.cnblogs.com/bjzhanghao/archive/2006/03/23/356547.html
  回复  引用  查看    

#21楼  2007-03-20 10:18 Beginer [未注册用户]
我有个问题,没有思路,请执教。
我想设计一个类似与VE的可视化界面设计工具,有两个想法,一是自己用draw2D绘制各种控件,一是借助SWT来绘制,目前觉得SWT比较合适,可是如何将SWT与GEF结合使用呢?
  回复  引用    

#22楼  2007-05-17 14:31 rock [未注册用户]
@tz
我在3.2版本下怎么运行不了这个例子?
  回复  引用    

#23楼  2007-12-04 11:40 zhou_zch [未注册用户]
我想用图片代替图元,我模型是这门定义的,可是不行!
八进制老大给我看下,该怎么写!
public class ImageModel extends AbstractModel{
private Image image = new Imag(null,"icons/example.gif");
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
}
  回复  引用    

#24楼 [楼主] 2007-12-04 16:41 八进制      
用org.eclipse.draw2d.ImageFigure
  回复  引用  查看    

#25楼  2007-12-12 22:10 chad [未注册用户]
你好, 八进制,
我拿原本的跟你修正过的比对后,发现似乎不只是只改extends Ellipse
以下这method也需要修正,

public NodeFigure() {
this.rectangleFigure = new RectangleFigure();
this.label = new Label();
this.add(rectangleFigure);
this.add(label);
}
也许对您来说觉得很理所当然,但说清楚些对新手是莫大福音
还有希望能提供一个范例文件同时包含椭圆形跟矩形,
否则直接把矩形改成圆形,如果新手要实做两种时,常常很容易搞混
例如我的问题是Diagram class中要同时处理椭圆形跟矩形
addNode是这样写吗??

public void addNode(Node node) {
nodes.add(node);
fireStructureChange(PROP_NODE, nodes);
}

public void removeNode(EllipseNode ellipseNode) {
nodes.remove(ellipseNode);
fireStructureChange(PROP_NODE, ellipseNode);
}

public void addNode(EllipseNode ellipseNode) {
nodes.add(ellipseNode);
fireStructureChange(PROP_NODE, ellipseNode);
}

public void removeNode(Node node) {
nodes.remove(node);
fireStructureChange(PROP_NODE, nodes);
}


这是我这新手拜读八进制大大的心得和遇到的瓶颈,
相信这些小修正能让新手学习更得心应手


  回复  引用    

#26楼 [楼主] 2007-12-13 09:39 八进制      
谢谢你的热心帮助,这也是我尽量提供源代码的原因:如果文中有写错或遗漏的地方,通过查看源代码多数也能得到解决。
  回复  引用  查看    

#27楼  2007-12-13 15:13 chad [未注册用户]
@八进制
那我的问题是Diagram class 中 要同时实做椭圆形跟矩形
是应该addNode(Node node); addNode(EllipseNode ellipseNode);
然后都是放到nodes这个list中

还是addNode(Node node);addEllipseNode(EllipseNode ellipseNode);
放到不同的list中呢? 这问题让我困惑很久,麻烦您提点,谢谢。


  回复  引用    

#28楼 [楼主] 2007-12-13 19:38 八进制      
我觉得都可以
  回复  引用  查看    

#29楼  2008-03-05 21:30 fengliang [未注册用户]
如何实现图片代替图元的拖拿,能给个详细的例子程序吗!谢谢!!!
  回复  引用    

#30楼 [楼主] 2008-03-06 18:08 八进制      
矩形图元用的是RectangleFigure,图片图元只要改为用ImageFigure就可以了。
  回复  引用  查看    

#31楼  2008-03-12 14:25 fengliang [未注册用户]
用ImageFigure如何增加图片的路径,只需要修改视图吗?
  回复  引用    

#32楼 [楼主] 2008-03-14 00:41 八进制      
ImageFigure#setImage(yourImage)即可,Image对象可从图片文件创建得到,记得用过要dispose()
  回复  引用  查看    

#33楼  2008-03-17 14:50 baozi [未注册用户]
八进制 请问.我现在做bpel流程得图形编辑器,, 遇到了一个技术难点,就是在sequence容器(复杂性活动)中,容器为顺序布局,选中子图片点击容器任意位置,就会排在最后,, 现在想能实现 :在两个子图片之间得箭头连线上点击,将图片加在点击得位置上 ,, 请问应该怎么做?
我不想重写布局方式,, 跟踪了一下 发现GMF是通过getcommand方法获取鼠标点击部分得命令. 我想用一个命令, 能将选中得子图片位置在容器里添加,然后调用refreshchild来实现.
请问 能有什么命令实现 将子活动加在容器活动得相应位置上呢? 是否也要写自己得request??请各位高手指导下 我非常苦恼..谢谢!
  回复  引用    

#34楼 [楼主] 2008-03-18 13:38 八进制      
大概思路:首先程序需要有一个变量跟踪当前选中的子图形,然后覆盖连线的editpart的getCommand()货performRequest()方法,在这里把这条连线删除,如果选中子图形原来有连线也删除,再创建两条新连线,分别连入和连出选中的子图形,这样就实现了让选中子图形位于连线位置了。需要的话再调用容器editpart的refresh()方法。
  回复  引用  查看    

#35楼  2008-03-19 20:56 baozi [未注册用户]
八进制,因为子图片之间的连线 是我直接继承PolylineConnection建立的一个类的对象,所有没有editpart 。
那如果我想点击容器中已有的子图片,然后将选中的子图片插在他后面,
这样 照你的思路 是不是就是说 先把已有子图片原有的线删掉 再添加两条连线连接选中子图形 刷新一下 就能排在后面了?
可是refresh()方法是利用对比getModelChildren与getChildren的不同来进行刷新的 这样的话 新加入图片的位置 能在getModelChildren里面得到修改吗?
  回复  引用    

#36楼 [楼主] 2008-03-30 17:18 八进制      
这要看你是怎样实现getModelChildren()方法了,只要保证这个方法返回的是排序后你需要的子元素列表即可。
  回复  引用  查看    

#37楼  2008-04-08 20:07 baozi [未注册用户]
@八进制
八进制, 我实在是很不好意思 老问你这些你看来应该很简单得问题,
可是我跟踪了一周得代码,还是不明白。。
我发现在容器中加入子元素时,调用CreateElementCommand得doDefaultElementCreation方法,在里面使用EMFCoreUtil.create方法,往容器得FeatureMap里面加入子元素。
我就想改写他的create方法,将新建得元素位置改变。但是,问题就是:
首先,FeatureMap里定义得是相同子元素得集合,而我要把容器里面container.eContents()里面得子元素位置改变,现在就不知道怎么做了。因为eContents里面是不让做add操作得。。 该怎样改变所有子活动得位置?
然后,问题二是,应该用什么方法改变容器对应模型里面子活动得位置?因为我需要模型对应得bpel文件,能够正确得反映他们得位置顺序。在EMFCoreUtil.create里面 子活动是顺次加到最后得。那插入子活动之后得模型要怎么才能改变?
  回复  引用    

#38楼  2008-04-08 20:13 baozi [未注册用户]
还想问一下,就是refreshchildren方法里面,getModelChildren()方法里面取到得modelchildren 是从container.eContents()里面取得吗? 谢谢
  回复  引用    

#39楼 [楼主] 2008-04-10 00:20 八进制      
一般getModelChildren()是自己实现的,所以不必通过eContents()方法,用自己在父节点类中定义的方法可取到。不知道我是否理解了你的问题。
  回复  引用  查看    

#40楼  2008-04-10 10:18 baozi [未注册用户]
@八进制
非常谢谢解答,那么晚了还来看看。谢谢!
我理解了你说得实现getModelChildren()来返回排序后需要的子元素列表得方法了,但是这样容器模型对应得bpel文件里面保存得,不还是位置没有变化得子元素列表吗?(因为我需要符合实际位置的.bpel文件)。还是说 生成的.bpel文件是根据视图层进行相应改变的? 我想在插入子活动时修改容器模型里面的子活动列表,这样生成的bpel文件才会对应一致起来吧?
  回复  引用    

#41楼 [楼主] 2008-04-14 16:59 八进制      
对不起,我有点lost了。你看到的editor里的视图应该是模型的反映,所以只要正确处理好模型,并且这个反映是准确的,就应该没有问题。如果有问题就可以在这两个方面找。
  回复  引用  查看    

#42楼  2008-04-15 10:02 baozi [未注册用户]
@八进制
对,我得问题就是 用什么命令或是手段 来改变容器模型里面子活动的排列顺序呢。。? 我就是一直没找到改变子活动模型在父容器里面对应位置的方法。 谢谢解答。
  回复  引用    

#43楼 [楼主] 2008-04-16 10:41 八进制      
这样行不行:
Activity act = parent.getChildren().get(K);//get the Kth child activity
parent.getChildren().add(0, act);//insert the activity to the beginning

  回复  引用  查看    

#44楼  2008-06-03 19:38 cnfree [未注册用户]
如果在椭圆外部选择,虽然是椭圆选择框,但是点在椭圆外的矩形区域,依然会获得焦点吧,如果只能点在椭圆区域获得焦点?
  回复  引用    

#45楼 [楼主] 2008-06-12 21:07 八进制      
@cnfree
你说的这个问题答案是肯定的。虽然没实际做过,但我认为通过覆盖椭圆的findFigureAt()可以方法解决。
  回复  引用  查看    

#46楼  2008-07-23 17:03 amandalv [未注册用户]
八大哥 你好!
有个问题想请教你:
现在我想要添加一个新的三角形或圆形的节点 按照你在楼上写的方法:
模型里增加新的元素,然后增加相应的editpart和figure等等
我增加了Ellipse类 EllipsePart 和 EllipticalFigure方法
但是运行出来的结果是 将调色板上的椭圆型工具拖上画板就会失败
不知道为什么?????
我按照chad的方法加了下面代码:
public void addNode(EllipseNode ellipseNode) {
nodes.add(ellipseNode);
fireStructureChange(PROP_NODE, nodes);
}

public void removeNode(Node node) {
nodes.remove(node);
fireStructureChange(PROP_NODE, nodes);
}
但是仍然不行 你觉得是什么原因?还要改很多代码吗?我看了一下node在很多类里出现过 是不是都要把Ellipse加进去呢?
请尽快回复好吗?谢谢啦!!!
  回复  引用    

#47楼  2008-07-23 17:19 amandalv [未注册用户]
command这些类要该吗?
  回复  引用    

#48楼  2008-07-23 17:21 amandalv [未注册用户]
NodeTreeEditpart是做什么用的?不好意思 问这么傻的问题。。。
  回复  引用    

#49楼  2008-07-24 16:32 amandalv [未注册用户]
我已经搞定啦 还是得靠自己啊。。。
其实chad 说的不对 让Ellipse继承Node类,根本不需要覆写addnode方法
只可惜八大哥还附和他 搞得我想了半天 后来看了 subject例子后 恍然大悟!
  回复  引用    

#50楼  2008-07-25 10:23 amandalv [未注册用户]
总之 谢谢你 八大哥 从你的博客中我学到了很多GEF的东西!ORZ
  回复  引用    

#51楼  2008-07-25 16:23 amandalv [未注册用户]
八大哥 想问你啊 三角形在draw2d中被定义为final,那就意味着我们不能创建继承于三角形的figure了?不能创建三角形的图形了?
还有 菱形这种图元draw2d有没有自带?要用org.eclipse.draw2d.ImageFigure ?
期待大师的回答~~~
  回复  引用    

#52楼 [楼主] 2008-08-06 20:37 八进制      
@amandalv
是的,final的类都是不能继承的。如果实在需要,你可以把Triangle的代码复制下来做修改。菱形没有,我一般用Polygon实现。
  回复  引用  查看