0

I would like to check my inputted string on a comma, which is pretty easy ( just used this: How can I check if a single character appears in a string?). Now I want to check if a character is present more than once. (in this case a comma (/u002C)) I have created this code:

public static void addTextLimiterDouble(final TextField tf, final int maxLength, final Button submitButton) {
    tf.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {

            if (oldValue.contains("\u002C") && newValue.endsWith("\u002C")) {
                tf.setText(oldValue);
            }
    }
});

This gives a StackOverflow error, because it seems it can not get out of the loop. Can anyone explain why it can't?

Note: I know there are maybe more ways to check for more than one character, but I am just curious why this gives me an error.

Any help is greatly appreciated!

Community
  • 1
  • 1
bashoogzaad
  • 4,611
  • 8
  • 40
  • 65

3 Answers3

2

Imagine the situation (actually, that's most likely the situation where you are in) where you are editing a string that ends in a comma. When you change something else in that string, then your if statement (if (oldValue.contains("\u002C") && newValue.endsWith("\u002C"))) returns true and you try to revert to the old value by calling tf.setText()

However- that changes the text! And your ChangeListener is invoked again. The new value ends in a comma (you were reverting back to a value that ends in a comma) and the old value also contains a comma, so again, your listener calls tf.setText().

After that, it invokes your ChangeListener because the text was changed. And again... ad nauseum

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • Thank you for this great explanation! I thought the ChangeListener would only be invoked by the user alternating the text in the textfield, but this is obviously not true. – bashoogzaad Oct 31 '14 at 12:00
1

String.endsWith checks if the passed String is present at the end of the String calling the method, but that is not what you are willing to do.

This is what I would do :

int index = myString.indexOf(ch);
boolean moreThanOnce = index != -1 && index != myString.lastIndexOf(ch);

However your test seems weird to me since it tests something on both oldValue and newValue. If I understood well what you want to do you should only consider one of those two.

Dici
  • 25,226
  • 7
  • 41
  • 82
1

You add a Listener to your TextField. Then you override the changed() method. In this method you call setText() !! This will invoke the Listeners' changed() again .... so you end up in an infinite loop ...