如何防止撤消 Document.Replace 后光标移动
如果您在 Java 中有一个文本组件并且执行替换,则光标将不会移动,如果您使用标准撤消管理器撤消和重做该替换,则光标将移动到该插入或删除的开头或结尾。
我该如何防止这种行为?
我能够使用 Java TextComponentDemo 触发此操作,我在其中添加了一个简单的替换操作来执行此操作:
doc.replace(doc.getText(0, doc.getLength()).indexOf("mouse"), 5, "cat", null);
如果我随后使用演示的撤消和重做,则光标将移动。
If you have a text component in Java and you do a replace the cursor will not move, if you undo and redo that replace using a standard undo manager the cursor will move to the beginning or end of that insertion or deletion.
How would I prevent this behavior?
I was able to trigger this with the Java TextComponentDemo, where I added a simple replace action that did this:
doc.replace(doc.getText(0, doc.getLength()).indexOf("mouse"), 5, "cat", null);
If I then use the demo's undo's and redo's the cursor will move.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Java Swing 并不是唯一在标准撤消管理器中具有此行为的 API。有时,XUL(Firefox 和 Thunderbird 的基础)对 3rd 方扩展中的文本区域执行相同的操作。本质上,即使在这种情况下原始文本和替换文本相似,文本区域也必须将文档视为全新文档,就像您执行了全选和操作一样>粘贴以覆盖旧文本。一般来说,将相同的光标位置恢复到新文档中是没有用的,如果文档较短,甚至可能不可能。
我认为解决这个问题最简单的方法是创建您自己的自定义操作来替换文本。聆听它们并执行操作,而不是执行默认操作。您的自定义操作应该是一个复合操作,它手动扫描文档,替换现有文档中的子字符串 - 通过执行多次文档更改来扫描并替换到最后。当您覆盖撤消方法时,只需浏览您所做的修改列表,以相反的顺序撤消每一项。只要复合动作中的每个动作正确设置文本和光标位置,并且其撤消方法正常工作,整个复合动作也将正确撤消。
本指南有望更清楚地解释这个概念。该示例在用户键入时将操作合并到组中。您只需要执行相同的操作,但要进行程序编辑。
Java Swing isn't the only API that has this behaviour in the standard undo manager. Sometimes XUL (which is the base for Firefox and Thunderbird) does the same thing with text areas in 3rd-party extensions. Essentially, even though the original text and the replacement text are similar in this case, the text area has to treat the document as an entirely new one, just like if you had done a select all and paste to overwrite the old text. In general, restoring the same cursor position to the new document would be useless, and if the document is shorter, it might not even be possible.
I think the easiest way around this would be to create your own custom actions for replacing text. Listen for them and perform the actions instead of performing the default action. Your custom action should be a compound action which scans the document manually, replacing substrings in the existing document - scan and replace all the way to the end by performing a number of document changes. When you override the undo method, just go through the list of modifications you made, undoing each one in reverse order. As long as each action in the compound action sets the text and the cursor position correctly, and its undo method works properly, the whole compound action will also undo properly.
This guide should hopefully explain this concept a little more clearly. The example merges actions into groups while the user types. You just need to do the same, but with procedural edits instead.
查看插入符号更新类
中的策略
DefaultCaret
。您可以在撤消或重做操作之前将更新策略设置为
NEVER_UPDATE
,然后将其设置回该操作之后的状态。Check out the caret update policy in the class
DefaultCaret
.You can set the update policy to
NEVER_UPDATE
before an undo or redo action, then set it back to what it was after the action.