Reputation: 958
In most text editors and platforms there are two ways of selecting text using the mouse:
The regular, Click+Drag, moves the end of the selection along with the mouse cursor
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
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