Реализует отменяемую команду - Java - PullRequest
3 голосов
/ 18 июля 2011

В настоящее время я программирую небольшой текстовый редактор (проект для школы), и у меня возникают проблемы с поиском хорошего и чистого способа управления командами, которые нельзя отменить.

(Это не вопрос проверки кода, поскольку речь идет не только об улучшении. Мне нужно изменить код, если я хочу, чтобы мое приложение работало так, как я хочу)

Вот как работает мое приложение: у меня есть конкретная тема, которая содержит буфер, который на самом деле является массивом символов. Всякий раз, когда этот массив данных изменяется (вставка, вырезание, вставка ...), субъект обновляет наблюдателей - которые на данный момент состоят только из одного графического интерфейса - (шаблон MVC).

То, что я делал до сих пор для отмены и повтора, - это сохранение всего состояния буфера (через память), который работает нормально, но:

  • очевидно может быть улучшено.
  • не работает для новой функции, которую мне нужно реализовать (запись действий пользователя, чтобы он мог воспроизводить их в любое время)

Я не могу понять, как сохранить команды вместо буфера, и если это хороший путь.

Вот некоторые фрагменты программы (для команды вставки):

"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).

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 18 июля 2011

Вы можете создать Undoable интерфейс, который могут реализовывать команды, такие как:

public interface Undoable {

   public void do(Editor text)

   public void undo(Editor text)

}

где Редактор - это модель вашего редактора, в которую вы можете вставлять текст, удалять текст или манипулировать другими командами. Команде, реализующей интерфейс, нужно только знать, как «делать» и «отменять» себя, поэтому вам не нужно сохранять копию текстового буфера на каждом шаге, просто сохраняйте список команд .

0 голосов
/ 18 июля 2011

Я бы предпочел определить два интерфейса, но без каких-либо аргументов в их методах

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 может бытьчерез CommandManager.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...