[GEF]实现模板功能

简介: 最近遇到一个需求是要在GEF应用里实现“模板”的功能,也就是像word那样在新建一个文件的时候,用户可以选择一个模板,然后以这个模板为基础进行编辑,而不用每次都从头开始。同时,用户要能够创建新模板和对模板进行编辑,在模板里可以指定一些对模型的限制,例如树的最大高度、子节点数目的限制,等等。

最近遇到一个需求是要在GEF应用里实现“模板”的功能,也就是像word那样在新建一个文件的时候,用户可以选择一个模板,然后以这个模板为基础进行编辑,而不用每次都从头开始。同时,用户要能够创建新模板和对模板进行编辑,在模板里可以指定一些对模型的限制,例如树的最大高度、子节点数目的限制,等等。

最简单的模板可以就是一个实例,以它为模板时创建的新实例就是这个实例的副本。这种情况下,模板编辑器就是实例编辑器。问题主要有两个,一是无法通过模板实现上述对实例的限制,二是除了扩展名以外,用户难以通过编辑器外观区分是在编辑模板还是编辑实例(本文中实例指原有的那个模型)。

更一般的模板可以这样设计:首先,模板模型和实例模型是很相似的,只是在实例模型的基础上,每个模板类多了一些用来限制实例的属性,因此,模板模型中的每个类应该是实例模型中对应类的子类,这样就解决了限制实例的问题。其次,对模板的编辑不能使用现有的Editor,而应该是对现有Editor的扩展,目的是区分两种编辑器的外观。

等一下,按照这个设计在实现上会有一些问题,在根据某个模板编辑实例的时候,必须知道模板信息,这样才能判断比如新增子节点操作是否可用。但是如果你某天打开一个实例时模板早已被删除了呢?我们实际需要的是,一旦实例被创建,它就与模板脱离关系,即使模板被修改和删除。因此,我认为模板和实例必须共享完全相同的模型,这样实例中就有完整的限制信息,并且还有一个额外的好处,它们的读取方法是完全一致的,可以节约不少工作量。

现在来看看实现。为了更加灵活,我们把模板单独作为一个新的Plugin,这样一是便于分开代码,二是很方便添加或移除模板功能(只要删掉模板Plugin就能移除模板功能)。因此,在模板Plugin里要额外指定对原来Plugin的依赖(在Plugin编辑器的dependencies属性页里),而原来Plugin里要确保Export了模板Plugin需要的所有包(在runtime属性页里)。

在这个Plugin里,创建一个继承实例Editor的新Editor(名为TemplateEditor)。怎样让这个Editor里显示的界面与实例Editor有所区别呢?最简单的一个方法是设置viewer的背景颜色,也就是覆盖configureGraphicalViewer()方法,加上下面这句:

getGraphicalViewer().getControl().setBackground( new  Color( null 250 250 200 )); 

如此一来,这个Editor的背景就是淡黄色了。但我还想进一步改造它,让每个节点的显示都与实例编辑器中不同。因为节点的figure是在editpart里创建的,所以就必须使用与原来不同的editpart,而editpart是通过partfactory创建的,所以要让viewer使用与原来不同的partfactory:

getGraphicalViewer().setEditPartFactory( new  TemplatePartFactory()); 

当然,我们还要通过继承原来的那些editpart得到一套新的editpart,在TemplatePartFactory的createEditPart()方法里返回它们。在新的editpart的createFigure()方法里,返回你希望的图形。

模板编辑(左图)和实例编辑(右图)

图形的问题解决了,还剩下另一个问题,应该只在编辑模板的时候在properties view里显示那些限制属性,而在编辑实例时不显示(这些属性在起作用,但不应该能被编辑)。按照GEF提供的例子,一般是在model类里定义用来控制哪些属性显示在properties view的IPropertyDescriptor数组,我们现在的情况是两个Plugin使用同一个model,这样就造成了矛盾。解决的办法是改为在editpart里定义IPropertyDescriptor数组。GEF的editpart通过getAdapter()方法返回实现IPropertySource接口的对象:

public  Object getAdapter(Class key)  {
    
if (IPropertySource.class == key) {
        
if (getModel() instanceof IPropertySource)
            
return getModel();
        
if (getModel() instanceof IAdaptable)
            
return ((IAdaptable)getModel()).getAdapter(key);
    }

    
if (AccessibleEditPart.class == key)
        
return getAccessibleEditPart();
    
return null;
}

可以看到当model类实现了IPropertySource时,就会返回model类。我们要覆盖这个方法,让它返回editpart本身,同时让editpart实现IPropertySource并把原来放在model类里的那些代码移动到editpart里。最好在原来的editpart里就做出修改,这样模板部分只要简单的继承下来并修改getPropertyDescriptors()等几个相关方法即可:

public  Object getAdapter(Class key)  {
    
if (IPropertySource.class == key) {
        
return this;
    }

    
return super.getAdapter(key);
}

模板模型的属性视图(左图)和实例模型的属性视图(右图)

要记住,为了让这些限制属性在实例编辑中起作用,必须修改原来的代码,增加这些额外的判断。之后,再在原来的CreationWizard里增加一个选择模板的page,模板功能就算实现了。按照这个思路,不需要额外写很多代码。

本文转自博客园八进制的博客,原文链接:[GEF]实现模板功能,如需转载请自行联系原博主。

相关文章
|
13天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
11天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
390 134
|
11天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
491 132
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
2天前
|
人工智能 移动开发 自然语言处理
阿里云百炼产品月刊【2025年9月】
本月通义千问模型大升级,新增多模态、语音、视频生成等高性能模型,支持图文理解、端到端视频生成。官网改版上线全新体验中心,推出高代码应用与智能体多模态知识融合,RAG能力增强,助力企业高效部署AI应用。
205 0
|
12天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
489 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
5天前
|
存储 JSON 安全
加密和解密函数的具体实现代码
加密和解密函数的具体实现代码
234 136
|
23天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1574 87