Java Swing Двойной щелчок + перетаскивание, чтобы выделить слова целиком - PullRequest
5 голосов
/ 02 февраля 2020

В большинстве текстовых редакторов и платформ есть два способа выделения текста с помощью мыши:

  1. Обычный, Click + Drag, перемещает конец выделения вместе с курсором мыши

  2. Двойной щелчок + перетаскивание, аналогично # 1, но начинается с выбора целого слова, а затем привязывает конец выделения к целым словам

В Swing GUI, однако, # 2 не работает, как указано выше. Он начинается правильно, выбирая все слово, где был двойной щелчок, но затем не привязывается к целым словам во время выделения.

Есть ли способ заставить текстовые поля Swing вести себя как 2, с привязкой к целым словам?

1 Ответ

2 голосов
/ 03 февраля 2020

Вы можете создать метод для расчета индекса того, где слово заканчивается и начинается ваш выбор. См. Ниже:

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;
}

Затем в вашем пользовательском интерфейсе (не совсем точно знаю, как работает JTextArea) вы можете получить позиции выбора start и end и фактически выбрать начальную и конечную позиции их слова:

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);
    }
}
...