java - 我目前正在使用文本编辑器,需要一些帮助来制作 "undo change"函数

标签 java

如上所述,我目前正在开发一个文本编辑器,作为一个有趣的副业。

我现在想包括一些恢复/重做更改功能,但我不太清楚该怎么做。

我目前的想法:

  1. 我需要一个 bufferedReaders 列表。
  2. 在加载文档时,无论如何我都会创建一个 bufferedReader 以将文档文本粘贴到我的文本区域中。这个状态将是我的第一个项目 列表
  3. 当用户编辑文档时,每次检测到按键时,我都会在线程中启动一个计时器。如果计时器用完 没有任何额外的键进入(假设它在 300ms 超时),它会生成一个新的 bufferedreader 并将其粘贴到 列表。
  4. 当用户要求恢复更改时,我会选择最 最近的列表条目,并用它覆盖 textArea。 (这是 考虑到这些文件,我认为我会遇到问题 可能很大,这需要一些时间)。如果他想再次恢复,我将在我的列表中后退一个索引。如果他 想重做,向前迈出一步。

但是,考虑到可以轻松收集大量数据,我不太清楚这是否是最佳方式。但是,我现在还想不出另一个想法来实现这一点。

你有什么建议可以让我更好地做到这一点吗?

最佳答案

我建议您阅读有关设计模式的内容,特别是命令模式。这里有一些信息:

命令模式被称为行为模式,因为它用于管理对象之间的算法、关系和职责。最初的四人帮设计模式一书中提供的命令定义如下:

将请求封装为一个对象,从而让您可以用不同的请求、队列或日志请求来参数化客户端,并支持可撤销操作

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

Command pattern

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

下面的时序图更清楚的展示了其中的关系: Sequence diagram

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

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

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

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

那么它在 Java 中是如何工作的呢? 让我们以 Remote 为例。我们的 Remote 是家庭自动化的中心,可以控制一切。我们仅以一盏灯为例,我们可以打开或关闭它,但我们可以添加更多命令。

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

//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;
   }

   }

在这种情况下,我们的调用者是 Remote 。

//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();

}

}

关于java - 我目前正在使用文本编辑器,需要一些帮助来制作 "undo change"函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30174298/

相关文章:

java - 反序列化问题 - 获取 java.lang.ClassNotFoundException

java - 如何使用 Formatter 类将扫描仪输入用作文件名

java - 如果我们不注销 BroadcastReceiver 会发生什么?

java - 使用 HttpUrlConnection 的抢先式基本身份验证?

java - Android 上增强基色类

Java:使用 Collat​​orKey 对集合进行排序

java - Ant/checksum : How to generate one . md5 文件用于多个文件(导致 md5 文件包含多行)

java - 在java中隐藏标签页眉

java - Android/Firebase - 检查您是否订阅了主题

java - 实例化参与者而不明确知道他们的名字