首页 > 解决方案 > Java Swing 双击+拖动选择整个单词

问题描述

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

  1. 常规的 Click+Drag 会随着鼠标光标移动选择的结尾

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

然而,在 Swing GUI 中,#2 不能像上面那样工作。它通过选择双击所在的整个单词来正确启动,但是在选择过程中它不会捕捉到整个单词。

有没有办法让 Swing 文本字段表现为 2,选择对齐到整个单词?

标签: javaswing

解决方案


您可以创建一种方法来计算您的选择结束和开始的单词的索引。见下文:

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 的工作原理)中,您可以获得所选内容的startend位置,并实际选择他们单词的开始和结束位置:

void updateSelection(JTextArea ta) {
    String text = ta.getText();
    int start = ta.getSelectionStart();
    int end = ta.getSelectionEnd();
    start = getWordStartPos(text, start);
    end = getWordEndPos(text, end);
    ta.select(start, end);
}

但是在哪里调用上面的代码片段呢?您可以听CarretEvent而不是MouseEvent(请参阅在 Java JTextArea 中选择文本触发器的哪个事件?):

textArea.addCarretListener((evt) -> updateSelection(textArea));

但是另一个问题来了:如何知道MouseEvent. 你可以做一个属性来存储它,然后进入鼠标事件监听器,它可以被设置。下面的代码试图把所有东西放在一起:

class UI implements MouseListener, CarretListener {
    JTextArea textArea;
    int clickCount = 0;

    UI() {
        textArea.addCarretListener(this);
        textArea.addMouseListener(this);
        // ...
    }

    @Override
    void mouseClicked(MouseEvent evt) {
        this.clickCount = evt.getClickCount();
        // other stuff
    }

    // other MouseListener methods

    @Override
    void caretUpdate(CaretEvent evt) {
        if (clickCount == 1) updateSelection(textArea);
        // other caret listener stuff
    }

    void updateSelection(JTextArea ta) {
        String text = ta.getText();
        int start = ta.getSelectionStart();
        int end = ta.getSelectionEnd();
        start = getWordStartPos(text, start);
        end = getWordEndPos(text, end);
        ta.select(start, end);
    }
}

推荐阅读