我目前正在编写文本编辑器,需要一些帮助才能进行“撤消更改”功能

时间:2015-05-11 17:47:41

标签: java

如上所述,我目前正在开发一个文本编辑器,就像一个有趣的项目一样。

我现在想要包含一些还原/重做更改功能,但我不知道该怎么做。

我目前的想法:

  1. 我需要一个bufferedReaders列表。
  2. 在文档加载时,我创建了一个bufferedReader,无论如何都要将文档文本粘贴到我的textarea中。这个状态将是我的第一个项目 列表
  3. 当用户编辑文档时,每次检测到按键时,我都会在一个线程中启动一个计时器。如果计时器用完了 没有任何额外的钥匙进来(让我们说它在300毫秒 超时),它将生成一个新的bufferedreader并将其粘贴到 清单。
  4. 当用户要求还原更改时,我会选择最多 最近的列表条目,并用它覆盖textArea。 (这是 考虑到文件,我认为我会遇到问题 可能很大,这需要一些时间)。如果他想再次恢复,我将退回列表中的一个索引。如果他 我想重做一步,前进一步。
  5. 但是,考虑到大量数据可以很容易地汇集在一起​​,我不太清楚这是否是最好的方法。但是,我现在还不能弄清楚如何实现这个目标。

    是否有任何提示可以让我更好地做到这一点?

1 个答案:

答案 0 :(得分:3)

我建议您阅读设计模式,特别是命令模式。以下是一些信息:

Command模式被称为行为模式,因为它用于管理对象之间的算法,关系和责任。最初的Gang of Four关于设计模式的书中提供的Command的定义说明:

将请求封装为对象,从而允许您使用不同的请求,队列或日志请求参数化客户端,并支持可撤消的操作

那么这在类图中意味着什么呢?

Command pattern

Command为所有命令声明一个接口,提供一个简单的execute()方法,该方法要求Receiver执行命令。接收方知道如何执行请求。 Invoker拥有一个命令,可以通过调用execute方法让Command执行请求。客户端创建ConcreteCommands并为命令设置Receiver。 ConcreteCommand定义了动作和接收者之间的绑定。当Invoker调用执行时,ConcreteCommand将在Receiver上运行一个或多个操作。

以下序列图以更清晰的方式显示关系: Sequence diagram

我什么时候使用这种模式? 命令模式在以下情况下非常有用:

  • 需要提供请求的历史记录
  • 您需要回调功能
  • 需要在变更时或变更订单中处理请求
  • 调用者应该与处理该对象的对象分离 调用。

当您需要进行多次撤消操作时,您会看到命令被大量使用,其中维护了最近执行的一堆命令。要实现撤消,您只需要做的就是获取堆栈中的最后一个命令并执行它的undo()方法。

您还会发现Command对向导,进度条,GUI按钮和菜单操作以及其他事务行为很有用。

那么它在Java中是如何工作的? 我们以遥控器为例。我们的遥控器是家庭自动化的中心,可以控制一切。我们只使用灯光作为示例,我们可以打开或关闭,但我们可以添加更多命令。

首先我们将创建命令界面:

//Command
public interface Command
{
    public void execute();
}

现在让我们创建两个具体的命令。一个会打开灯,另一个会关灯:

//Concrete Command
public class LightOnCommand implementsCommand
{
//reference to the light
Light light;

public LightOnCommand(Light light)
{
    this.light = light;
}

public void execute()
{
    light.switchOn();
}

}


 //Concrete Command
public class LightOffCommand implementsCommand
{
//reference to the light
Light light;

public LightOffCommand(Light light)
{
    this.light = light;
}

public void execute()
{
    light.switchOff();
}

}

Light是我们的接收器类,所以我们现在就设置它:

    //Receiver
   public class Light
   {
   private boolean on;

   public void switchOn()
   {
      on = true;
   }

   public void switchOff()
   {
      on = false;
   }

   }

在这种情况下,我们的调用者是遥控器。

//Invoker
public class RemoteControl
{
private Command command;

public void setCommand(Command command)
{
    this.command = command;
}


public void pressButton()
{
    command.execute();
}

}

最后,我们将设置一个客户端来使用调用程序

//Client
public class Client
{
public static void main(String[] args)
{
    RemoteControl control = new RemoteControl();

    Light light = new Light();

    Command lightsOn = new LightsOnCommand(light);
    Command lightsOff = new LightsOffCommand(light);

    //switch on
    control.setCommand(lightsOn);
    control.pressButton();

    //switch off
    control.setCommand(lightsOff);
    control.pressButton();

}

}