Как предотвратить перемещение курсора после отмены Document.Replace - PullRequest
2 голосов
/ 31 марта 2011

Если у вас есть текстовый компонент в Java, и вы выполняете замену, курсор не будет двигаться, если вы отменяете и повторяете операции замены, используя стандартный менеджер отмены, курсор перемещается в начало или конец этой вставки или удаления.

Как бы я мог предотвратить это поведение?

Я смог вызвать это с помощью Java TextComponentDemo , где я добавил простое действие замены, которое сделало это:

doc.replace(doc.getText(0, doc.getLength()).indexOf("mouse"), 5, "cat", null);

Если я затем использую отмену демо и повтор, курсор будет двигаться.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2011

Ознакомьтесь с политикой обновления каретки в классе DefaultCaret.

Следующие политики обновления допускается:

  • NEVER_UPDATE: каретка остается в той же абсолютной позиции в документ независимо от любого документа обновления, кроме случаев, когда длина документа становится меньше текущей каретки положение из-за удаления. В таком случае позиция каретки отрегулирована до конца документа. Карета не пытается чтобы оставаться видимым при прокрутке связанный вид при использовании этого политика.
  • ALWAYS_UPDATE: каретка всегда отслеживает изменения документа. Для обычных меняет это увеличивает свою позицию, если вставка происходит до или в его текущая позиция и уменьшается положение, если удаление происходит раньше его текущее положение. Для отмены / повтора обновления всегда перемещаются в позиция, где произошло обновление. карета также пытается держать себя видимый при вызове AdjustVisibility способ.
  • UPDATE_WHEN_ON_EDT: действует как ALWAYS_UPDATE, если документ обновляется выполняются на Диспетчере событий Тема и как NEVER_UPDATE, если обновления выполняются в другом потоке.

Вы можете установить политику обновления на NEVER_UPDATE перед действием отмены или повтора, а затем установить обратно на то, что было после действия.

public void actionPerformed(ActionEvent e) {
    int updatePolicy = caret.getUpdatePolicy();
    caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
    undoManager.undo();
    caret.setUpdatePolicy(updatePolicy);
}
0 голосов
/ 08 апреля 2011

Java Swing - не единственный API, который имеет такое поведение в стандартном менеджере отмены. Иногда XUL (который является основой для Firefox и Thunderbird) делает то же самое с текстовыми областями в сторонних расширениях. По сути, даже если исходный текст и текст замены в этом случае похожи, текстовая область должна обрабатывать документ как совершенно новый, как если бы вы сделали , выделив все и Вставьте , чтобы перезаписать старый текст. Как правило, восстановление той же позиции курсора для нового документа было бы бесполезным, а если документ короче, это может быть даже невозможно.

Я думаю, что самым простым способом было бы создать свои собственные действия для замены текста. Слушайте их и выполняйте действия вместо выполнения действий по умолчанию. Ваше настраиваемое действие должно быть составным действием, которое сканирует документ вручную, заменяя подстроки в существующем документе - сканирует и заменяет полностью до конца, выполняя ряд изменений документа. Когда вы переопределяете метод отмены, просто просмотрите список внесенных вами изменений, отменяя каждое в обратном порядке. Пока каждое действие в составном действии правильно устанавливает текст и позицию курсора и его метод отмены работает должным образом, все составное действие также будет отменяться правильно.

В этом руководстве следует надеяться, что эта концепция будет объяснена немного яснее. Пример объединяет действия в группы, пока пользователь печатает. Вам просто нужно сделать то же самое, но с процедурными правками.

...