【问题标题】:Control selection/browsing in JTextPane在 JTextPane 中控制选择/浏览
【发布时间】:2013-11-13 16:58:02
【问题描述】:

我有一个 JTestPane 包含一些文本(显然)。使用键盘浏览文本时,通常使用 control + 向右箭头来跳过整个单词。 JTestPane 中的默认行为是将插入符号放在下一个单词的第一个字符之前。

例如,让我们考虑句子“This is a sentence”。从位置 0 开始,如果我跳过“This”并转到下一个单词(使用 CTRL+RIGHT),插入符号将位于位置 5,即“is”之前。

这对于浏览来说很好,但我不喜欢这种文本选择行为。在我正在处理的应用程序中,如果在使用 SHFT+CTRL+RIGHT 时,我只选择“This”(没有额外的空间)而不是“This”,那会更好,因为它是默认的。换句话说,我想选择字符 0-3 而不是 0-4。

我没有找到太多关于如何调整 Swing 以获得这种结果的信息。到目前为止,我已经尝试将CaretListener 注册到JTestPane 并手动缩短选择,以便在必要时删除尾随空格。但是感觉不太对劲,而且效果也不好,因为它阻止了选择多个单词。

所以,如果有人能指出我正确的方向,我会非常高兴。

【问题讨论】:

  • 您需要覆盖键绑定

标签: java swing selection jtextpane


【解决方案1】:

Swing 使用 Key Binding 在调用某个 KeyStroke 时调用 Action。有关这些绑定的列表,请参阅 Key Bindings。如您所见,在这种情况下会调用 selection-next-word Action,因此您需要提供自定义 Action。

您可以查看DefaultEditorKit 的源代码 - 了解它是如何实现的,只需减少选择 1。

或者您可以使用Wrapping Actions 概念来包装原始Action,然后调用JTextPane 的setSelection() 方法将选择重置为比您需要的少1。不确定哪种方法更简单。

【讨论】:

    【解决方案2】:

    所以,我按照 camickr 的建议将关联的 Action 更改为 selection-next-word。对于那些感兴趣的人,这就是我所做的。

    首先,我检索了内部类DefaultEditorKit.NextWordAction 的源代码,它在跳过(浏览时)和选择单词时都会调用。然后我复制它来定义我自己的版本,并通过以下方式修改了它的actionPerformed方法。

    该方法包含指令offs = Utilities.getNextWord(target, offs);,对应于下一个单词开头的插入符号位置的处理。变量target 是考虑的JTextComponentoffs 是当前插入符号位置。方法调用后,offs 包含下一个单词的开头位置。

    所以,我在这一行之后添加了以下代码:

            // remove trailing space from selection 
            if(offs>0)          
            {   String c = target.getText(offs-1, 1);
                if(c.equals(" "))
                    offs = offs - 1;
            }
            // remove trailing "'s" from selection 
            if(offs>1)
            {   String c = target.getText(offs-2, 2);
                if(c.equals("'s"))
                    offs = offs - 2;
            }
    

    如您所见,它更正了offs,使其位于尾随空格之前。我还希望它在任何 's 之前(如属格标记,例如 Vincent*'s* bike),因此我的源代码的第二部分(此附加功能未在我原来的问题)。

    但是,通过这个单独的修改,出现了一个新问题:现在无法选择几个连续的单词。多次按 SHFT+CTRL+RIGHT 时,选择会卡在第一个单词上。

    因此,为避免这种情况,我在前面提到的行(getNextWord 调用)之前添加了以下代码:

            // check for trailing "'"
            if(offs<end-2)
            {   String c = target.getText(offs, 2);
                if(c.equals("'s"))
                    offs = offs + 2;
            }
            // check for trailing space
            if(offs<end-1)
            {   String c = target.getText(offs, 1);
                if(c.equals(" "))
                    offs = offs + 1;
            }
    

    现在,它工作正常,这正是我想要的。非常感谢 camickr 的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多