八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  235 随笔 :: 0 文章 :: 3088 评论 :: 14 引用

当一个GEF应用程序实现了大部分必需的业务功能后,为了能让用户使用得更方便,我们应该在易用性方面做些考虑。从3.0版本开始, GEF增加了更多这方面的新特性,开发人员很容易利用它们来改善自己的应用程序界面。这篇帖子将介绍主要的几个功能,它们有些在GEF 2.1中就出现了,但因为都是关于易用性的而且以前没有提到,所以放在这里一起来说。( 下载示例代码

可折叠调色板

在以前的例子里,我们的编辑器都继承自GraphicalEditorWithPalette。GEF 3.0提供了一个功能更加丰富的编辑器父类:GraphicalEditorWithFlyoutPalette,继承它的编辑器具有一个可以折叠的工具条,并且能够利用Eclipse自带的调色板视图,当调色板视图显示时,工具条会自动转移到这个视图中。

flyoutPalette.gif
图1 可折叠和配置的调色板

与以前的GraphicalEditorWithPalette相比,继承 GraphicalEditorWithFlyoutPalette的编辑器要多做一些工作。首先要实现getPalettePreferences() 方法,它返回一个FlyoutPreferences实例,作用是把调色板的几个状态信息(位置、大小和是否展开)保存起来,这样下次打开编辑器的时候就可以自动套用这些设置。下面使用偏好设置的方式保存和载入这些状态,你也可以使用其他方法,比如保存为.properties文件:

protected FlyoutPreferences getPalettePreferences() {
return new FlyoutPreferences() {
public
int getDockLocation() {
return SubjectEditorPlugin.getDefault().getPreferenceStore().getInt(IConstants.PREF_PALETTE_DOCK_LOCATION);
}
public
void setDockLocation(int location) {
SubjectEditorPlugin.getDefault().getPreferenceStore().setValue(IConstants.PREF_PALETTE_DOCK_LOCATION,location);
}

};
}

然后要覆盖缺省的createPaletteViewerProvider()实现,在这里为调色板增加拖放支持,即指定调色板为拖放源(之所以用这样的方式,原因是在编辑器里没有办法得到它对应的调色板实例),在以前这个工作通常是在initializePaletteViewer ()方法里完成的,而现在这个方法已经不需要了:

protected PaletteViewerProvider createPaletteViewerProvider() {
return new PaletteViewerProvider(getEditDomain()) {
protected
void configurePaletteViewer(PaletteViewer viewer) {
super.configurePaletteViewer(viewer);
viewer.addDragSourceListener(
new TemplateTransferDragSourceListener(viewer));
}
};
}

GEF 3.0还允许用户对调色板里的各种工具进行定制,例如隐藏某个工具,或是修改工具的描述等等,这是通过给PaletteViewer定义一个 PaletteCustomizer实例实现的,但由于时间关系,这里暂时不详细介绍了,如果需要这项功能你可以参考Logic例子中的实现方法。

缩放

由于Draw2D中的图形都具有天然的缩放功能,因此在GEF里实现缩放功能是很容易的,而且缩放的效果不错。GEF为我们提供了 ZoomInAction和ZoomOutAction以及对应的RetargetAction(ZoomInRetargetAction和 ZoomOutRetargetAction),只要在编辑器里构造它们的实例,然后在编辑器的ActionBarContributer类里将它们添加到想要的菜单或工具条位置即可。因为ZoomInAction和ZoomOutAction的构造方法要求一个ZoomManager类型的参数,而后者需要从GEF的RootEditPart中获得(ScalableRootEditPart或 ScalableFreeformRootEditPart),所以最好在编辑器的 configureGraphicalViewer()里构造这两个Action比较方便,请看下面的代码:

protected void configureGraphicalViewer() {
super.configureGraphicalViewer();
ScalableFreeformRootEditPart root
= new ScalableFreeformRootEditPart();
getGraphicalViewer().setRootEditPart(root);
getGraphicalViewer().setEditPartFactory(
new PartFactory());
action
= new ZoomInAction(root.getZoomManager());
getActionRegistry().registerAction(action);
getSite().getKeyBindingService().registerAction(action);
action
= new ZoomOutAction(root.getZoomManager());
getActionRegistry().registerAction(action);
getSite().getKeyBindingService().registerAction(action);
}

假设我们想把这两个命令添加到主工具条上,在DiagramActionBarContributor里应该做两件事:在 buildActions()里构造对应的RetargetAction,然后在contributeToToolBar()里添加它们到工具条(原理请参考前面关于菜单和工具条的 帖子):

protected void buildActions() {
//其他命令

//缩放命令
addRetargetAction(new ZoomInRetargetAction());
addRetargetAction(
new ZoomOutRetargetAction());
}
public
void contributeToToolBar(IToolBarManager toolBarManager) {
//工具条中的其他按钮

//缩放按钮
toolBarManager.add(getAction(GEFActionConstants.ZOOM_IN));
toolBarManager.add(getAction(GEFActionConstants.ZOOM_OUT));
toolBarManager.add(
new ZoomComboContributionItem(getPage()));
}

请注意,在contributeToToolBar()方法里我们额外添加了一个ZoomComboContributionItem 的实例,这个类也是GEF提供的,它的作用是显示一个缩放百分比的下拉框,用户可以选择或输入想要的数值。为了让这个下拉框能与编辑器联系在一起,我们要修改一下编辑器的getAdapter()方法,增加对它的支持:

public Object getAdapter(Class type) {

if (type == ZoomManager.class)
return getGraphicalViewer().getProperty(ZoomManager.class.toString());
return super.getAdapter(type);
}

现在,打开编辑器后主工具条中将出现下图所示的两个按钮和一个下拉框:

zoom.gif
图2 缩放工具条

有时候我们想让程序把用户当前的缩放值记录下来,以便下次打开时显示同样的比例。这就须要在画布模型里增加一个zoom变量,在编辑器的初始化过程中增加下面的语句,其中diagram是我们的画布实例:

ZoomManager manager = (ZoomManager) getGraphicalViewer().getProperty(ZoomManager.class.toString());
if (manager != null)
manager.setZoom(diagram.getZoom());

在保存模型前得到当前的缩放比例放在画布模型里一起保存:

ZoomManager manager = (ZoomManager) getGraphicalViewer().getProperty(ZoomManager.class.toString());
if (manager != null)
diagram.setZoom(manager.getZoom());

辅助网格

你可能用过一些这样的应用程序,画布里可以显示一个灰色的网格帮助定位你的图形元素,当被拖动的节点接近网格线条时会被"吸附"到网格上,这样可以很容易的把画布上的图形元素排列整齐,GEF 3.0里就提供了显示这种辅助网格的功能。

grid.gif
图3 辅助编辑网格

是否显示网格以及是否打开吸附功能是由GraphicalViewer的两个布尔类型的属性(property)值决定的,它们分别是 SnapToGrid.PROPERTY_GRID_VISIBLE和SnapToGrid.PROPERTY_GRID_ENABLED,这些属性是通过GriaphicalViewer.getProperty()和setProperty()方法来操作的。GEF为我们提供了一个 ToggleGridAction用来同时切换它们的值(保持这两个值同步确实符合一般使用习惯),但没有像缩放功能那样提供对应的 RetargetAction,不知道GEF是出于什么考虑。另外因为这个Action没有预先设置的图标,所以把它直接添加到工具条上会很不好看,所以要么把它只放在菜单中,要么为它设置一个图标,至于添加到菜单的方法这里不赘述了。

要想在保存模型时同时记录当前网格线是否显示,必须在画布模型里增加一个布尔类型变量,并在打开模型和保存模型的方法中增加处理它的代码。

几何对齐

这个功能也是为了方便用户排列图形元素的,如果打开了此功能,当用户拖动的图形有某个边靠近另一图形的某个平行边延长线时,会自动吸附到这条延长线上;若两个图形的中心线(通过图形中心点的水平或垂直线)平行靠近时也会产生吸附效果。例如下图中,Subject1的左边与 Subject2的右边是吸附在一起的,Subject3原本是与Subject2水平中心线吸附的,而用户在拖动的过程中它的上边吸附到 Subject1的底边。

snapToGeometry.gif
图4 几何对齐

几何对齐也是通过GraphicalViewer的属性来控制是否打开的,属性的名称是 SnapToGeometry.PROPERTY_SNAP_ENABLED,值为布尔类型。在程序里增加吸附对齐切换的功能和前面说的增加网格切换功能基本是一样的,记住GEF为它提供的Action是ToggleSnapToGeometryAction。

要实现对齐功能,还有一个重要的步骤,那就是在画布所对应的EditPart的getAdapter()方法里增加对 SnapToHelper类的回应,像下面这样:

public Object getAdapter(Class adapter) {
    
if (adapter == SnapToHelper.class) {
        List snapStrategies 
= new ArrayList();
        Boolean val 
= (Boolean)getViewer().getProperty(RulerProvider.PROPERTY_RULER_VISIBILITY);
        
if (val != null && val.booleanValue())
            snapStrategies.add(
new SnapToGuides(this));
        val 
= (Boolean)getViewer().getProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED);
        
if (val != null && val.booleanValue())
            snapStrategies.add(
new SnapToGeometry(this));
        val 
= (Boolean)getViewer().getProperty(SnapToGrid.PROPERTY_GRID_ENABLED);
        
if (val != null && val.booleanValue())
            snapStrategies.add(
new SnapToGrid(this));
        
        
if (snapStrategies.size() == 0)
            
return null;
        
if (snapStrategies.size() == 1)
            
return (SnapToHelper)snapStrategies.get(0);

        SnapToHelper ss[] 
= new SnapToHelper[snapStrategies.size()];
        
for (int i = 0; i < snapStrategies.size(); i++)
            ss[i] 
= (SnapToHelper)snapStrategies.get(i);
        
return new CompoundSnapToHelper(ss);
    }
    
return super.getAdapter(adapter);
}

标尺和辅助线

标尺位于画布的上部和左侧,在每个标尺上可以建立很多与标尺垂直的辅助线,这些显示在画布上的虚线具有吸附功能。

ruler.gif
图5 标尺和辅助线

标尺和辅助线的实现要稍微复杂一些。首先要修改原有的模型,新增加标尺和辅助线这两个类,它们之间的关系请看下图:< /p>

modelWithRuler.gif
图6 增加标尺和辅助线后的模型

与上篇帖子里的 模型图比较后可以发现,在Diagram类里增加了四个变量,其中除rulerVisibility以外三个的作用都在前面部分做过介绍,而rulerVisibility和它们类似,作用记录标尺的可见性,当然只有在标尺可见的时候辅助线才是可见的。我们新增了Ruler和 Guide两个类,前者表示标尺,后者表示辅助线。因为辅助线是建立在标尺上的,所以Ruler到Guide有一个包含关系(黑色菱形);画布上有两个标尺,分别用topRuler和leftRuler这两个变量引用,也是包含关系,也就是说,画布上只能同时具有这两个标尺;Node到Guide有两个引用,表示Node吸附到的两条辅助线(为了简单起见,在本文附的例子中并没有实际使用到它们,Guide类中定义的几个方法也没有用到)。Guide类里的map变量用来记录吸附在自己上的节点和对应的吸附边。要让画布上能够显示标尺,首先要将原先的GraphicalViewer改放在一个 RulerComposite实例上(而不是直接放在编辑器上),后者是GEF提供的专门用于显示标尺的组件,具体的改变方法如下:

//定义一个RulerComposite类型的变量
private RulerComposite rulerComp;
//创建RulerComposite,并把GraphicalViewer创建在其上< span style="color: #008000;">
protected void createGraphicalViewer(Composite parent) {
rulerComp
= new RulerComposite(parent, SWT.NONE);
super.createGraphicalViewer(rulerComp);
rulerComp.setGraphicalViewer((ScrollingGraphicalViewer) getGraphicalViewer());
}
//覆盖getGraphicalControl返回RulerComposite实例< span style="color: #008000;">
protected Control getGraphicalControl() {
return rulerComp;
}

然后,要设置GraphicalViewer的几个有关属性,如下所示,其中前两个分别表示左侧和上方的标尺,而最后一个表示标尺的可见性:

getGraphicalViewer().setProperty(RulerProvider.PROPERTY_VERTICAL_RULER,new SubjectRulerProvider(diagram.getLeftRuler()));
getGraphicalViewer().setProperty(RulerProvider.PROPERTY_HORIZONTAL_RULER,
new SubjectRulerProvider(diagram.getTopRuler()));
getGraphicalViewer().setProperty(RulerProvider.PROPERTY_RULER_VISIBILITY,
new Boolean(diagram.isRulerVisibility()));

在前两个方法里用到了SubjectRulerProvider这个类,它是我们从RulerProvider类继承过来的, RulerProvider是一个比较特殊的类,其作用有点像EditPolicy,不过除了一些getXXXCommand()方法以外,还有其他几个方法要实现。需要返回Command的方法包括:getCreateGuideCommand()、getDeleteGuideCommand()和 getMoveGuideCommand(),分别返回创建辅助线、删除辅助线和移动辅助线的命令,下面列出创建辅助线的命令,其他两个的实现方式是类似的,你可以在本文所附例子中找到它们的代码:

public class CreateGuideCommand extends Command {
private Guide guide;
private Ruler ruler;
private
int position;
public CreateGuideCommand(Ruler parent,
int position) {
setLabel(
"Create Guide");
this.ruler = parent;
this.position = position;
}
public
void execute() {
guide
= ModelFactory.eINSTANCE.createGuide();//创建一条新的辅助线
guide.setHorizontal(!ruler.isHorizontal());
guide.setPosition(position);
ruler.getGuides().add(guide);
}
public
void undo() {
ruler.getGuides().remove(guide);
}
}

接下来再看看RulerProvider的其他方法,SubjectRulerProvider维护一个Ruler对象,在构造方法里要把它的值传入。此外,在构造方法里还应该给Ruler和Guide模型对象增加监听器用来响应标尺和辅助线的变化,下面是Ruler监听器的主要代码(因为使用了EMF作为模型,所以监听器实现为Adapter。如果你不用EMF,可以使用PropertyChangeListener实现):

public void notifyChanged(Notification notification) {
switch (notification.getFeatureID(ModelPackage.class)) {
case ModelPackage.RULER__UNIT:
for (int i = 0; i < listeners.size(); i++)
((RulerChangeListener) listeners.get(i)).notifyUnitsChanged(ruler.getUnit());
break;
case ModelPackage.RULER__GUIDES:
Guide guide
= (Guide) notification.getNewValue();
if (getGuides().contains(guide))
guide.eAdapters().add(guideAdapter);
else
guide.eAdapters().remove(guideAdapter);
for (int i = 0; i < listeners.size(); i++)
((RulerChangeListener) listeners.get(i)).notifyGuideReparented(guide);
break;
}
}

可以看到监听器在被触发时所做的工作实际上是触发这个RulerProvider的监听器列表(listeners)里的所有监听器,而这些监听器就是RulerEditPart或GuideEditPart,而我们不需要去关心这两个类。Ruler的事件有两种,一是单位(象素、厘米、英寸)改变,二是创建辅助线,在创建辅助线的情况要给这个辅助线增加监听器。下面是Guide监听器的主要代码:

public void notifyChanged(Notification notification) {
Guide guide
= (Guide) notification.getNotifier();
switch (notification.getFeatureID(ModelPackage.class)) {
case ModelPackage.GUIDE__POSITION:
for (int i = 0; i < listeners.size(); i++)
((RulerChangeListener) listeners.get(i)).notifyGuideMoved(guide);
break;
case ModelPackage.GUIDE__MAP:
for (int i = 0; i < listeners.size(); i++)
((RulerChangeListener) listeners.get(i)).notifyPartAttachmentChanged(notification.getNewValue(),guide);
break;
}
}

Guide监听器也有两种事件,一是辅助线位置改变,二是辅助线上吸附的图形的增减变化。请注意,这里的循环一定不要用 iterator的方式,而应该用上面列出的下标方式,否则会出现ConcurrentModificationException异常,原因和 RulerProvider的notifyXXX()实现有关。我们的SubjectRulerProvider构造方法如下所示,它的主要工作就是增加监听器:

public SubjectRulerProvider(Ruler ruler) {
this.ruler = ruler;
ruler.eAdapters().add(rulerAdapter);
//载入模型的情况下,ruler可能已经包含一些guides,所以要给它们增加监听器< span style="color: #008000;">
for (Iterator iter = ruler.getGuides().iterator(); iter.hasNext();) {
Guide guide
= (Guide) iter.next();
guide.eAdapters().add(guideAdapter);
}
}

在RulerProvider里还有几个方法要实现才能正确使用标尺:getRuler()返回RulerProvider维护的 Ruler实例,getGuides()返回辅助线列表,getGuidePosition(Object)返回某条辅助线在标尺上的位置(以pixel 为单位),getPositions()返回标尺上所有辅助线位置构成的整数数组。以下是本例中的实现方式:

public Object getRuler() {
return ruler;
}
public List getGuides() {
return ruler.getGuides();
}
public
int[] getGuidePositions() {
List guides
= getGuides();
int[] result = new int[guides.size()];
for (int i = 0; i < guides.size(); i++) {
result[i]
= ((Guide) guides.get(i)).getPosition();
}
return result;
}
public
int getGuidePosition(Object arg0) {
return ((Guide) arg0).getPosition();
}

有了这个自定义的RulerProvider类,再通过把该类的两个实例被放在GraphicalViewer的两个属性(PROPERTY_VERTICAL_RULER和PROPERTY_HORIZONTAL_RULER)中,画布就具有标尺的功能了。GEF提供了用于切换标尺可见性的命令:ToggleRulerVisibilityAction,我们使用和前面同样的方法把它加到主菜单即可控制显示或隐藏标尺和辅助线。

位置和尺寸对齐

图形编辑工具大多具有这样的功能:选中两个以上图形,再按一下按钮就可以让它们以某一个边或中心线对齐,或是调整它们为同样的宽度高度。GEF提供AlignmentAction和MatchSizeAction分别用来实现位置对齐和尺寸对齐,使用方法很简单,在编辑器的 createActions()方法里构造需要的对齐方式Action(例如对齐到上边、下边等等),然后在编辑器的 ActionBarContributor里通过这些Action对应的RetargetAction将它们添加到菜单或工具条即可。编辑器里的代码如下,注意最后一句的作用是把它们加到selectionAction列表里以响应选择事件:

IAction action=new AlignmentAction((IWorkbenchPart)this,PositionConstants.LEFT);
getActionRegistry().registerAction(action);
getSelectionActions().add(action.getId());

AlignmentAction的构造方法的参数是编辑器本身和一个代表对齐方式的整数,后者可以是 PositionConstants.LEFT、CENTER、RIGHT、TOP、MIDDLE、BOTTOM中的一个; MatchSizeAction有两个子类,MatchWidthAction和MatchHeightAction,你可以使用它们达到只调整宽度或高度的目的。下图是添加在工具条中的按钮,左边六个为位置对齐,最后两个为尺寸对齐,请注意,当选择多个图形时,被六个黑点包围的那个称为"主选择",对齐时以该图形所在位置和大小为准做调整。

adjust.gif
图7 位置对齐和尺寸对齐

posted on 2005-04-21 11:21 八进制 阅读(9366) 评论(106)  编辑 收藏 网摘 所属分类: EclipseGEF

评论

#1楼  2005-04-21 12:43 yes [未注册用户]
在gef里,Bound好像一般都是矩形框,这有可能带来一些问题.比如,如果在2个菱形间连一条线,由于菱形有矩形的边框(Bound),所以线的端点会落在矩形边框的4条边上而不是菱形的4条边上,这样线的端点就会和菱形的边存在一些距离,影响美观,请问有什么好的方法解决吗?是不是要自己写一个Anchor?
  回复  引用    

#2楼 [楼主] 2005-04-21 13:59 八进制      
是的。另外比如选中那个菱形时显示的黑色边框,如果希望是菱形边框也要自己实现,非矩形的情况有不少类似问题,虽然都可以解决但比较麻烦。
  回复  引用  查看    

#3楼  2005-04-21 16:53 puzzled [未注册用户]
如果想要在用户界面上,把大纲做成选项卡形式,从不同的视角聚焦编辑区域的图形,是不是只需要在ui中重写ContentOutlinePage类?

其它的地方还需要改动吗?
由于对GEF还不是很了解,所以现在很困惑,期待你的解答,谢谢.
  回复  引用    

#4楼 [楼主] 2005-04-21 17:01 八进制      
不知道你说的“从不同的视角”是指什么,能举个例子说明吗?
  回复  引用  查看    

#5楼  2005-04-21 17:20 PUZZLED [未注册用户]
比如说画出的类图,它有子类,实例跟属性.

在大纲中可以用一个大纲视图列出所有的类,切换到另一个大纲视图可以查看某一个类的所有属性,子类,实例等等.就像在Eclipse里可以同时打开许多个程序.
  回复  引用    

#6楼  2005-04-21 17:38 dou [未注册用户]
对画布上的图形元素进行鼠标右键菜单的复制,粘贴之类的操作,应该如何实现呢?

我找到的都是对文本的右键操作.


  回复  引用    

#7楼 [楼主] 2005-04-21 17:46 八进制      
to puzzled: 我想这个功能可以通过现有的大纲视图实现,让大纲只显示当前选中的editpart里的内容(当没有选中任何editpart的时候,GEF认为你选中的是rootEditPart)。
to dou: copy/paste我还没有使用过,你可以看看GEF的CopyTemplateAction,或者联系howjay(http://howj.51.net/
  回复  引用  查看    

#8楼  2005-04-22 10:27 yes [未注册用户]
八进制,你好!
请问有没有可能实现这种效果:不改变边框的形状,菱形的边框仍然是矩形,但连接到菱形的直线可以穿过边框的边连接到菱形的边上?如果可能,大概要如何实现呢?
  回复  引用    

#9楼 [楼主] 2005-04-22 14:43 八进制      
我觉得你可以写自己的Anchor;或者继承ChopboxAnchor,覆盖它的getLocation()方法。后者好象比较适合你的要求。
  回复  引用  查看    

#10楼  2005-04-24 00:11 howjay [未注册用户]
CopyTemplateAction好像是copy的Palette中的内容,而不是你画布上的内容。关于C/C/P,老是说要写下来是如何实现的,就是没去写,实在惭愧,没有八进制这么敬业啊:)

顺便问一下,在自己做的RCP程序里新建的项目的项目名称左边没有图标哎,丑死了,这个能设置吗?
  回复  引用    

#11楼  2005-04-24 16:27 ljian03 [未注册用户]
可以重写copytemplateaction的代码
  回复  引用    

#12楼  2005-04-24 18:41 howjay [未注册用户]
这样可以实现吗? ljian03你有没有实现啊?

我已经开始把我实现C/C/P的方法写下来了,正在进行中
  回复  引用    

#13楼 [楼主] 2005-04-24 18:54 八进制      
加油,写完了留个地址。
  回复  引用  查看    

#14楼  2005-04-25 18:25 yes [未注册用户]
请问求2条polyline的交点该怎么求?我试着把2条线的方程求出,然后再求交点,可是求出来的结果好像不对,有什么其他的方法吗?
  回复  引用    

#15楼 [楼主] 2005-04-25 22:18 八进制      
好象只能自己算,如果你的两条polyline都是直线应该还好,解二元一次方程就可以了,再检查一下你的算法看看是不是哪里写错了。
  回复  引用  查看    

#16楼  2005-05-03 11:35 梁辉 [未注册用户]
八进制:
   您好!最近我正在做一个项目,用到了GEF,苦于现有的资料太少,仅有的资料也很难理解,在拜读了您的大作之后,立刻有相见恨晚的感觉.希望您能够出书,我强烈支持您!!
   由于刚刚接触eclipse ,emf,gef,所以对它们的使用不熟悉.我在载入GetPractice这个例自时,总是说
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.ui.plugin.*;
import org.osgi.framework.BundleContext;
不能被resolve,我现在用的是eclipse 2.1.0,及相应的GEF plugins,请您赐教,麻烦您了.
  另外,能不能将您的E-mail 给我,我想向您多多请教,您要是愿意,可以将您的邮箱地址发到:lianghui234@sina.com,期盼着您的回音!
  回复  引用    

#17楼 [楼主] 2005-05-03 12:26 八进制      
梁辉:请用Eclipse 3.0以上版本,应该没问题的。我的联系方式按最上面的“联系”按钮就看到了。
  回复  引用  查看    

#18楼  2005-05-11 13:46 郭奕 [未注册用户]
再问一个问题。。
我现在的情况跟你那个subject的程序相似,不同之处在于我利用算法自动计算出来一组attribute属于某一个subject,然后再创建这个subject.subject也可以包含另外的subject容器作为children. 先有attribute再建subject.目前的问题是,subject不以那些已经计算出来的attribute为children.(具体的表现是不能显示那些attribute,只能显示attribute之间连接;删除subject的时候不能够删除对应的那组attribute).我在算法中已经将那组attribute加入到subject的children了也重写了getModelChildren()。你觉得还应该注意哪些问题呢??

  回复  引用    

#19楼 [楼主] 2005-05-11 15:44 八进制      
看看attribute的refreshVisuals()方法有没有问题,可能那些不显示的attribute的preferredSize不对。
  回复  引用  查看    

#20楼  2005-05-12 09:45 dudu      

setOpaque(false),虽然可以看到子图形,可是好像还是不能作为container 的subFigure来进行编辑。
是不是跟先有的子图形后有的container有关系?
如果那个subject的例子,可以在subject里面创建subject,可以在diagram里面创建attribute,还需要注意哪些问题?

作者: 郭奕 注: 原来的评论由于含有不完整的html代码, 影响页面的显示而被删除。
  回复  引用  查看    

#21楼  2005-05-12 09:52 mine [未注册用户]
这个可能是还要给每个Attribute设置parent,
EditPart有个setParent方法,是干这个的。
不知道是不是这个。。
  回复  引用    

#22楼 [楼主] 2005-05-12 13:29 八进制      
如果要在diagram里能直接创建attribute,应该让Subject和Attribute都继承同一个类,比如DiagramChild,然后DiagramPart的getModelChildren()方法返回DiagramChild的列表。
  回复  引用  查看    

zoomIn 和 zoomOut 是否可以作用于 images 对象呢?每个 image 都是一个新创建的类的实例。 我试着做 zoom, 可是只有 connections 之类的元素积极响应, 我原有的那些 image icons 却都消失了。

有谁可以给些指导和建议吗? 谢过了先。

不好意思,刚才贴错地方了,放在这里更合适。 刚还没睡醒呢。 :P
  回复  引用    

#24楼 [楼主] 2005-07-23 00:46 八进制      
可能image不能zoom吧,但我不确定。不好意思最近事情太多了,没法帮你试,不过image消失是不应该的。
  回复  引用  查看    

八进制,

不管怎样都非常感谢你,真是太感动了,你做这么多事,真是让小懒猫觉得好惭愧啊。因为我有点马虎,还总是想偷懒,呵呵,虽然只是想想而已。可是有这样的想法就已经不应该了。:P 生活太美好了,总觉得除了专业,还有太多事情要做呢。所以很欣赏那些敬业的人。:)

Thanks a lot. Merci de tout coeur. :)


  回复  引用    

#26楼 [楼主] 2005-07-23 22:22 八进制      
欢迎常来:-)
  回复  引用  查看    

Hi, 如果我想自己定义一个zoom manager在一个Layer上,怎么设置zoom manager的参数呢?

  回复  引用    

我新建了一个LAYER,在这个LAYER里有一个ScrollPane。
我想只针对这个LAYER来zoom in, zoom out。
是不是要自己创建一个ZoomManager的对象,这个对象的两个参数该从什么地方拿呢?
谢谢。
BTW:
我刚开始看GEF,如果什么地方走错了路,请大侠指教。

protected void configureGraphicalViewer() {
super.configureGraphicalViewer();

GraphicalViewer viewer = getGraphicalViewer();
ScalableRootEditPart rooteditpart = new ScalableRootEditPart(){
protected void createLayers(LayeredPane layeredPane) {
super.createLayers(layeredPane);

Image image = new Image(null , getClass().getResourceAsStream("BigPic.gif"));
ImageFigure imageFigure = new ImageFigure(image);
//add figure to panel
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContents(imageFigure);
FreeformLayer czLayer = new FreeformLayer();
czLayer.setLayoutManager(new XYLayout());
czLayer.add(scrollPane, new Rectangle(0, 0, image.getImageData().width, image.getImageData().height));
//add layer to layerpanel
layeredPane.addLayerAfter(czLayer, CZ_LAYER, null);
//prepare for zoom

//viewport = scrollPane.getViewport();
//scaleableLayeredPane = (ScalableLayeredPane)layeredPane;
}
};

viewer.setRootEditPart(rooteditpart);
viewer.setEditPartFactory(new PartFactory());
//ZoomManager zoomManager = new ZoomManager(scaleableLayeredPane, viewport);

  回复  引用    

现在CODE基本上可以实现背景图片的ZOOM了,同时保持NODE的大小和位置不便。但是我用的FreeformLayey好像不支持滚动条。
不知道该用什么。
  回复  引用    

#30楼  2005-08-10 15:24 sawxb [未注册用户]
请问:
在一个编辑器中可以同时使用两种或者两种以上的路由吗?比如:在子类中使用曼哈顿路由,在父类中则使用最短路径路由。该如何实现?
期待中...........
  回复  引用    

#31楼 [楼主] 2005-08-10 20:37 八进制      
chenzhuang:我有时间会帮你研究研究。
sawxb:可以,使用不同的connectionpart即可。
  回复  引用  查看    

#32楼  2005-08-11 19:53 sawxb [未注册用户]
非常感谢 八进制 所需功能已实现
  回复  引用    

#33楼  2005-08-26 16:40 cooleyes [未注册用户]
可以实现多页editor吗?
我试过MultiPageEditorPart,但其页面不能随意打开关闭

  回复  引用    

#34楼 [楼主] 2005-08-26 22:36 八进制      
能实现是肯定的,以前项目组里做过。但不是我来做的,呵呵。
  回复  引用  查看    

#35楼  2005-08-29 09:18 cooleyes [未注册用户]
呵呵,我也觉得可以。
但现在缺的是一个思路,能否给点醒一下
  回复  引用    

#36楼  2005-08-30 15:04 cooleyes [未注册用户]
有没有办法检测到一个Editor将要被关闭的消息
因为我的editor,我需要在其关闭前做一些判断,判断它是否能被关闭
  回复  引用    

#37楼  2005-08-30 15:52 Jianhui [未注册用户]
请问,我在class NodePart类里, 它 extends AbstractGraphicalEditPart implements PropertyChangeListener, NodeEditPart。我怎样才能在这里找到IWorkbenchPage,继而打开一个editor,因为我要在performrequest里头响应一个REQ_OPEN,然后就希望打开一个editor,这个应该怎么实现呢?我试图通过很多api函数寻找,都找不到。请指点!谢谢
  回复  引用    

#38楼  2005-08-30 16:13 cooleyes [未注册用户]
打开的问题我解决了,但现在是要关闭它,(当父Editor关闭的时候,我要关闭子Editor)
至于打开Editor,我是这样处理的
public void performRequest(Request req) {
if (req.getType().equals(RequestConstants.REQ_OPEN) ) {
IWorkbenchPage page = EditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorInput input = new MyEditInput();
try {
IEditorPart editor = page.openEditor(input, myEditorID, true);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
  回复  引用    

#39楼  2005-08-30 18:32 Jianhui [未注册用户]
谢谢,我没有想到可以用Plugin类。太感谢了。
  回复  引用    

#40楼  2005-09-16 11:45 剑辉 [未注册用户]
请问,gef的模型存储的时候,我想用xml,而不是简单的序列化,那么这个时候,然后parser的时候,用dom还是sax比较好呢?你有没有推荐的开源包,比如Xerces和JDOM哪个更好点?他们对于保存那种有含有多层子节点的模型是否可以支持比较好?还有一般存储模型的xml 是用caster还是就用parser包,比如Xerces存入?由于这一块我是刚接触,请多指教!
  回复  引用    

#41楼 [楼主] 2005-09-16 13:55 八进制      
手工保存用jdom就很好,但手工方式都比较繁琐,如果格式改变要动很多代码,还是推荐使用类似castor这样的工具。
  回复  引用  查看    

#42楼  2005-09-16 14:55 剑辉 [未注册用户]
保存模型成xml的时候都必须手工一个元素一个元素的输入吗?有没有快速点的方法。还有就是我看了你关于digester的文章,digester可以用来解析和转换成java模型,不知道digester支持从模型转换到xml吗?我看了好多digester的文章好像都没有讲到从模型到xml的转换。
  回复  引用    

#43楼 [楼主] 2005-09-16 16:29 八进制      
digester只是xml->java,你可以看看xmlobject,这种工具应该有不少。
  回复  引用  查看    

#44楼  2005-09-16 16:50 剑辉 [未注册用户]
嗯,谢谢啊,我觉得castor也还可以,我都会试试看,看看哪个好用!
  回复  引用    

#45楼  2005-09-20 18:17 剑辉 [未注册用户]
做成GEF的RCP形式,EMF不支持RCP代码的生成吧?那么是不是意味着设计GEF的RCP形式,一般都是先做好GEF插件,然后再改成RCP?还是说一开始就要按照RCP的来设计?可能这个问题并不冲突,我只想知道设计GEF的RCP,到底RCP的部分在设计阶段是什么时候考虑?请指教。
  回复  引用    

#46楼 [楼主] 2005-09-20 21:51 八进制      
我觉得RCP和eclipse插件之间的转换并不复杂,所以按哪种设计都问题不大。
  回复  引用  查看    

#47楼  2005-09-23 10:58 剑辉 [未注册用户]
八进制:我把一个GEF editor改成了multipage的editor,发现原先实现的继承SelectionAction的几个action都不能够正确的enable,在multipage editor里头找不到getSelectedObjects()里头选中的editpart,这个函数返回都是null,是不是有些机制我没有实现?
  回复  引用    

#48楼  2005-09-23 18:50 剑辉 [未注册用户]
我实现了SelectionListener就好用了,不过略微感觉麻烦了些
  回复  引用    

#49楼 [楼主] 2005-09-23 23:30 八进制      
有机会我会研究一下multipageeditor
  回复  引用  查看    

#50楼  2005-10-18 10:00 Logic [未注册用户]
请问八进制:怎么屏蔽掉Eclipse插件里头菜单的部分无用选项,还有定制工具栏,比如希望把工具栏图标变大。我做一个elcipse图形编辑器插件,发现很多菜单选项和工具栏选项都用不着,而且需要定制,该如何着手?
因为好像完全转换为RCP,听说会比较麻烦。
  回复  引用    

#51楼 [楼主] 2005-10-18 17:59 八进制      
就用rcp,不会很麻烦,多写几个类而已。
  回复  引用  查看    

#52楼  2005-10-21 12:46 Logic [未注册用户]
我已经成功把原先的gef插件改成了rcp,不过发现一个问题,就是我用resource navigator新建一个项目的时候,这个项目tree中,项目名称节点icon却没有了,而文件的icon还存在,我找了半天也不知道怎么往resource navigator里头添加project名称的icon,你知道怎么改吗?
  回复  引用    

#53楼  2005-10-21 13:43 Logic [未注册用户]
I have troubleshooting this problem. The answer is found in the NewsGroup. Now I attach it here for your information.

Regarding icons; go to org.eclipse.ui.internal.ide.IDEWorkbenchAdvisor in
ide.jar (org.eclipse.ui.ide plugin) and copy boh:

declareWorkbenchImage(Bundle ideBundle, String symbolicName, String path,
boolean shared)
declareWorkbenchImages()

methods to your WorkbenchAdvisor class. Then call declareWorkbenchImages()
from within initialize(IWorkbenchConfigurer configurer).

Your projects will show the icons!

  回复  引用    

#54楼 [楼主] 2005-10-21 17:53 八进制      
Thank you, logic.
  回复  引用  查看    

求助:

一个非技术问题:去年认识的法国同学,今年计算机专业 Master 2,就读于法国勒阿弗尔大学。我们一起合作过一个包含GEF的项目,人很机智幽默,编程厉害没得说,学习和适应能力都很强。他很喜欢中国,很想能在中国完成毕业实习(明年三月起,四个月的实习期),甚至想以后留在中国工作。讲英文没问题,法文母语就不用说了,只是中文讲得不太多,不过他很好学,一直在学习和进步中。

有谁可以帮忙给些相关的信息或建议吗?
dorothyhelene@hotmail.com

多谢先。:)
  回复  引用    

#56楼  2005-11-07 11:46 breeze [未注册用户]
我按照你的方法加上了辅助网格,也打开吸附功能,但是只有网格而没有吸附效果,希望指教


  回复  引用    

to breeze:
我按 八进制 的方法加了网格和吸附,可以实现啊!要不你把代码贴上来看看,或者发到我邮箱里吧,wangzhiwei@gmail.com,我不一定能解答你的问题,不过可以帮你看看
  回复  引用    

to 八进制:
我只希望用户在有限的范围内添加控件,就像本章例子中的attribute只能添加到subject中一样,可是,在attribute加入subject之后,diagram的网格和吸附功能对attribute不起作用了(对subject还是有作用的)。
我的问题是,怎么样在subject中添加网格和吸附功能呢?
多谢!
  回复  引用    

#59楼 [楼主] 2005-12-09 21:49 八进制      
感谢热心的wangzhiwei,很高兴看到关心这里的朋友们能够互相交流:-)
上面的问题我回你信箱了,希望能有帮助。
  回复  引用  查看    

#60楼  2005-12-17 15:54 linpay [未注册用户]
对齐功能为什么选择多个组件后,是恢的呢。不可用。
  回复  引用