On Wed, 27 May 2020 12:11:48 GMT, Robert Lichtenberger <rlich...@openjdk.org> 
wrote:

>> you are hacking around ;)
>> 
>> doSelect _must not_ be called somewhere "in-between" changing the text: the 
>> api doc clearly states that the
>> caret/anchor coordinates are the _new_ coordinates, that is after all 
>> changes have been applied. When re-calculating
>> them on-the-fly might have unexpected side-effects, f.i. if a TextFormatter 
>> had something special in mind (no failing
>> test handy though).
>
> Most of the time, value in 
> javafx.scene.control.TextInputControl.replaceText(int, int, String, int, int) 
> will already
> be filtered (e.g. linebreaks in TextField) In that case, adjustmentAmount 
> will be zero and one could just do the
> selection before actually inserting the text.
> But a case can be constructed with a TextFormatter that will produce 
> characters that will be filtered by the TextField
> itself:
>     
>     @Test public void replaceSelectionWithFilteredCharacters() {
>         txtField.setText("x xxxyyy");
>         txtField.selectRange(2, 5);
>         txtField.setTextFormatter(new TextFormatter<>(this::noDigits));
>         txtField.replaceSelection("a1234a");
>         assertEquals("x aayyy", txtField.getText());
>         assertEquals(4, txtField.getSelection().getStart());
>         assertEquals(4, txtField.getSelection().getStart());
>     }
> 
>     private Change noDigits(Change change) {
>         Change filtered = change.clone();
>         filtered.setText(change.getText().replaceAll("[0-9]","\n"));
>         return filtered;
>     }

The last commit on this branch seems like the "best" way to fix this problem. 
It prevents in-between changes in
selectedText and does not introduce (to the best of my knowledge) any new 
corner cases. It eliminiates the "root cause"
of the problem by postponing selectedText update to the end of whole 
replace-operation. So, this is RFR now (I hope).

-------------

PR: https://git.openjdk.java.net/jfx/pull/138

Reply via email to