GEF 进阶,第六部分: Feedback

简介: Feedback(反馈)指的是GEF中对用户操作的一种回显,这种回显一般来说是视觉上的,但是也不一定。完全可以由用户来定制。本文介绍Feedback的相关概念,并通过实例演示其定制过程。

Feedback(反馈)指的是GEF中对用户操作的一种回显,这种回显一般来说是视觉上的,但是也不一定。完全可以由用户来定制。本文介绍Feedback的相关概念,并通过实例演示其定制过程。

Feedback

Feedback(反馈)是对用户操作的某种响应,我们先来一点感性认识,见下图:


图1看到,在拖动某个图形时,我们一般会看到一个虚影,这就叫做反馈。它告诉了用户这个图形在松开鼠标之后将会被放置在什么地方,这是一种很好的提高用户友好度的方式,也是反馈的主要目的。

反馈有两种:Source Feedback(源反馈)和Target Feedback(目标反馈)。鼠标操作的图形叫源,鼠 标移动时经过的地方叫目的。在图1中,那个椭圆就是源,而那个虚影就是源反馈,而目标就是你鼠标具 体指向的地方了,如果你的鼠标停在一个矩形上,那么那个矩形就是目标,由目标提供的反馈就叫目标反 馈。一般我们在GEF中见到的反馈都是一些视觉上的效果,比如图1中的虚影。如果你愿意,你可以播放一 段音乐或者别的什么,所以反馈并不限于视觉效果。对于视觉上的效果而言,GEF提供了一个缺省的层, 叫做Feedback Layer(反馈层),我们看到的图形一般都是添加到反馈层的。

提示: 不了解层的概念的请回顾本系列第三部分

还有一个问题就是反馈的触发时机。反馈到底是在什么时候才会出现呢?对于源反馈,它是在拖动的时候触发的,对于目标反馈,鼠标的移动,进入或者拖动都有可能触发。但是这只是一般的情况,是GEF缺省的情况。如果你需要在更多的场合显示反馈,需要多实现一些方法罢了,但是也并不复杂。

最后一个问题是该显示什么样的反馈。我们先来看看EditPart接口中两个和反馈显示有关方法的原型:

清单1. 显示反馈的方法原型

public interface EditPart extends IAdaptable {
   // other methods
   ......
   
   void showSourceFeedback(Request request);
   void showTargetFeedback(Request request);
}

方法的参数为Request对象。所以Request对象是我们判断显示何种反馈的主要依据。GEF的缺省Request类型都定义在RequestConstants接口中,而我们自己也可以定义Request。于是,“显示什么样的反馈”这个问题也就清楚了。

自定义Feedback

概念上的东西只有这么多,现在我们来尝试定制反馈行为。我们要实现的功能很简单,拖动一个图形的时候,显示一个字符串表示是什么图形。然后在拖动的过程中,显示一个坐标信息表示当前拖动到了什么位置。

自定义源反馈

观察AbstractEditPart的代码可以发现,它实际是把showSourceFeedback和showTargetFeedback都转发给了EditPolicy来完成,所以自定义Feedback正确的做法应该是实现一个自定义的EditPolicy并安装到EditPart中。这里又有一个问题,应该安装到哪个角色上呢?和拖动图形相关的角色叫Primary Drag,这个角色的Policy是由父类提供的。所以我们找到DiagramEditPart,修改它的ShapesXYLayoutEditPolicy内部类,覆盖其父类的createChildEditPolicy方法。如下所示:

清单2. 改变孩子的EditPolicy

private static class ShapesXYLayoutEditPolicy extends XYLayoutEditPolicy {
   // other methods
   ......
   
   @Override
   protected EditPolicy createChildEditPolicy(EditPart child) {
      return new CustomResizableEditPolicy();
   }
}
而CustomResizableEditPolicy的代码如下:

清单3. CustomResizableEditPolicy的实现

public class CustomResizableEditPolicy extends ResizableEditPolicy {
   @Override
   protected IFigure createDragSourceFeedbackFigure() {
      IFigure f = null;
      if(getHostFigure() instanceof Ellipse)
         f = new Label("Source: Ellipse");
      else
         f = new Label("Source: Rectangle");
      addFeedback(f);
      return f;
   }
}

由于我只是继承了现成的ResizableEditPolicy, 所以留给我的工作并不多,简单的替换成我们想显示的Feedback即可。从以上代码上可以看出,我返回的是一个标签,所以我们的源反馈从一个虚影变成了一个标签。如下图所示:



自定义目标反馈

现在我们再来考虑目标反馈。我们希望在拖动的时候显示一个坐标信息,那么拖动这个动作是一个布局相关的东西,应该是归一个具有Layout角色的EditPart负责的。在我们的例子里,图形是放在Diagram里面的,所以对于目标反馈,我们仍然需要修改ShapesXYLayoutEditPolicy。代码如下所示:

清单4. 实现目标反馈

protected void showLayoutTargetFeedback(Request request) {
   if(request instanceof ChangeBoundsRequest) {
      ChangeBoundsRequest r = (ChangeBoundsRequest)request;
      Point mouse = r.getLocation();
      if(feedback == null) {
         feedback = new Label("" + mouse.x + ", " + mouse.y);
         addFeedback(feedback);
      } else 
         ((Label)feedback).setText("" + mouse.x + ", " + mouse.y);
         
      feedback.setBounds(new Rectangle(mouse.translate(0, 20), 
         feedback.getPreferredSize()));
   }
}

protected void eraseLayoutTargetFeedback(Request request) {
   if(feedback != null)
      removeFeedback(feedback);
   feedback = null;
}

我们只需要覆盖两个方法,因为父类已经为我们处理了其它情况。如果你要追根究底的话,我们来看看LayoutEditPolicy中的showTargetFeedback()方法:

清单5. 父类做了什么

public void showTargetFeedback(Request request) {
   if (REQ_ADD.equals(request.getType())
      || REQ_CLONE.equals(request.getType())
      || REQ_MOVE.equals(request.getType())
      || REQ_RESIZE_CHILDREN.equals(request.getType())
      || REQ_CREATE.equals(request.getType()))
      showLayoutTargetFeedback(request);
      
   if (REQ_CREATE.equals(request.getType())) {
      CreateRequest createReq = (CreateRequest)request;
      if (createReq.getSize() != null)
         showSizeOnDropFeedback(createReq);
   }
}

LayoutEditPolicy为我们判断了很多request类型,和拖动相关的就是REQ_MOVE。所以我们不用再做判断了。我们添加的方法中,一个用来创建反馈图形,一个用来移除反馈图形,逻辑上非常简单。要注意addFeedback和removeFeedback的实现,它先得到反馈层,再把我们创建的图形添加到反馈层。现在运行整个例子,可以看到鼠标拖动的时候有一个坐标信息显示在附近。如图所示:


结束语

我们介绍了Feedback的概念并给出了具体示例。需要强调的是:学习GEF,重要的是了解它的流程, 了解了流程之后才能更好的理解细节。对于Feedback而言,它由EditPart负责,转发给EditPolicy,再根据Request类型创建反馈图形,添加到反馈层。本文的例子只覆盖了一些很基本的情况,这里我提出一些高级的功能,留给有兴趣的读者完成:

  1. 实现非图形化的反馈,比如播放声音
  2. 尝试用反馈实现一个浮动工具条,当鼠标移动到某个图形上时,显示这个工具条,过一段时间后消失。

大家可以想象一下使用反馈能实现什么样的有趣功能。

http://www.ibm.com/developerworks/cn/opensource/os-ecl-gef/part6/



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值