八进制

少年壮志无烟抽

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

先简单回顾一下Request在GEF里的作用。Request是GEF里一个比较重要的角色,Tool将原始的鼠标事件转换为EditPart可以识别的请求,Request则承载了这些请求信息。举例来说,用户在调色板(Palette)里选择了创建节点工具(CreationTool),然后在画布区域按下鼠标左键,这时产生在画布上的鼠标单击事件将被CreationTool转换为一个CreateRequest,它里面包含了要创建的对象,坐标位置等信息。 EditPart上如果安装了能够处理CreateRequest的EditPolicy,则相应的EditPolicy会根据这个 CreateRequest创建一个Command,由后者实际执行创建新对象的必要操作。

GEF已经为我们提供了很多种类的Request,其中最常用的是CreateRequest及其子类 CreateConnectionRequest,其他比较常见的还有SelectionRequest,ChangeBoundsRequest和 ReconnectRequest等等。要实现一个典型的图形化应用程序,例如UML类图编辑器,这些预定义的Request基本够用了。然而各种稀奇古怪的需求我相信大家也见过不少,很多需求不太符合约定俗成的使用习惯,因此实现起来更多依赖开发人员的编码,而不是开发框架带来的便利。在这种时候,我们唯一的期望就是开发框架提供足够的扩展机制,以便让我们额外编写的代码能和其他代码和平共处,幸好GEF是具有足够的扩展性的。有点跑题了,再回到Request的问题上,为了说明什么情况下需要自定义 Request,我在前文“应用实例”里的示例应用基础上假设一个新的需求:

在Palette里增加三个工具,作用分别是把选中节点的背景颜色改变为红色、绿色和蓝色。

假如你用过Photoshop或类似软件,这个需求很像给节点上色的“油漆桶”或“上色工具”,当然在用户界面的背后,实际应用里这些颜色可能代表一个节点的重要程度,优先级或是异常信息等等。现在,让我们通过创建一个自定义的Request来实现这个需求,还是以前文中的示例项目为基础。

一、首先,原来的模型里节点(Node)类里没有反映颜色的成员变量,所以先要在Node类里添加一个color属性,以及相应的 getter/setter方法,注意这个setter方法里要和其他成员变量的setter方法一样传递模型改变的消息。仿照其他成员变量,还应该有一个静态字符串变量,用来区分消息对应哪个属性。


final public static String PROP_COLOR = "COLOR";

protected RGB color = new RGB(255255255);

public RGB getColor() {
    
return color;
}

public void setColor(RGB color) {
    
if (this.color.equals(color)) {
        
return;
    }
    
this.color = color;
    firePropertyChange(PROP_COLOR, 
null, color);
}

二、然后,要让Node的color属性变化能够反映到图形上,因此要修改NodePart里的propertyChanged()和 refreshVisuals()方法,在前者里增加对color属性的响应,在后者里将NodeFigure的背景颜色设置为Node的color属性对应的颜色。(注意,Color对象是系统资源对象,实际使用里需要缓存以避免系统资源耗尽,为节约篇幅起见,示例代码直接new Color()了)

public void propertyChange(PropertyChangeEvent evt) {
    
    
if (evt.getPropertyName().equals(Node.PROP_COLOR))//Response to color change
        refreshVisuals();
}

protected void refreshVisuals() {
    
    ((NodeFigure) 
this.getFigure()).setBackgroundColor(new Color(null, node.getColor()));//TODO cache color instances
}

三、现在来创建我们自己的Request,因为目的是改变颜色,所以不妨叫做ChangeColorRequest。它应当继承自org.eclipse.gef.Request,我们需要ChangeColorRequest上带有两样信息:1.需要改变颜色的节点;2.目标颜色。因此它应该有这两个成员变量。

import org.eclipse.gef.Request;
import org.eclipse.swt.graphics.RGB;
import com.example.model.Node;

public class ChangeColorRequest extends Request{
    
final static public String REQ_CHANGE_COLOR="REQ_CHANGE_COLOR";
    
private Node node;
    
private RGB color;

    
public ChangeColorRequest(Node node, RGB color) {
        
super();
        
this.color = color;
        
this.node = node;
        setType(REQ_CHANGE_COLOR);
    }

    
public RGB getColor() {
        
return color;
    }

    
public Node getNode() {
        
return node;
    }

    
public void setNode(Node node) {
        
this.node = node;
    }

    
public void setColor(RGB color) {
        
this.color = color;
    }
    
}

ChangeColorRequest看起来和一个JavaBean差不多,的确如此,因为Request的作用就是传递翻译后的鼠标事件。如果你看一下org.eclipse.gef.Request的代码,你会发现Request还有一个type属性,这个属性一般是一个字符串(在gef的RequestConstants里预定义了一些,如RequestConstants.REQ_SELECTION_HOVER), EditPolicy可以根据它决定是否处理这个Request。在我们的例子里,顺便定义了这样一个常量字符串REQ_CHANGE_COLOR,在后面的 ChangeColorEditPolicy里会用到它。

四、现在有一个问题,这个Request的实例应该在哪里生成?答案是在Tool里,用户在画布区域按下鼠标左键时,当前 Palette里被选中的Tool负责创建一个Request。我们现在面对的这个需求需要我们创建一种新的Tool:ChangeColorTool。我们让ChangeColorTool继承org.eclipse.gef.tools.SelectionTool,因为“上色工具”的用法和“选择工具”基本上差不多。显然,我们需要覆盖的是handleButtonDown()方法,用来告诉gef如果用户当前选择了这个工具,在画布区域按下鼠标会发生什么事情。代码如下:

import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.tools.SelectionTool;
import org.eclipse.swt.graphics.RGB;
import com.example.model.Node;
import com.example.parts.NodePart;

public class ChangeColorTool extends SelectionTool {
    
private RGB color;

    
public ChangeColorTool(RGB color) {
        
super();
        
this.color = color;
    }

    
/**
     * If target editpart is an {
@link NodePart}, create a {@link ChangeColorRequest} instance, 
     * get command from target editpart with this request and execute.
     
*/
    @Override
    
protected boolean handleButtonDown(int button) {
        
//Get selected editpart
        EditPart editPart = this.getTargetEditPart();
        
        
if (editPart instanceof NodePart) {
            NodePart nodePart 
= (NodePart) editPart;
            Node node 
= (Node) nodePart.getModel();
            
            
//Create an instance of ChangeColorRequest
            ChangeColorRequest request = new ChangeColorRequest(node, color);
            
            
//Get command from the editpart
            Command command = editPart.getCommand(request);
            
            
//Execute the command
            this.getDomain().getCommandStack().execute(command);
            
            
return true;
        }
        
return false;
    }

}

五、有了Tool,还需要用ToolEntry把它包装起来添加到Palette里。所以我们创建一个名为 ChangeColorToolEntry并继承org.eclipse.gef.palette.ToolEntry的类,覆盖createTool ()方法,让它返回我们的ChangeColorTool实例。这个ChangeColorToolEntry代码应该很容易理解:

import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.Tool;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.RGB;

public class ChangeColorToolEntry extends ToolEntry {
    
private RGB color;

    
public ChangeColorToolEntry(RGB color, String label, String shortDesc, ImageDescriptor iconSmall,
            ImageDescriptor iconLarge) {
        
super(label, shortDesc, iconSmall, iconLarge);
        
this.color = color;
    }

    @Override
    
public Tool createTool() {
        ChangeColorTool tool 
= new ChangeColorTool(color);
        tool.setUnloadWhenFinished(
false);//Switch to selection tool after performed?
        tool.setDefaultCursor(SharedCursors.CROSS);//Any cursor you like
        return tool;
    }

}

六、要把三个这样的ToolEntry添加到Palette里,当然是通过修改原来的PaletteFactory类。为节约篇幅,这里就不帖它的代码了,可以下载并参考示例代码PaletteFactory.java里的createCategories()和 createColorDrawer()方法。

到目前为止,ChangeColorRequest已经可以发出了,接下来要解决的问题是如何让EditPart处理这个请求。

七、我们知道,gef里任何对模型的修改都是通过command完成的,因此一个ChangeColorCommand肯定是需要的。它的execute()方法和undo()方法如下所示:

public class ChangeColorCommand extends Command{

    
private RGB oldColor;
    

    @Override
    
public void execute() {
        oldColor 
= node.getColor();
        node.setColor(color);
    }
    
    @Override
    
public void undo() {
        node.setColor(oldColor);
    }
}

八、EditPolicy负责接收所有的Request,所以还要创建一个ChangeColorEditPolicy。在下面列出的代码里,你会看到我们定义了一个新的“Role”字符串,过一会儿我们在EditPart上安装这个EditPolicy的时候要以这个字符串作为Key,以避免覆盖EditPart上已有的其他EditPolicy。

import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.AbstractEditPolicy;
import org.eclipse.swt.graphics.RGB;

import com.example.model.Node;

public class ChangeColorEditPolicy extends AbstractEditPolicy {
    
final static public String CHANGE_COLOR_ROLE = "CHANGE_COLOR_ROLE";

    @Override
    
public Command getCommand(Request request) {
        
//Judge whether this request is intersting by its type
        if (request.getType() == ChangeColorRequest.REQ_CHANGE_COLOR) {
            ChangeColorRequest theRequest 
= (ChangeColorRequest) request;
            
            
//Get information from request
            Node node = theRequest.getNode();
            RGB color 
= theRequest.getColor();
            
            
//Create corresponding command and return it
            ChangeColorCommand command = new ChangeColorCommand(node, color);
            
return command;
        }
        
return null;
    }
}

九、最后还是回到EditPart,前面在第二个步骤里我们曾经修改过的NodePart里还有最后一处需要添加,那就是在installEditPolicies()方法里添加刚刚创建的ChangeColorEditPolicy:

protected void createEditPolicies() {
    
    
    
//Add change color editpolicy
    installEditPolicy(ChangeColorEditPolicy.CHANGE_COLOR_ROLE, new ChangeColorEditPolicy());
}

现在我们已经完成了所有必要的修改,来看一下运行结果。


总结一下,需要创建的类有:ChangeColorRequest, ChangeColorTool, ChangeColorToolEntry, ChangeColorCommand, ChangeColorEditPolicy;需要修改的类有:Node, NodePart, PaletteFactory。在实例项目里,为了方便大家浏览,所有新创建的类都放在com.example.request包里,实际项目里还是建议分别放在对应的包里。

下载示例代码(在eclipse3.2.1和gef3.2下编译通过)

posted on 2007-06-21 23:35 八进制 阅读(4903) 评论(71)  编辑 收藏 所属分类: EclipseGEF

评论

#1楼  2007-06-29 00:17 yy [未注册用户]
哈哈 不错 :)
沙发!!!
  回复  引用    

#2楼  2007-07-04 11:59 谢谢了 [未注册用户]
谢谢了
  回复  引用    

#3楼  2007-07-04 15:34 幸运星 [未注册用户]
求助...

怎么给图元加单击事件啊???

找了好长时间没找到,.....


  回复  引用    

#4楼  2007-07-06 09:34 hehui0912 [未注册用户]
l楼上的:  你可以继承selectionTool处理鼠标事件。
  回复  引用    

#5楼  2007-07-06 09:35 hehui0912 [未注册用户]
gef自带的request是如何被调用的?在什么时候?被谁调用?是selectionTool吗?
  回复  引用    

#6楼  2007-07-06 09:55 hehui0912 [未注册用户]
在相应的editpart里这样处理:
public void performRequest(Request req) {
if(req.equals("open"))
{}
else
if(req.equals("direct edit"))
{}


}
  回复  引用    

#7楼  2007-07-06 10:01 hehui0912 [未注册用户]
我自己搜集的资料:



When the user causes an event, a
Tool object sends a Request to the selected EditPart. This EditPart uses a List of
EditPolicys to create a Command that updates the Model class. When the Model
changes, it fires a PropertyChangeEvent. After receiving this event, the EditPart
modifies the component’s Figure (View) by invoking one of its refresh() meth-ods.



详细的事件流程:
1. 用户点击相关可视化控件,发出鼠标或者键盘的事件.
2. SWT Control 捕获到键盘或者鼠标的事件?参考SWT的Canvas接口(SWT Events).
3. 然后将事件传递到EditPartViewer中进行处理?参考GraphicalViewer和IFigure接口.(实现类为GraphicalViewerImpl,Figure类) Draw2D系统中的LightWeightSystem,Events.
4. 在EditPartViewer中处理完后,然后继续将事件传递到EditDomain中处理?参考EditDomain类,
5. 在EditDomain类处理完成后,继续将事件传递到Active Tool来处理?参考SelectionTool,SelectEditPartTracker类 (他们superClass为TargetingTool类)
6. 至此事件的传递完成.接着由Tool产生Request接口类型的request?参考SelectionRequest类.
7. EditPart来处理产生的request?参考AbstractEditPart中的performRequest()方法, AbstractGraphicalEditPart类.
8. 在EditPart中安装了EditPolicy?参考GraphicalNodeEditPolicy类
9. 在EditPolicy类中创建若干Command, 其中关于redo,undo操作的command 形成CommandStack(实际上就是一个ArrayList),?参考CompoundCommand类.
10. 到一定的时候执行Command中的execute方法.



本流程针对http://jtauber.com/2004/gef/gef.zip中的pt1来说:
1. 系统首先打开一个EditorPart, 然后开始一些初始化操作:
2. EditorPart初始化一个模型Diagram;
3. 在Diagram这个model中PropertyChangeListener, PropertyChangeSupport这些类的存在就是为了监听模型的改变,如果模型改变了,那么要告知模型对应的editPart,让editPart执行相应的操作. 我们可以注意到在editPart类的代码中有PropertyChangeEvent, PropertyChangeListener类的存在,这些代码的存在就是对侦听到的事件进行处理;
4. EditorPart初始化一个setEditDomain(),将EditDomain联系起来;
5. EditorPart通过SetInput() 将IEditorInput联系起来, 可以将生成的Diagram模型放入到IEditorInput中来;
6. EditorPart要负责生成一个editPartViewer. editPartViewer的主要作用是:要知道他周围的所有的editParts, 所有的viewPart, 同时将用户点击的热点区域映射到editPart, 由editPart 创建viewPart.下面开始讲解editPartViewer的生成过程;
7. EditorPart的configureGraphicalViewer()方法中首先得到EditPartViewer,然后做下面的一些设置:
getGraphicalViewer().setRootEditPart(new ScalableFreeformRootEditPart()) ----设置顶级别的EditPart,
getGraphicalViewer().setEditPartFactory(new PartFactory())----针对每一个模型制定一个editPart,
PartFactory这个类的作用是 针对不同的model给不同的editPart.
到此就达到了一个目的: 每一个model 一一对应起一个edtipart. 于是editpart就可以操作每一个model, 每一个model的改变首先告知对应的editPart, 由editpart来负责通知viewPart的更改;
8. EditorPart的initializeGraphicalViewer()方法的
getGraphicalViewer().setContents(this.diagram);----含义:
根据前面的
configureGraphicalViewer()中的setEditPartFactory()方法,不同的model得到不同的editPart, editorPart将diagram模型植入到editPartViewer中的同时,将diagram模型对应的editpart(DiagramEditPart)置为顶级别的editPart, 然后根据DiagramEditPart中的一些方法getModelChildren()得到整个模型,再根据各自的模型得到对应的editPart(例如NodePart),这些editPart中有createFigure(),createEditPolicies(), 完成各个viewPart的创建.到此时为止editPartViewer构造完成.
9. 总体观察: 通过editorPart完成了editPartViewer的整体构造.





GEF应用程序的工作方式如下: EditPartViewer接受用户的操作
,例如节点的选择、新增或删除等等,每个节点都对应一个EditPart对象,
这个对象有一组按操作Role分开的EditPolicy,
每个EditPolicy会对应一些Command对象,Command最终对模型进行直接修改。
用户的操作转换为Request分配给适当的EditPolicy,
由后者创建适当的Command来修改模型,这些Command
会保留在EditDomain(专门用于维护EditPartViewer、
Command等信息的对象,一般每个Editor对应唯一一个该对象)
的命令堆栈里,用于实现撤消/重做功能。


用户的操作会被当前工具(缺省为选择工具SelectionTool)转换为请求(Request),请求根据类型被分发到目标EditPart所安装的EditPolicy,后者根据请求对应的角色来判断是否应该创建命令并执行。


Requests

  回复  引用    

#8楼  2007-07-06 15:27 yy [未注册用户]
楼上的好强:)3X
  回复  引用    

#9楼  2007-07-07 14:26 幸运星 [未注册用户]
@hehui0912


selectionTool 是要继承一个类,可不可以通过实现借口来完成单击啊?
  回复  引用    

#10楼  2007-07-09 10:55 幸运星 [未注册用户]
GEF 怎么把画布生成图片啊????
  回复  引用    

#11楼  2007-07-09 21:33 jiezi [未注册用户]
我做一个流程编辑器,里面有泳道、活动图元和正交迁移线,如果给用户提供一个按钮实现自动规整布局功能,里面的策略应该怎么定(迁移线不交叉?不穿过图元?)这样实现起来难度大么?(自动布局后用户仍可以拖动修改)
请大大指教
bit506@163.com
  回复  引用    

#12楼  2007-07-10 14:35 hehui0912 [未注册用户]
在相应的editpart里这样处理:
public void performRequest(Request req) {
if(req.equals("open"))
{}
else
if(req.equals("direct edit"))
{}


}
  回复  引用    

#13楼  2007-07-10 15:24 jiezi [未注册用户]
请问下自动布局就调DirectGraphLayout或它的子类CompoundDirectedGraphLayout?自己需要定义规则么,怎样定义,比如editor里嵌套2层,外层ToolLayout,里层xyLayout,要对所有的最里层自动布局
  回复  引用    

#14楼 [楼主] 2007-07-10 15:43 八进制      
应该不支持这些规则。
  回复  引用  查看    

#15楼  2007-07-10 15:43 hehui0912 [未注册用户]
我最新修改的代码,在这里下,是eclipse过程,自己看看,我做了一些扩展。http://www.blogjava.net/Files/hehui0912/gefpracticc.zip
  回复  引用    

#16楼  2007-07-10 15:46 hehui0912 [未注册用户]
我想问问 EditPolicy 的role 有什么作用,除了作为一个标识之外,还有什么作用?
  回复  引用    

#17楼  2007-07-10 15:48 hehui0912 [未注册用户]
EditPolicy 是如何被调用的?比如ComponentEditPolicy?
  回复  引用    

#18楼  2007-07-10 16:04 hehui0912 [未注册用户]
我想做个图像化的编辑器,就象dreamweaver一样的,在设计页面,有光标在闪动,也可以直接输入文字,在gef中有可能实现吗?谢谢!
  回复  引用    

#19楼  2007-07-11 10:40 jiezi [未注册用户]
请问下,Model的层次一定要一定要和Figure层次一致么,比如您的subject例子,能否在model层把subject和attribute都作为diagram的子,只是在EditPart层人为地把attribute作为subject的子展现在figure层,貌似说得有点乱。。
  回复  引用    

#20楼  2007-07-11 11:15 hehui0912 [未注册用户]
public class Diagram extends Element
public class Node extends Element implements IPropertySource


你看看这个就知道了,都是Element 的子类,而node不是Diagram 的子类。



  回复  引用    

#21楼  2007-07-11 11:22 hehui0912 [未注册用户]
最主要的就是DiagramPart中的这个方法,决定了Diagram figure 中可以放置的figure是 NodeFigure,而model之间可以不必是父子关系的。
protected List getModelChildren() {
return ((Diagram) this.getModel()).getNodes();
}
  回复  引用    

#22楼  2007-07-11 11:29 jiezi [未注册用户]
多谢ls的大哥
  回复  引用    

#23楼  2007-07-11 11:31 hehui0912 [未注册用户]
最好自己写个看看 就知道了
  回复  引用    

#24楼  2007-07-11 11:33 jiezi [未注册用户]
对了,我说的层次关系不是继承层次哦,是指的在Diagram类里同时有addSubject()和addAttribute()
  回复  引用    

#25楼  2007-07-11 11:38 hehui0912 [未注册用户]
你要这二个方法做什么呢? addSubject(),addAttribute()




  回复  引用    

#26楼  2007-07-11 11:49 hehui0912 [未注册用户]
主要是这个方法
protected void refreshVisuals() {




Node node = (Node) getModel();
Point loc = node.getLocation();
Dimension d=node.getSize();


Rectangle rectangle = new Rectangle(loc, d);

((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), rectangle);

}


那你如何调用  ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), rectangle); 这个呢?
  回复  引用    

#27楼  2007-07-11 11:53 jiezi [未注册用户]
类似,大致就是要实现一个Editor内,先是Diagram包含subject,subject包含attribute;然后在UI展现上通过一个Action可以拿掉中间那层subject;而且通过这个Action可以方便地在有subject的3层次和无subject的2层次之间切换
这个用一套Model实现,就会存在model的层次该怎么设计的问题了。。
其实也在设计阶段,语言组织有点乱- -!!!
  回复  引用    

#28楼  2007-07-11 11:54 jiezi [未注册用户]
ls能留个联系方式么,方便向您请教,呵呵
  回复  引用    

#29楼 [楼主] 2007-07-11 13:53 八进制      
@hehui0912
dreamweaver那样的图形化界面gef可以做到,eclipse的ve就比较接近这种,问题是工作量比较大。
  回复  引用  查看    

#30楼  2007-07-11 14:16 hehui0912 [未注册用户]
我也不懂啊
我的qq 是81553652
  回复  引用    

#31楼  2007-07-11 14:16 jiezi [未注册用户]
哇,八进制大大,帮我看看,就是你那个subject例子的话,如果只有attribute之间有迁移线,能否通过editor的action控制subject Figure的隐藏和显示
  回复  引用    

#32楼  2007-07-11 14:37 hehui0912 [未注册用户]
我的还要求在界面上可以输入文字,可以回车,gef可以做到吗?
  回复  引用    

#33楼  2007-07-12 09:16 hehui0912 [未注册用户]
@八进制
我想作的比ve还要好一点,要可以输入文字,有光标,可以支持回车等。这个可以吗?谢谢了
  回复  引用    

#34楼 [楼主] 2007-07-14 13:16 八进制      
我原来以为ve是可以直接输入文字的..看来记错了,因为很少用。在图形界面上输入文字就是实现direct edit功能,应该也不难实现,回车我一般用ctrl+enter代替。
  回复  引用  查看    

#35楼 [楼主] 2007-07-14 13:18 八进制      
@jiezi
用action控制figure的显示不难啊,setVisible(false)就可以了。
  回复  引用  查看    

#36楼  2007-07-16 09:14 jiezi [未注册用户]
这个问题比较特殊,如果有subject层,diagram层用的是toollayout;
如果取消subject层,diagram层要自动换到xylayout。

  回复  引用    

#37楼  2007-07-18 14:40 yy [未注册用户]
八进制,你好!
请问ECLIPSE的插件开发如何用JUNIT做测试呢?
公司急用,交给我的任务,不知怎么完成啊,网上找了一阵也没找到,急啊。
先谢谢了哈!
  回复  引用    

#38楼 [楼主] 2007-07-18 22:10 八进制      
测试方面我不熟,不过eclipse集成了junit测试工具,我曾写过一些简单的介绍,如http://www.cnblogs.com/bjzhanghao/archive/2004/07/29/28309.html;另外eclipse的tptp好像是专门为测试做的。
  回复  引用  查看    

#39楼  2007-07-20 15:41 hehui0912 [未注册用户]
如何来使用protected Command createAddCommand(EditPart child, Object constraint)? 我现在要用这个 方法.
  回复  引用    

#40楼  2007-07-21 15:55 老蒋 [未注册用户]
八进制我在打包RCP程序的时候打完后运行报错,帮看下吧!!~`
eclipse.buildId=unknown
java.version=1.5.0_06
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=zh_CN
Command-line arguments: -os win32 -ws win32 -arch x86

org.osgi.framework.BundleException: The activator com.webrage.workflow.workfloweditor.WorkflowEditorPlugin for bundle workfloweditor is invalid

  回复  引用    

#41楼  2007-07-23 08:24 hehui0912 [未注册用户]
@hehui0912
这个我已经知道可
  回复  引用    

#42楼  2007-07-23 08:25 hehui0912 [未注册用户]
在gef中如何实现动态弹出式菜单?
  回复  引用    

#43楼 [楼主] 2007-07-23 23:03 八进制      
@老蒋
看不出来,invalid的可能很多,感觉需要更多信息。
  回复  引用  查看    

#44楼  2007-07-24 16:13 hehui0912 [未注册用户]
我现在有个TableFigure,里面有很多Children, 如何在TableFigure改变大小的时候,里面的figure也跟着同样的比例改变大小呢?
  回复  引用    

#45楼  2007-07-25 14:12 hehui0912 [未注册用户]
r如何在初始化的时候在TableFigure中就加入child呢?
  回复  引用    

#46楼  2007-07-30 22:00 老蒋 [未注册用户]
@八进制

我已经找到错误了,是打包的时候顺序搞错了.....


  回复  引用    

#47楼  2007-07-30 22:09 老蒋 [未注册用户]
八进制您好!!~`

俺又来提问题了!~~

我想在ECLIPSE上把那个画完的图打出来,

也可以给他保存到一张图片上!~~~

这样该怎么实现啊!~~~

给点思路或帮找点小例子..... 这个东西一直没找到...

  回复  引用    

#48楼 [楼主] 2007-08-01 00:06 八进制      
请看http://www.cnblogs.com/bjzhanghao/archive/2007/08/01/838278.html
  回复  引用  查看    

#49楼  2007-08-02 17:16 zjq [未注册用户]
@hehui0912
详细的事件流程:
"1. 用户点击相关可视化控件,发出鼠标或者键盘的事件.
2. SWT Control 捕获到键盘或者鼠标的事件?参考SWT的Canvas接口(SWT Events).
3. 然后将事件传递到EditPartViewer中进行处理?参考GraphicalViewer和IFigure接口.(实现类为GraphicalViewerImpl,Figure类) Draw2D系统中的LightWeightSystem,Events.
4. 在EditPartViewer中处理完后,然后继续将事件传递到EditDomain中处理?参考EditDomain类,
5. 在EditDomain类处理完成后,继续将事件传递到Active Tool来处理?参考SelectionTool,SelectEditPartTracker类 (他们superClass为TargetingTool类)
6. 至此事件的传递完成.接着由Tool产生Request接口类型的request?参考SelectionRequest类.
7. EditPart来处理产生的request?参考AbstractEditPart中的performRequest()方法, AbstractGraphicalEditPart类.
8. 在EditPart中安装了EditPolicy?参考GraphicalNodeEditPolicy类
9. 在EditPolicy类中创建若干Command, 其中关于redo,undo操作的command 形成CommandStack(实际上就是一个ArrayList),?参考CompoundCommand类.
10. 到一定的时候执行Command中的execute方法.""""""


那我要是想把上面的流程反过来执行的话,即,通过修改模型来实现创建一个Node,然后让它再显示在view当中去~~应该是什么顺序啊????

  回复  引用    

#50楼  2007-08-03 17:11 任我行 [未注册用户]
DiagramPart中,performRequest(Request req)好像无法执行。请问如何在捕获鼠标双击事件,目的是打开窗口,修改Diagram的属性。谢谢!
  回复  引用    

#51楼 [楼主] 2007-08-03 18:29 八进制      
performRequest()应该可以执行的。
  回复  引用  查看    

#52楼  2007-08-07 16:09 金鹏 [未注册用户]
请问你一个问题:GEF是如何将系统动作(比如鼠标移动等)封装成Request的?可否用一个例子结合GEF中的源代码说明,万分感谢!!如果你知道答案请发我邮箱吧,jinpeng198484@126.com,谢谢!
  回复  引用    

#53楼 [楼主] 2007-08-14 09:19 八进制      
见org.eclipse.gef.tools.CreationTool#handleButtonUp()
  回复  引用  查看    

#54楼  2007-08-14 17:11 老蒋 [未注册用户]
@八进制

谢谢了.....图片问题搞定了.呵呵

又有新问题....

图员怎么加 复制 粘贴功能啊???

有系统提供的吗??
  回复  引用    

#55楼  2007-08-28 23:15 speditor [未注册用户]
不知在GEF中有没有与Save相对应的Request,还是应该自己定义。
  回复  引用    

#56楼 [楼主] 2007-08-29 11:43 八进制      
@speditor
应该没有
  回复  引用  查看    

#57楼  2007-09-13 15:12 Whisper [未注册用户]
你好!请教个问题。
我在做一个流程编辑器,出了缺省的connection实现外,我还需要建立其他不同含义的connection实现。
一、新connection我尝试直接用
new ConnectionCreationToolEntry(label, tooltip, factory,descriptor, null);
来实现。但是在节点的policy里(如下)
public class NodeGraphicalNodeEditPolicy extends GraphicalNodeEditPolicy {
protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
String connectionType = (String) request.getType();
}
}
中,新connection和原connection获取到的connectionType都一样。而且好像没有办法区分开到底是哪个connection被选中了?!

二、我也试图单独建立ConnectionCreationTool、ConnectionToolEntry、Request类,然后手动加载到pattern中。
不知下面的代码有无问题,以及我下一步要如何继续?

CreationFactory factory= new ElementCreationFactory(Constant.TimeLimitConnection_NAME,
editor);

ToolEntry entry = new ConnectionCreationToolEntry(Constant.TimeLimitConnection_NAME,
"Creates a TimeLimit Connection", factory, null, null);
entry.setToolClass(TimeLimitConnectionTool.class);

  回复  引用    

#58楼  2007-09-13 15:30 Whisper [未注册用户]
补充一下:
policy、command等类我都建立了。
因为connection的性质和你提供的例子有所不同,所以我不太明白如何实现自定义的connection。
在网上搜索了很久,也没有找到有多个connection实现的案例 :(

  回复  引用    

#59楼  2007-09-14 09:10 Whisper [未注册用户]
续:
查到了‘request.getNewObjectType()’可以区分被选择的connection。
不过用方法二来执行,这个返回的type为空(不明白少了什么设置了),只好用方法一(好像之前没有说清楚,这个方式的参数都配置在plugin.xml中)了。

另外:找到一个采用多个connection的开源项目Jupe(http://jupe.binaervarianz.de)
  回复  引用    

#60楼  2007-11-19 21:59 aphrodite [未注册用户]
sequence容器中怎样给子图片添加点击监听?
八进制你好,我在做sequence容器布局时,试图点击sequence中子图片,实现监听来插入新图片,
可是 原本的sequence容器是垂直布局,子图片上没法点击, 请问 要能添加点击监听功能,应该怎么实现? 能给一下指导吗?
  回复  引用    

#61楼  2008-01-24 13:29 zhp_std [未注册用户]
我现在在做的东西要求是能单击就能输入文字了,而不是像DirectEdit一样要双击进去,而且不仅要能直接输入文字,还要可以放其他的Figure像Label一样的,我现在不知道怎么做?好象有个FlowPage之类的东西,不知道哪位高人,做过这样一来的东西呢?指点一下,方向也可以。
  回复  引用    

#62楼 [楼主] 2008-01-27 16:48 八进制      
单击输入可以在performRequest()里实现,request类型可能是SelectionRequest。FlowPage实现换行功能参见http://bjzhanghao.cnblogs.com/archive/2006/03/23/356547.html
  回复  引用  查看    

#63楼  2008-01-28 13:47 zhp_std [未注册用户]
非常感谢老大的回话,对我很有帮助。
还有就是我的意图是跟18楼的是一样的,就是能像dreamweaver一样,能直接输入文字,还可以存放其他的Figure,您说是可以做到的,但是,我还是没有头绪,用到的布局肯定不是XYLayout,而应该是FlowLayout吧?还有就是,要能输入文字,而不是DirectEdit要怎么弄呢?因为DirectEditr它里面最终的实现还是SWT里面的一个Text控件,那还是装不了其他的Figure?希望老大能在百忙中再给点意见哦
  回复  引用    

#64楼  2008-06-25 18:28 jy [未注册用户]
八进制你好,我也是看了你很多文章成长起来的.我挺崇拜你的.很厉害.
我现在遇到了个问题~ 我做的开发项目是不带Palette的
所以根本没办法触发到 protected Command getCreateCommand(CreateRequest request) 这个方法,所以就无法得到request对象,最终无法得到X,Y的位置. 我现在是用一个List代替Palette的角色,直接把左面的东西从List里面拖拽到面版上,但每次只能放在做上角 也就是(0,0)的位置.
请问如何解决呢. 拖拽对象触发的event对象里的 x,y 并不是那面版的位置,而是整个屏幕的位置.请指教.
如果可以的话 加我的QQ:317045633 ,MSN:jy02149522@eyou.com
谢谢了~ 如果哪为朋友看到这贴 也请能帮助我. 小弟谢谢了
  回复  引用    

#65楼  2008-07-03 16:31 ccg [未注册用户]
GMF里,自定义Request用上面的办法做了一边,好像不行啊,是不是GMF自己单独有一套机制
  回复  引用    

#66楼 [楼主] 2008-07-11 23:03 八进制      
@ccg
GMF上我没试过。既然GMF是基于GEF的,应该是同样适用的才对。
  回复  引用  查看    

#67楼 [楼主] 2008-07-11 23:07 八进制      
@zhp_std
我想还是要借助DirectEdit的方式实现,只是做一些改进,让用户看不出来实际上是在一个swt的Text控件里输入,例如隐藏Text控件的边框等等。建议你研究一下VE实现这部分的代码。
  回复  引用  查看