Java Swing双击+;拖动以选择整个单词

Java Swing双击+;拖动以选择整个单词,java,swing,Java,Swing,在大多数文本编辑器和平台中,有两种使用鼠标选择文本的方法: 常规的“单击+拖动”操作会随鼠标光标移动选择的结尾 双击并拖动,与#1相同,但它首先选择一个完整的单词,然后将选择的结尾捕捉到完整的单词 但是,在Swing GUI中,#2不能像上面那样工作。它正确地从双击的位置选择整个单词开始,但在选择过程中它不会捕捉到整个单词 有没有办法让Swing文本字段表现为2,并将所选内容捕捉到整个单词?您可以创建一个方法来计算所选内容的结束和开始位置的索引。见下文: int getWordEndPos(St

在大多数文本编辑器和平台中,有两种使用鼠标选择文本的方法:

  • 常规的“单击+拖动”操作会随鼠标光标移动选择的结尾

  • 双击并拖动,与#1相同,但它首先选择一个完整的单词,然后将选择的结尾捕捉到完整的单词

  • 但是,在Swing GUI中,#2不能像上面那样工作。它正确地从双击的位置选择整个单词开始,但在选择过程中它不会捕捉到整个单词


    有没有办法让Swing文本字段表现为2,并将所选内容捕捉到整个单词?

    您可以创建一个方法来计算所选内容的结束和开始位置的索引。见下文:

    int getWordEndPos(String text, int initPos) {
        int i = initPos;
        while(Character.isAlphabetic(text.charAt(i))) {
            i++;
        }
        return i;
    }
    
    int getWordStartPos(String text, int initPos) {
        int i = initPos;
        while(Character.isAlphabetic(text.charAt(i))) {
            i--;
        }
        return i+1;
    }
    
    然后在您的UI中(不确定JTextArea如何工作),您可以获得所选内容的
    开始
    结束
    位置,并实际选择其单词的开始和结束位置:

    void updateSelection(JTextArea ta){
    String text=ta.getText();
    int start=ta.getSelectionStart();
    int end=ta.getSelectionEnd();
    开始=getWordStartPos(文本,开始);
    end=getWordEndPos(文本,end);
    ta.选择(开始、结束);
    }
    
    但是在哪里调用上面的代码片段呢?您可以收听
    CarretEvent
    ,而不是
    MouseEvent
    (请参阅):

    但另一个问题出现了:如何知道
    MouseEvent
    的点击次数。您可以创建一个属性来存储它,然后在鼠标事件侦听器中设置它。下面的代码尝试将所有内容组合在一起:

    class UI实现了MouseListener、CarretListener{
    JTextArea textArea;
    int clickCount=0;
    UI(){
    textArea.addCarretListener(这个);
    textArea.addMouseListener(这个);
    // ...
    }
    @凌驾
    无效鼠标点击(鼠标事件evt){
    this.clickCount=evt.getClickCount();
    //其他东西
    }
    //其他MouseListener方法
    @凌驾
    作废caretUpdate(CaretEvent evt){
    如果(clickCount==1)更新选择(textArea);
    //其他插入符号侦听器内容
    }
    无效更新选择(JTextArea ta){
    String text=ta.getText();
    int start=ta.getSelectionStart();
    int end=ta.getSelectionEnd();
    开始=getWordStartPos(文本,开始);
    end=getWordEndPos(文本,end);
    ta.选择(开始、结束);
    }
    }
    
    Hm,我明白你的意思。这将需要更多的考虑,可能你正在寻找:@aterai啊,是的,这似乎是同一个问题(虽然特别是对于JTextArea,我使用JTextPane,但似乎解决方案也适用于此)。我在搜索时没有找到它。这能回答你的问题吗?是的,但不幸的是,困难的部分不是如何找到单词的边界。这可以通过几种方式实现。棘手的部分是如何将其与选择机制同步(区分单击和双击行为等)。您可以使用
    MouseEvent.getClickCount()
    计算单击次数,请参见。是,但是MouseEvent.getClickCount()在本例中不返回2。对于完全的“正常”双击,它只返回2,而不是在通过双击启动拖动操作时。然后我认为您可以测试在按下或拖动事件中是否
    getClickCount()==1
    。是的,但这也会检测到单次单击,这意味着单次单击之后是常规的单击+拖动,将具有与双击+拖动相同的事件序列。因此,您需要添加约500毫秒的计时器,并检查XY位置,确定是否是双击,然后开始变得非常混乱,但可能这是唯一可能的解决方案。
    textArea.addCarretListener((evt) -> updateSelection(textArea));