3

我目前正在编写一个小文本编辑器(学校项目),我在寻找一种管理可撤销命令的好方法时遇到了一些麻烦。

(这不是一个代码审查问题,因为它不仅仅是关于改进。如果我希望我的应用程序按我想要的方式工作,我需要更改我的代码)

以下是我的应用程序的工作方式:我有一个具体的主题,它保存实际上是一个字符数组列表的缓冲区。每当修改此数组列表(插入、剪切、粘贴...)时,主题都会更新观察者——目前仅包含一个 gui——(MVC 模式)。

到目前为止,我为撤消和重做所做的是保存缓冲区的整个状态(通过纪念品),这工作正常但是:

  • 显然可以改进。
  • 不适用于我需要实现的新功能(记录用户操作,以便他可以随时播放)

我不知道如何保存命令而不是缓冲区,以及它是否是好方法。

这是程序的一些块(用于插入命令):

“图形用户界面”.java

...

class KeyboardListener extends KeyAdapter { 

    @Override
    public void keyPressed(KeyEvent e) {
            ...
            commandManager.executeCommandInsert(caretStart, caretStop, e.getKeyChar());
            ...
    }
    ...
}

命令管理器.java

...

public void executeCommandInsert(int start, int end, char character) {  
    addMementoUndo();   
    commandInsert.setCarets(start, end);
    commandInsert.setChar(character);
    commandInsert.execute();    
}

public void addMementoUndo() 
{
    TextConcrete text = TextConcrete.getInstance();
    this.commandsUndo.add(0, text.createMemento());
    if(recordMode){
        this.recordings.add(text.createMemento());
    }
}
...

命令插入.java

...
public void execute(){
   TextConcrete text = TextConcrete.getInstance();
   text.insert(this.start, this.end, this.character);
}
...

TextConcrete.java

...
public void insert(int start, int end, char character){
    //inserting in ArrayList
}

public CommandUndoable createMemento(){
   CommandUndoable mem = new CommandUndoable();
   mem.setState(getState());
   return mem;
}

public String getState(){
   StringBuilder temp = new StringBuilder();
   for(int idx = 0; idx < this.state.size(); idx++){
       temp.append(this.state.get(idx));
   }    
   return temp.toString();
}
...

CommandUndoable 只是保存缓冲区状态的备忘录,然后保存在 CareTaker (CommandManager) 中的备忘录列表中。

任何帮助将不胜感激。

4

2 回答 2

2

您可以创建一个命令可以实现的Undoable接口,例如:

public interface Undoable {

   public void do(Editor text)

   public void undo(Editor text)

}

其中Editor是编辑器的模型,您可以在其中插入文本、从中删除文本或使用其他命令进行操作。实现接口的命令只需要知道如何“执行”和“撤消”本身,因此您不需要在每一步存储文本缓冲区的副本,只需存储命令列表即可。

于 2011-07-18T14:01:23.950 回答
0

我更愿意定义两个接口,但在它们的方法中没有任何参数

public interface Command {

    public void execute();

}

...对于撤消操作:

 public interface UndoableCommand extends Command  {

    public void undo();

}

我认为,这更灵活,因为您的应用程序中可能有一些不可撤消的交互。(比如保存或加载文件)

要实现这样的UndoableCommand只是写一些这样的想法..

 public class EditorInsertCommand implements UndoableCommand  {

    private Editor editor;

    private String textToInsert;

    private String textBefore;

    public EditorInsertCommand(Editor editor, String textToInsert){
       this.editor = editor;
       this.textToInsert = textToInsert;
    }


    public void execute() {
        this.textBefore = editor.getText();
        editor.setText(textToInsert);
    };

    public void undo(){
       editor.setText(textBefore );
    };

}

execute和,的处理undo也可以通过 a 来完成CommandManager

于 2011-07-18T14:10:02.650 回答