如果您在Java中有一个文本组件,并且您执行了替换,则光标将不会移动,如果您使用标准撤消管理器撤消和重做替换,则光标将移动到该插入或删除的开头或结尾。
我该如何防止这种行为?
我能够使用Java TextComponentDemo触发此操作,我在其中添加了一个简单的替换操作:
doc.replace(doc.getText(0, doc.getLength()).indexOf("mouse"), 5, "cat", null);
如果我然后使用演示的撤消和重做,光标将移动。
答案 0 :(得分:0)
Java Swing不是唯一在标准撤消管理器中具有此行为的API。有时XUL(Firefox和Thunderbird的基础)对第三方扩展中的文本区域做同样的事情。基本上,即使原始文本和替换文本在这种情况下相似,文本区域也必须将文档视为一个全新的文档,就像您已经完成选择所有和粘贴以覆盖旧文本。通常,将相同的光标位置恢复到新文档将是无用的,如果文档较短,甚至可能无法实现。
我认为最简单的方法是创建自己的自定义操作来替换文本。听取它们并执行操作,而不是执行默认操作。您的自定义操作应该是复合操作,该操作会手动扫描文档,替换现有文档中的子字符串 - 通过执行大量文档更改来扫描和替换到最后。当您覆盖撤消方法时,只需浏览您所做的修改列表,以相反的顺序撤消每个修改。只要复合动作中的每个动作都正确设置文本和光标位置,并且其撤消方法正常工作,整个复合动作也将正确撤消。
This guide应该更清楚地解释这个概念。该示例在用户键入时将操作合并到组中。您只需要执行相同的操作,但需要进行程序编辑。
答案 1 :(得分:0)
查看课程caret update policy中的DefaultCaret
。
以下更新政策 允许的:
- NEVER_UPDATE:插入符号位于相同的绝对位置 文件,无论任何文件 更新,除了文档长度 变得比目前的插入符号少 由于搬迁的位置。在这种情况下 插入位置调整到最后 该文件。插入符不尝试 通过滚动保持自己可见 使用它时的关联视图 政策。
- ALWAYS_UPDATE:插入符始终跟踪文档更改。经常 改变它增加其位置,如果 插入发生在其之前或之中 当前位置,并减少 如果之前发生了移除, 它目前的位置。对于撤消/重做 更新它总是移动到 更新发生的位置。该 插入符号也试图保持自己 通过调用adjustVisibility可见 方法
- UPDATE_WHEN_ON_EDT:如果文档更新,则表现为ALWAYS_UPDATE 在事件调度上执行 线程和NEVER_UPDATE一样if 更新在其他线程上执行。
您可以在撤消或重做操作之前将更新策略设置为NEVER_UPDATE
,然后将其设置回操作后的状态。
public void actionPerformed(ActionEvent e) {
int updatePolicy = caret.getUpdatePolicy();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
undoManager.undo();
caret.setUpdatePolicy(updatePolicy);
}