Как реализовать функцию Undo/Redo в java

Не могу сделать функции Undo Redo для JTextArea. Как это сделать?


Ответы (1 шт):

Автор решения: Leviathan_ZC

Ответ уже был(правда для С++), но позволю себе дать его перевод :

Я дам еще один ответ, но я думаю, что до сих пор многие об этом не знают.

Тема далеко не тривиальна, и поиск в Интернете дает много результатов. Многие приложения реализуют операцию "Undo", и существует множество вариантов.

Есть 2 паттерна проектирования, которые могут помочь нам здесь:

  • Command: это воплощение действия

  • Memento: которая заключается в сохранении состояния (обычно подразумевает некоторую форму сериализации)

Паттерн Команда широко используется в графических средах, поскольку обычно существуют различные способы выполнения действия. Например, подумайте об операции сохранения в Microsoft Word:

  • вы можете нажать на значок сохранения
  • вы можете перейти в меню Файл и нажать на Сохранить
  • вы используете комбинацию клавиш, как правило, CTRL+S

И, конечно, save, вероятно, реализован в термине save as.

Преимущество паттерна Команда здесь двоякое:

  • вы можете создать стек объектов
  • вы можете попросить каждый объект выполнить операцию Undo

Теперь есть различные проблемы, которые присуще операции Undo:

  • некоторые операции не могут быть отменены (например, рассмотрим rm в Linux или действие Очистки корзины в Windows)
  • некоторые операции трудно отменить, или это может быть неестественно (вам нужно сохранить некоторое состояние, объект обычно уничтожается, но здесь вам нужно будет фактически сохранить его в команде для операции Undo)
  • как правило, мы думаем об отмене/повторении как о стеке, некоторые программы (в основном графические) предлагают отменять элементы,
    фактически не отменяя то, что было сделано позже, этого гораздо
    труднее достичь, особенно когда новые действия были построены поверх
    действия для отмены...

Поскольку существуют различные проблемы, существуют различные подходы к решению:

  • Для простой Команды вы можете рассмотреть возможность реализации отмены (например, добавление символа можно отменить, удалив его)
  • Для более сложной команды вы можете рассмотреть возможность реализации отмены как восстановления предыдущего состояния (именно
    здесь включается Memento)
  • Если у вас много сложных команд, что может означать много Memento, которые занимают много места, вы можете использовать подход, который заключается в запоминании только одного снимка(снапшота) каждые 10 или 20 Команд, а затем повторении Команд с последнего снимка до отмененной команды

На самом деле, вы, вероятно, можете смешивать Command и Memento по желанию, в зависимости от специфики вашей системы и, следовательно, сложности любого из них.

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

Источник

Так же рекомендую посмотреть UndoManager, UndoText

→ Ссылка