在JTextPane中控制选择/浏览

时间:2013-11-12 20:47:57

标签: java swing selection jtextpane

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

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

这适合浏览,但我不喜欢这种行为进行文本选择。在我正在研究的应用程序中,如果使用SHFT + CTRL + RIGHT时,我只选择“This”(没有额外的空格)而不是“This”,因为它是默认情况下会好得多。换句话说,我想选择字符0-3而不是0-4。

我没有找到很多关于如何调整Swing以获得此类结果的信息。到目前为止,我已尝试向CaretListener注册JTestPane并手动缩短选择范围,以便在必要时删除尾随空格。虽然它感觉不对,但它也不能很好地工作,因为它无法选择多个单词。

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

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:0)

所以,我遵循了camickr的建议,并将Actionselection-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,使其位于尾随空格之前。我也希望它在任何人之前(如在genitive的标记中,例如Vincent * * 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的帮助。