撤消Document.Replace后如何防止光标移动

时间:2011-03-31 15:44:29

标签: java swing replace document undo

如果您在Java中有一个文本组件,并且您执行了替换,则光标将不会移动,如果您使用标准撤消管理器撤消和重做替换,则光标将移动到该插入或删除的开头或结尾。

我该如何防止这种行为?

我能够使用Java TextComponentDemo触发此操作,我在其中添加了一个简单的替换操作:

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

如果我然后使用演示的撤消和重做,光标将移动。

2 个答案:

答案 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);
}
相关问题