Arrows do not move in text field with regex [closed]

2

I have the following code with a regular expression inside a Keyreleased method, which allows only a few characters to be entered by the user into a text field:

String text = input.getText();
text = text.replaceAll("[^A-Za-z&\|!]", "");
input.setText(text.toUpper());

When you try to press the arrow keys like - (left) or (right) - > , the regular expression will not let me go back into the edit string something, Regex does not allow.

Example:

The cursor at this point is in front of C, but I can not return the cursor so that it is in front of B or A.

Would anyone know how to solve this problem?

    
asked by anonymous 31.10.2017 / 23:57

1 answer

8

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.

    
01.11.2017 / 13:50