3

私は現在、小さなテキスト エディター (学校向けのプロジェクト) をプログラミングしていますが、取り消し可能なコマンドを管理する適切でクリーンな方法を見つけるのに苦労しています。

(改善だけではないため、コード レビューの質問ではありません。アプリケーションを希望どおりに動作させたい場合は、コードを変更する必要があります)

私のアプリケーションの動作は次のとおりです。実際には文字の配列リストであるバッファを保持する具体的なサブジェクトがあります。この配列リストが変更されるたびに (挿入、切り取り、貼り付けなど)、サブジェクトはオブザーバーを更新します (現時点では 1 つの GUI のみで構成されます) (MVC パターン)。

元に戻すとやり直しのために今まで行っていたのは、バッファの状態全体を保存することでした(記念品を介して)。これは正常に機能していますが、

  • 明らかに改善できます。
  • 実装する必要がある新機能が機能していない (ユーザー アクションを記録して、いつでも再生できるようにする)

バッファの代わりにコマンドを保存する方法がわかりません。また、それが良い方法であるかどうかもわかりません。

プログラムの一部を次に示します (insert コマンドの場合)。

「GUI」.java

...

class KeyboardListener extends KeyAdapter { 

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

CommandManager.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());
    }
}
...

CommandInsert.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

私は2つのインターフェースを定義したいのですが、それらのメソッドには引数がありません

public interface Command {

    public void execute();

}

...およびUndoアクションの場合:

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

}

との処理はexecuteundoを介して行うこともできますCommandManager

于 2011-07-18T14:10:02.650 に答える