【原创】命令堆栈(二十七)

  在GEF框架中,通常会用到命令执行、撤销和重复的操作,在Eclipse中,也大量地采用Command、CommandManager和ICommandListener等机制来控制命令的执行及监听。在此将简要介绍GEF命令堆栈(CommandStack)的运行方式,有兴趣的读者可以跟踪Eclipse源代码,查找其他框架命令的执行和撤销。

  命令堆栈(CommandStack)

  GEF框架会维护CommandStack,通过CommandStack来执行、撤销和重复命令的操作。CommandStack中有两个堆栈(Stack)类型的数据——undoable和redoable:通过undoable,CommandStack知道有哪些命令可以撤销;通过redoable,CommandStack知道有哪些命令可能被重复。

  当用户执行撤销操作时(例如按快捷键【Ctrl+Z】),GEF框架会调用CommandStack的undo方法,执行撤销的操作。当用户执行重复的操作时(例如按快捷键【Ctrl+Y】),GEF框架会调用CommandStack的redo方法,执行重复的操作。undo和redo方法的代码片断如以下代码如示。

  public void undo() {

  Command command = (Command)undoable.pop();

  notifyListeners(command, PRE_UNDO);

  try {

  command.undo();

  redoable.push(command);

  notifyListeners();

  } finally {

  notifyListeners(command, POST_UNDO);

  }

  }

  public void redo() {

  if (!canRedo())

  return;

  Command command = (Command)redoable.pop();

  notifyListeners(command, PRE_REDO);

  try {

  command.redo();

  undoable.push(command);

  notifyListeners();

  } finally {

  notifyListeners(command, POST_REDO);

  }

  }

  undo和redo方法会从相应堆栈的顶部取出命令,执行命令的undo和redo操作,然后把取出的命令放入另外一个堆栈中。通过这种机制,GEF框架能够重复和撤销用户创建的命令,从而完成重复和撤销的操作。

  CommandStack不但完成重复和撤销命令的操作,还会协助完成命令的执行,当GEF框架要执行命令时,会调用CommandStack的execute方法执行相关命令,如以下代码片段所示。

  public void execute(Command command) {

  if (command == null || !command.canExecute())

  return;

  flushRedo();

  notifyListeners(command, PRE_EXECUTE);

  try {

  command.execute();

  if (getUndoLimit() > 0) {

  while (undoable.size() >= getUndoLimit()) {

  ((Command)undoable.remove(0)).dispose();

  if (saveLocation > -1)

  saveLocation--;

  }

  }

  if (saveLocation > undoable.size())

  saveLocation = -1;

  undoable.push(command);

  notifyListeners();

  } finally {

  notifyListeners(command, POST_EXECUTE);

  }

  }

  CommandStack会调用command的execute方法执行命令,然后把command放入撤销命令的堆栈中。

  另外,读者可以看到,在execute、undo和redo方法中都会调用notifyListeners方法,CommandStack通过notifyListeners方法通知所有注册的监听器,命令堆栈已经发生了改变。

  监听器

  在GEF编辑器中,用户可以通过“getEditDomain().getCommandStack()”代码获得编辑器的命令堆栈,在CommandStack中可以通过addCommandStackListener方法添加命令堆栈的监听器,监听器是CommandStackListener类型的对象。CommandStackListener接口定义如例程1所示。

  例程1 CommandStackListener.java

  package org.eclipse.gef.commands;

  import java.util.EventObject;

  public interface CommandStackListener {

  void commandStackChanged(EventObject event);

  }

  CommandStackListener接口中声明了一个方法commandStackChanged,当命令堆栈发生改变时,commandStackChanged方法将会执行,如以下代码片段所示。

  public void commandStackChanged(EventObject event)

  {

  updateActions(stackActionIDs);

  setDirty(getCommandStack().isDirty());

  }

  protected void setDirty(boolean dirty)

  {

  if (isDirty != dirty)

  {

  isDirty = dirty;

  //通知Eclipse,当前编辑器已经被修改

  firePropertyChange(IEditorPart.PROP_DIRTY);

  }

  }

  如以上代码所示,当命令堆栈改变时,编辑器将更新相应的Action,另外通过fireProperty Change方法通知编辑器,当前编辑的内容已经被修改。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13081368/viewspace-407098/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13081368/viewspace-407098/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值