As I mentioned in the comments but it's never too much to repeat, the problem has nothing to do with replaceAll
or regex , but with the listener that you're using.
The KeyReleased
event is triggered every time a key is released after it has been pressed. Arrows are also keys, so each time you press any, the event will be triggered.
Since you did not provide a relevant snippet for review, I'll assume your event looks similar to the below:
@Override
public void keyReleased(KeyEvent e) {
JTextComponent input = ((JTextComponent) e.getSource());
String text = input.getText();
text = text.replaceAll("[^A-Za-z&\|!]", "");
input.setText(text.toUpperCase());
}
Note that every time a key is pressed in the text field, this entire routine will occur. And when you press a directional key (or arrows), all text in the field will be filtered by the regex and then reapplied in the field, and this will cause the Caret
default (that text cursor that appears in the field) a href="https://docs.oracle.com/javase/9/docs/api/javax/swing/text/DefaultCaret.html"> move to the end of the new applied sentence .
It is not recommended that you use keyboard events to filter strings in text fields, since text fields have another suitable way to do this, which is through the Document
.
In this answer there is an example of using the PlainDocument
, adapting to your situation, would look something like this:
input.setDocument(new PlainDocument() {
@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (str == null) {
return;
}
super.insertString(offs, str.replaceAll("[^A-Za-z&\|!]", "").toUpperCase(), a);
}
});
Running:
In the answer I gave you more details about this class.