foolo
foolo

Reputation: 958

Java Swing Double-click + drag to select whole words

In most text editors and platforms there are two ways of selecting text using the mouse:

  1. The regular, Click+Drag, moves the end of the selection along with the mouse cursor

  2. Double-click+Drag, same as #1 but it starts by selecting one whole word, and then snaps the end of the selection to whole words

In Swing GUI however, #2 does not work as above. It starts correctly by selecting the whole word where the double-click was, but then it does not snap to whole words during selection.

Is there any way to get Swing text fields to behave as 2, with the selection snapping to whole words?

Upvotes: 5

Views: 684

Answers (1)

LBald
LBald

Reputation: 493

You can create a method to calculate the index of where word your selection ends and starts. See below:

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

Then in your UI (not sure exactly how JTextArea works) you could get the start and end position of your selection, and actually selects the start and end position of their words:

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

But where to call the snippet above? You could listen to CarretEvent instead of MouseEvent (see Which event a selection of text trigger in Java JTextArea?):

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

But another problem arrises: how to know the click count of MouseEvent. You could make an attribute to store it, and then into the mouse event listener, it can be set. The code below tries to put everything toghether:

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

Upvotes: 2

Related Questions