A common reason for using the TextFormatter is the need for a filter.
Therefore, the following constructor is typically used:
public TextFormatter(@NamedArg("filter") UnaryOperator<Change> filter) { ... }
With that, no valueConverter is set in the TextFormatter.
When a TextField will commit his value, TextFormatter.updateValue(...) is called.
Since valueConverter is null, an NPE is thrown and catched inside it and TextFormatter.updateText() is called (which will call TextInputControl.updateText(...)), which won't do anything either since valueConverter is still not set (=null).
A minor improvement here is to just skip TextFormatter.updateValue(...) and therefore TextFormatter.updateText(), since this methods won't do anything without a valueConverter.
With that change, no exception is thrown and catched, and therefore also exception breakpoints are not called.
This will also slightly increase the performance, as throwing exceptions is a (minor) bottleneck.
Therefore, the following constructor is typically used:
public TextFormatter(@NamedArg("filter") UnaryOperator<Change> filter) { ... }
With that, no valueConverter is set in the TextFormatter.
When a TextField will commit his value, TextFormatter.updateValue(...) is called.
Since valueConverter is null, an NPE is thrown and catched inside it and TextFormatter.updateText() is called (which will call TextInputControl.updateText(...)), which won't do anything either since valueConverter is still not set (=null).
A minor improvement here is to just skip TextFormatter.updateValue(...) and therefore TextFormatter.updateText(), since this methods won't do anything without a valueConverter.
With that change, no exception is thrown and catched, and therefore also exception breakpoints are not called.
This will also slightly increase the performance, as throwing exceptions is a (minor) bottleneck.